Page MenuHomeWildfire Games

fix back-to-work button for garrisoned units
ClosedPublic

Authored by mimo on Jun 27 2017, 7:29 PM.

Details

Reviewers
fatherbushido
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Commits
rP19869: fix back-to-work button for garrisoned units
Summary

Garrisoned turrets (units on walls) have the back-to-work button in the command panel, but it is currently broken: task a unit (range+infantry) to gather something then garrison it on a wall, when clicking on the back-to-work button, the unit will play the move animation but only its selection ring will move to the gathering point. In addition, the workOrders have been cleared so can't be recovered after proper ungarrisoning.
The patch insert an ungarrison order before the backtowork one.

It's possible that the patch also fixes the first infinite loop reported in #4523 as it seems connected

Test Plan

test as described before that it is broken without the patch, and fixed with it

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

mimo created this revision.Jun 27 2017, 7:29 PM
Vulcan added a subscriber: Vulcan.Jun 27 2017, 8:04 PM
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4774|4774| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4775|4775| 	if (this.isGuardOf)
|4776|4776| 	{
|4777|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4777|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4778|4778| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4779|4779| 		if (cmpUnitAI && cmpAttack &&
|4780|4780| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4821|4821| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4822|4822| 	if (this.isGuardOf)
|4823|4823| 	{
|4824|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4824|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4825|4825| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4826|4826| 		if (cmpUnitAI && cmpAttack &&
|4827|4827| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4989|4989| 	{
|4990|4990| 		if

http://jw:8080/job/phabricator_lint/247/ for more details.

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1642/ for more details.

mimo updated this revision to Diff 2737.Jun 28 2017, 7:00 PM

fix an oversight

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1652/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4774|4774| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4775|4775| 	if (this.isGuardOf)
|4776|4776| 	{
|4777|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4777|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4778|4778| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4779|4779| 		if (cmpUnitAI && cmpAttack &&
|4780|4780| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4821|4821| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4822|4822| 	if (this.isGuardOf)
|4823|4823| 	{
|4824|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4824|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4825|4825| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4826|4826| 		if (cmpUnitAI && cmpAttack &&
|4827|4827| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4989|4989| 	{
|4990|4990| 		if

http://jw:8080/job/phabricator_lint/256/ for more details.

elexis added a subscriber: elexis.Jun 29 2017, 12:20 PM

Agree that the patch is good. It's the only legit case I can think of where we can select a garrisoned unit.

It also solves the case where the unit is garrisoned and happens to receive that back-to-work order and segfaults the game due to that infinite loop described in the ticket.

Does it have to be a forced unload though?
(With this patch it is possible to ungarrison a unit from a ship in the middle of the sea if we manage to click on the controlgroup and press Y simultanoeusly. We can't do anything with the unit under water and whenever moving it, it will move to the closest shoreline instead.)
Perhaps an IsTurret check could be added and the order could be aborted otherwise.

The infinite loop still should be fixed either way, no matter how it's triggered (so that players can't trigger a segfault by scripting some simulation command or doing some weird thing). That may or may not be the case when both of your patches are committed.

(Consistency could also be considered, f.e. it might be unexpected that the unit follows the back-to-work order when garrisoned but ignores all other commands besides unloading and deleting). No real opinion on it.)

mimo updated this revision to Diff 2758.Jun 29 2017, 7:19 PM

update

mimo added a comment.Jun 29 2017, 7:23 PM
In D685#27648, @elexis wrote:

Does it have to be a forced unload though?

No you are right, it should not. Fixed.

(With this patch it is possible to ungarrison a unit from a ship in the middle of the sea if we manage to click on the controlgroup and press Y simultanoeusly. We can't do anything with the unit under water and whenever moving it, it will move to the closest shoreline instead.)
Perhaps an IsTurret check could be added and the order could be aborted otherwise.

Why? when not turret, the order can't be sent except if the player change its mind at the last moment and the order arrives on the same turn as the effective garrisoning, and then why not execute it?

The infinite loop still should be fixed either way, no matter how it's triggered (so that players can't trigger a segfault by scripting some simulation command or doing some weird thing). That may or may not be the case when both of your patches are committed.

I think these garrisoning infinite loops are fixed with D685+D686

mimo added a comment.Jun 29 2017, 7:28 PM
In D685#27697, @elexis wrote:

(Consistency could also be considered, f.e. it might be unexpected that the unit follows the back-to-work order when garrisoned but ignores all other commands besides unloading and deleting). No real opinion on it.)

I also don't mind, the important point is that the current code is broken and should be fixed. We can also ignore the order, but doing it as in this patch allows to reduce the number of clicks when sending them back-to-work (otherwise you should unload them first and then back-to-work)
if ignoring it, it should also be greyed/disabled in the command panel (also true for the other commands).

leper added a reviewer: Restricted Owners Package.Jun 29 2017, 8:57 PM
leper added a subscriber: leper.

GetGarrisonHolder seems like it might be useful for allowing to focus on the building a control group is garrisoned in.

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1665/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4774|4774| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4775|4775| 	if (this.isGuardOf)
|4776|4776| 	{
|4777|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4777|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4778|4778| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4779|4779| 		if (cmpUnitAI && cmpAttack &&
|4780|4780| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4821|4821| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4822|4822| 	if (this.isGuardOf)
|4823|4823| 	{
|4824|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4824|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4825|4825| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4826|4826| 		if (cmpUnitAI && cmpAttack &&
|4827|4827| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4989|4989| 	{
|4990|4990| 		if

http://jw:8080/job/phabricator_lint/266/ for more details.

mimo added a comment.Jun 29 2017, 10:15 PM
In D685#27739, @leper wrote:

GetGarrisonHolder seems like it might be useful for allowing to focus on the building a control group is garrisoned in.

yep, in the plan for after a22. Should be stored in GetEntityState and used in the gui (for example in getEntityOrHolder which currently won't work if the entity is an attacking turret as the garrison order won't be the first one)

fatherbushido added a subscriber: fatherbushido.

"Test as described before that it is broken without the patch, and fixed with it" -> test ok

(do you think to recursive garrisoning stuff?)

This revision is now accepted and ready to land.Jul 3 2017, 5:12 PM
Imarok added a subscriber: Imarok.Jul 3 2017, 5:30 PM

related bug: select a unit on the wall, order it to repair something. (This clears the order queue) Press back-to-work: you will get "Some unit(s) can't go back to work".

mimo updated this revision to Diff 2797.Jul 3 2017, 7:00 PM

fix problem spotted by imarok

mimo added a comment.Jul 3 2017, 7:02 PM
In D685#28047, @Imarok wrote:

related bug: select a unit on the wall, order it to repair something. (This clears the order queue) Press back-to-work: you will get "Some unit(s) can't go back to work".

yep thanks for spotting it, fixed in new patch

Imarok added inline comments.Jul 3 2017, 7:23 PM
binaries/data/mods/public/simulation/components/UnitAI.js
3848 ↗(On Diff #2797)

I guess "type" should be type...

mimo updated this revision to Diff 2800.Jul 3 2017, 7:30 PM

fixes imarok new comment

Imarok added a comment.Jul 3 2017, 7:41 PM

I don't know if this matters, but clicking repair with a unit on a wall changes the order queue from [{"type":"Garrison","data":{"target":723}}] to [{"type":"Garrison","data":{"target":723,"force":true}}]. (So it removes the "force": true)

mimo updated this revision to Diff 2801.Jul 3 2017, 7:49 PM

maybe a slightly nicer version

Vulcan added a comment.Jul 3 2017, 7:50 PM

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1683/ for more details.

mimo added a comment.Jul 3 2017, 7:51 PM
In D685#28072, @Imarok wrote:

I don't know if this matters, but clicking repair with a unit on a wall changes the order queue from [{"type":"Garrison","data":{"target":723}}] to [{"type":"Garrison","data":{"target":723,"force":true}}]. (So it removes the "force": true)

yes, because the first order was given by the player (so forced) while the second one is not (just issued automatically to keep a consistent unitAI state), so i've not added the force=true. I could, but i don't think it matters for garrisoning.

Vulcan added a comment.Jul 3 2017, 7:52 PM
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4781|4781| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4782|4782| 	if (this.isGuardOf)
|4783|4783| 	{
|4784|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4784|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4785|4785| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4786|4786| 		if (cmpUnitAI && cmpAttack &&
|4787|4787| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4828|4828| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4829|4829| 	if (this.isGuardOf)
|4830|4830| 	{
|4831|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4831|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4832|4832| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4833|4833| 		if (cmpUnitAI && cmpAttack &&
|4834|4834| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4996|4996| 	{
|4997|4997| 		if (this.isGuardOf == target && this.order && this.order.type == "Guard")
|4998|4998| 			return;
|4999|    |-		else
|5000|    |-			this.RemoveGuard();
|    |4999|+		this.RemoveGuard();
|5001|5000| 	}
|5002|5001| 
|5003|5002| 	this.AddOrder("Guard", { "target": target, "force": false }, queued);
|    | [NORMAL] ESLintBear (no-undef-init):
|    | It's not necessary to initialize 'lastPos' to undefined.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|5244|5244| 
|5245|5245| 	// Remember the position of our target, if any, in case it disappears
|5246|5246| 	// later and we want to head to its last known position
|5247|    |-	var lastPos = undefined;
|    |5247|+	var lastPos;
|5248|5248| 	var cmpPosition = Engine.QueryInterface(target, IID_Position);
|5249|5249| 	if (cmpPosition && cmpPosition.IsInWorld())
|5250|5250| 		lastPos = cmpPosition.GetPosition();

binaries/data/mods/public/simulation/components/UnitAI.js
|2482| »   »   »   »   »   »   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
|3905| »   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
|4230| »   »   let·cmpOwnership·=·Engine.QueryInterface(ent,·IID_Ownership);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'cmpOwnership' is already declared in the upper scope.

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

binaries/data/mods/public/simulation/components/UnitAI.js
|4718| »   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
|4764| »   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
|4787| »   »   ····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
| 363| »   »   ····&&·(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
|1951| »   »   »   »   »   »   var·cmpFormation·=·Engine.QueryInterface(this.formationController,·IID_Formation);
|    | [NORMAL] JSHintBear:
|    | 'cmpFormation' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2177| »   »   »   »   »   »   »   »   ·&&·((type.generic·==·"treasure"·&&·oldType.generic·==·"treasure")
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

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

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|2242| »   »   »   »   »   »   »   »   &&·((type.generic·==·"treasure"·&&·oldType.generic·==·"treasure")
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|2288| »   »   »   »   »   »   »   ||·(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
|2289| »   »   »   »   »   »   »   &&·(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
|2305| »   »   »   »   »   var·nearby·=·this.FindNearestDropsite(resourceType.generic);
|    | [NORMAL] JSHintBear:
|    | 'nearby' is already defined.

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|2496| »   »   »   »   »   »   »   ||·(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
|2497| »   »   »   »   »   »   »   &&·(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
|2517| »   »   »   »   »   var·nearby·=·this.FindNearestDropsite(resourceType.generic);
|    | [NORMAL] JSHintBear:
|    | 'nearby' is already defined.

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

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

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

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

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

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

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

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

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

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|3363| »   return·this.alertRaiser·!=·undefined;
|    | [NORMAL] JSHintBear:
|    | Use '!==' to compare with 'undefined'.

binaries/data/mods/public/simulation/components/UnitAI.js
|3505| »   »   »   ||·this.orderQueue[0].type·==·"Pack"·||·this.orderQueue[0].type·==·"Unpack")))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '||'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|3569| »   »   if·(i·==·0)
|    | [NORMAL] JSHintBear:
|    | Use '===' to compare with '0'.

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|3948| »   if·(this.workOrders.length·==·0)
|    | [NORMAL] JSHintBear:
|    | Use '===' to compare with '0'.

binaries/data/mods/public/simulation/components/UnitAI.js
|4134| »   return·cmpHealth·&&·cmpHealth.GetHitpoints()·!=·0;
|    | [NORMAL] JSHintBear:
|    | Use '!==' to compare with '0'.

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|4484| »   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
|4540| »   »   »   &&·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
|4720| »   »   &&·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
|4721| »   »   &&·(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
|5247| »   var·lastPos·=·undefined;
|    | [NORMAL] JSHintBear:
|    | It's not necessary to initialize 'lastPos' to 'undefined'.

binaries/data/mods/public/simulation/components/UnitAI.js
|5586| »   »   »   »   »   »   &&·!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
|5589| »   »   »   »   »   »   &&·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
|5602| »   var·targets·=·this.GetTargetsFromUnit();
|    | [NORMAL] JSHintBear:
|    | 'targets' is already defined.

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

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

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

binaries/data/mods/public/simulation/components/UnitAI.js
|5612| »   »   »   »   &&·!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
|5615| »   »   »   »   &&·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
|5615| »   »   »   »   &&·MatchesClassList(cmpIdentity.GetClassesList(),·targetClasses.avoid))
|    | [MAJOR] JSHintBear:
|    | Too many errors. (91% scanned).
Executing section XML GUI...
Executing section Python...
Executing section Perl...

http://jw:8080/job/phabricator_lint/279/ for more details.

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1686/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4781|4781| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4782|4782| 	if (this.isGuardOf)
|4783|4783| 	{
|4784|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4784|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4785|4785| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4786|4786| 		if (cmpUnitAI && cmpAttack &&
|4787|4787| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4828|4828| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4829|4829| 	if (this.isGuardOf)
|4830|4830| 	{
|4831|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4831|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4832|4832| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4833|4833| 		if (cmpUnitAI && cmpAttack &&
|4834|4834| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4996|4996| 	{
|4997|4997| 		if

http://jw:8080/job/phabricator_lint/282/ for more details.

Build is green

Updating workspaces.
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jw:8080/job/phabricator/1687/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
| 911| 911| 					this.FinishOrder();
| 912| 912| 					return;
| 913| 913| 				}
| 914|    |-				else
| 915|    |-				{
|    | 914|+				
| 916| 915| 					// Out of range; move there in formation
| 917| 916| 					if (this.MoveToGarrisonRange(msg.data.target))
| 918| 917| 					{
| 919| 918| 						this.SetNextState("GARRISON.APPROACHING");
| 920| 919| 						return;
| 921| 920| 					}
| 922|    |-				}
|    | 921|+				
| 923| 922| 			}
| 924| 923| 
| 925| 924| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|1958|1958| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1959|1959| 
|1960|1960| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1961|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1961|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1962|1962| 
|1963|1963| 					this.FaceTowardsTarget(this.order.data.target);
|1964|1964| 
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2184|2184| 							this.PerformGather(nearby, false, false);
|2185|2185| 							return true;
|2186|2186| 						}
|2187|    |-						else
|2188|    |-						{
|    |2187|+						
|2189|2188| 							// It's probably better in this case, to avoid units getting stuck around a dropsite
|2190|2189| 							// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
|2191|2190| 							// to order it to GatherNear the resource position.
|2206|2205| 									return true;
|2207|2206| 								}
|2208|2207| 							}
|2209|    |-						}
|    |2208|+						
|2210|2209| 						return true;
|2211|2210| 					}
|2212|2211| 					return false;
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2196|2196| 								this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
|2197|2197| 								return true;
|2198|2198| 							}
|2199|    |-							else
|2200|    |-							{
|    |2199|+							
|2201|2200| 								// we're kind of stuck here. Return resource.
|2202|2201| 								var nearby = this.FindNearestDropsite(oldType.generic);
|2203|2202| 								if (nearby)
|2205|2204| 									this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
|2206|2205| 									return true;
|2207|2206| 								}
|2208|    |-							}
|    |2207|+							
|2209|2208| 						}
|2210|2209| 						return true;
|2211|2210| 					}
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|2580|2580| 					this.StartTimer(prepare, this.healTimers.repeat);
|2581|2581| 
|2582|2582| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2583|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2583|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2584|2584| 
|2585|2585| 					this.FaceTowardsTarget(this.order.data.target);
|2586|2586| 				},
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3396|3396| 
|3397|3397| UnitAI.prototype.IsAnimal = function()
|3398|3398| {
|3399|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3399|+	return (!!this.template.NaturalBehaviour);
|3400|3400| };
|3401|3401| 
|3402|3402| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|3715|3715| 		// Otherwise we've successfully processed a new order
|3716|3716| 		return true;
|3717|3717| 	}
|3718|    |-	else
|3719|    |-	{
|    |3718|+	
|3720|3719| 		this.SetNextState("IDLE");
|3721|3720| 
|3722|3721| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3737|3736| 		}
|3738|3737| 
|3739|3738| 		return false;
|3740|    |-	}
|    |3739|+	
|3741|3740| };
|3742|3741| 
|3743|3742| /**
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4780|4780| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4781|4781| 	if (this.isGuardOf)
|4782|4782| 	{
|4783|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4783|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4784|4784| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4785|4785| 		if (cmpUnitAI && cmpAttack &&
|4786|4786| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4827|4827| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4828|4828| 	if (this.isGuardOf)
|4829|4829| 	{
|4830|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4830|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4831|4831| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4832|4832| 		if (cmpUnitAI && cmpAttack &&
|4833|4833| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/simulation/components/UnitAI.js
|4995|4995| 	{
|4996|4996| 		if

http://jw:8080/job/phabricator_lint/283/ for more details.

(sorry for not having caught that, thx Imarok for having doing it)
I did some test with traders (allowing them on walls), with promotion, with formations and didn't notice anything wrong.
It's annoying to have to set those specific things in those generic function (like ReplaceOrder) but it's already the case and it seems necessary.

This revision was automatically updated to reflect the committed changes.