Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml	(révision 13290)
+++ binaries/data/mods/public/gui/session/session.xml	(copie de travail)
@@ -866,8 +866,9 @@
 			    <object size="90 -2 126 34" name="attackAndArmorStats" type="image" sprite="stretched:session/icons/stances/defensive.png" tooltip="Attack and Armor" tooltip_style="sessionToolTip"/>
 
 			    <!-- Resource carrying icon/counter -->
+			    <!-- Used also for number of gatherers/builders -->
 			    <object size="100%-78 -2 100%-28 34" type="text" name="resourceCarryingText" style="CarryingTextRight"/>
-			    <object size="100%-36 -2 100% 34" type="image" name="resourceCarryingIcon"/>
+			    <object size="100%-36 -2 100% 34" type="image" name="resourceCarryingIcon" tooltip_style="sessionToolTip"/>
 			</object>
 			
 			<!-- Big unit icon -->
Index: binaries/data/mods/public/gui/session/selection_details.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_details.js	(révision 13290)
+++ binaries/data/mods/public/gui/session/selection_details.js	(copie de travail)
@@ -131,6 +131,7 @@
 		getGUIObjectByName("resourceCarryingText").hidden = false;
 		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+carried.type+".png";
 		getGUIObjectByName("resourceCarryingText").caption = carried.amount + " / " + carried.max;
+		getGUIObjectByName("resourceCarryingIcon").tooltip = "";
 	}
 	// Use the same indicators for traders
 	else if (entState.trader && entState.trader.goods.amount > 0)
@@ -139,7 +140,25 @@
 		getGUIObjectByName("resourceCarryingText").hidden = false;
 		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+entState.trader.goods.type+".png";
 		getGUIObjectByName("resourceCarryingText").caption = entState.trader.goods.amount;
+		getGUIObjectByName("resourceCarryingIcon").tooltip = "";
 	}
+	// And for number of workers
+	else if (entState.foundation)
+	{
+		getGUIObjectByName("resourceCarryingIcon").hidden = false;
+		getGUIObjectByName("resourceCarryingText").hidden = false;
+		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
+		getGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + "    ";
+		getGUIObjectByName("resourceCarryingIcon").tooltip = "number of builders";
+	}
+	else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints))
+	{
+		getGUIObjectByName("resourceCarryingIcon").hidden = false;
+		getGUIObjectByName("resourceCarryingText").hidden = false;
+		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
+		getGUIObjectByName("resourceCarryingText").caption = entState.resourceSupply.gatherers.length + " / " + entState.resourceSupply.maxGatherers + "    ";
+		getGUIObjectByName("resourceCarryingIcon").tooltip = "number/max of gatherers";
+	}
 	else
 	{
 		getGUIObjectByName("resourceCarryingIcon").hidden = true;
@@ -148,7 +167,7 @@
 
 	// Set Player details
 	getGUIObjectByName("specific").caption = specificName;
-		getGUIObjectByName("player").caption = playerName;
+	getGUIObjectByName("player").caption = playerName;
 	getGUIObjectByName("playerColorBackground").sprite = "colour: " + playerColor;
 	
 	if (genericName)
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js	(révision 13290)
+++ binaries/data/mods/public/simulation/components/GuiInterface.js	(copie de travail)
@@ -235,7 +235,8 @@
 	if (cmpFoundation)
 	{
 		ret.foundation = {
-			"progress": cmpFoundation.GetBuildPercentage()
+			"progress": cmpFoundation.GetBuildPercentage(),
+			"numBuilders": cmpFoundation.GetNumBuilders(),
 		};
 	}
 
Index: binaries/data/mods/public/simulation/components/Foundation.js
===================================================================
--- binaries/data/mods/public/simulation/components/Foundation.js	(révision 13290)
+++ binaries/data/mods/public/simulation/components/Foundation.js	(copie de travail)
@@ -12,27 +12,12 @@
 	// its obstruction once there's nothing in the way.
 	this.committed = false;
 
-	// Set up a timer so we can count the number of builders in a 1-second period.
-	// (We assume each builder only builds once per second, which is what UnitAI
-	// implements.)
-	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
-	this.timer = cmpTimer.SetInterval(this.entity, IID_Foundation, "UpdateTimeout", 1000, 1000, {});
-	this.recentBuilders = []; // builder entities since the last timeout
-	this.numRecentBuilders = 0; // number of builder entities as of the last timeout
+	this.builders = []; // builder entities
 	this.buildMultiplier = 1; // Multiplier for the amount of work builders do.
 	
 	this.previewEntity = INVALID_ENTITY;
 };
 
-Foundation.prototype.UpdateTimeout = function()
-{
-	this.numRecentBuilders = this.recentBuilders.length;
-	this.recentBuilders = [];
-	this.SetBuildMultiplier();
-
-	Engine.QueryInterface(this.entity, IID_Visual).SetVariable("numbuilders", this.numRecentBuilders);
-};
-
 Foundation.prototype.InitialiseConstruction = function(owner, template)
 {
 	this.finalTemplateName = template;
@@ -80,6 +65,11 @@
 	return Math.floor(this.GetBuildProgress() * 100);
 };
 
+Foundation.prototype.GetNumBuilders = function()
+{
+	return this.builders.length;
+};
+
 Foundation.prototype.IsFinished = function()
 {
 	return (this.GetBuildProgress() == 1.0);
@@ -115,36 +105,43 @@
 				cmpStatisticsTracker.IncreaseResourceUsedCounter(r, -scaled);
 		}
 	}
-
-	// Reset the timer
-	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
-	cmpTimer.CancelTimer(this.timer);
 };
 
 /**
- * Adds a builder to the counter. Used indirectly by UnitAI to signal that
- * a unit has started the construction timer and will actually build soon.
+ * Adds or removes a builder to the counter.
  */
 Foundation.prototype.AddBuilder = function(builderEnt)
 {
-	if (this.recentBuilders.indexOf(builderEnt) != -1)
-		return;
+	if (this.builders.indexOf(builderEnt) === -1)
+	{
+		this.builders.push(builderEnt);
+		Engine.QueryInterface(this.entity, IID_Visual).SetVariable("numbuilders", this.builders.length);
+		this.SetBuildMultiplier();
+	}
+};
 
-	this.recentBuilders.push(builderEnt);
-	if (this.recentBuilders.length > this.numRecentBuilders)
+Foundation.prototype.RemoveBuilder = function(builderEnt)
+{
+	if (this.builders.indexOf(builderEnt) !== -1)
 	{
-		this.numRecentBuilders = this.recentBuilders.length;
+		this.builders.splice(this.builders.indexOf(builderEnt),1);
+		Engine.QueryInterface(this.entity, IID_Visual).SetVariable("numbuilders", this.builders.length);
 		this.SetBuildMultiplier();
 	}
 };
 
 /**
  * Sets the build rate multiplier, which is applied to all builders.
+ * Yields a total rate of construction equal to numBuilders^0.7
  */
+
 Foundation.prototype.SetBuildMultiplier = function()
 {
-	// Yields a total rate of construction equal to numRecentBuilders^0.7
-	this.buildMultiplier = Math.pow(this.numRecentBuilders, 0.7) / this.numRecentBuilders;
+	var numBuilders = this.builders.length;
+	if (numBuilders == 0)
+		this.buildMultiplier = 1;
+	else
+		this.buildMultiplier = Math.pow(numBuilders, 0.7) / numBuilders;
 };
 
 /**
@@ -241,9 +238,6 @@
 	var cmpCost = Engine.QueryInterface(this.entity, IID_Cost);
 	var amount = work / cmpCost.GetBuildTime();
 
-	// Record this builder so we can count the total number
-	this.AddBuilder(builderEnt);
-
 	// Add an appropriate proportion of hitpoints
 	var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
 	var maxHealth = cmpHealth.GetMaxHitpoints();
Index: binaries/data/mods/public/simulation/components/UnitAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/UnitAI.js	(révision 13290)
+++ binaries/data/mods/public/simulation/components/UnitAI.js	(copie de travail)
@@ -2103,9 +2103,9 @@
 
 					this.order.data.force = false;
 
-					var target = this.order.data.target;
+					this.repairTarget = this.order.data.target;	// temporary, deleted in "leave".
 					// Check we can still reach and repair the target
-					if (!this.CheckTargetRange(target, IID_Builder) || !this.CanRepair(target))
+					if (!this.CheckTargetRange(this.repairTarget, IID_Builder) || !this.CanRepair(this.repairTarget))
 					{
 						// Can't reach it, no longer owned by ally, or it doesn't exist any more
 						this.FinishOrder();
@@ -2113,7 +2113,7 @@
 					}
 					else
 					{
-						var cmpFoundation = Engine.QueryInterface(target, IID_Foundation);
+						var cmpFoundation = Engine.QueryInterface(this.repairTarget, IID_Foundation);
 						if (cmpFoundation)
 							cmpFoundation.AddBuilder(this.entity);
 					}
@@ -2124,13 +2124,16 @@
 				},
 
 				"leave": function() {
+					var cmpFoundation = Engine.QueryInterface(this.repairTarget, IID_Foundation);
+					if (cmpFoundation)
+						cmpFoundation.RemoveBuilder(this.entity);
+					delete this.repairTarget;
 					this.StopTimer();
 				},
 
 				"Timer": function(msg) {
-					var target = this.order.data.target;
 					// Check we can still reach and repair the target
-					if (!this.CheckTargetRange(target, IID_Builder) || !this.CanRepair(target))
+					if (!this.CheckTargetRange(this.repairTarget, IID_Builder) || !this.CanRepair(this.repairTarget))
 					{
 						// Can't reach it, no longer owned by ally, or it doesn't exist any more
 						this.FinishOrder();
@@ -2138,7 +2141,7 @@
 					}
 					
 					var cmpBuilder = Engine.QueryInterface(this.entity, IID_Builder);
-					cmpBuilder.PerformBuilding(target);
+					cmpBuilder.PerformBuilding(this.repairTarget);
 				},
 			},
 
@@ -2592,7 +2595,15 @@
 			cmpSupply.RemoveGatherer(this.entity);
 		delete this.gatheringTarget;
 	}
-	
+	// And the Foundation builder count
+	if (this.repairTarget)
+	{
+		var cmpFoundation = Engine.QueryInterface(this.repairTarget, IID_Foundation);
+		if (cmpFoundation)
+			cmpFoundation.RemoveBuilder(this.entity);
+		delete this.repairTarget;
+	}
+
 	// Clean up range queries
 	var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
 	if (this.losRangeQuery)
