Index: engine/action/action_repair.cpp
===================================================================
--- engine/action/action_repair.cpp	(revision 10239)
+++ engine/action/action_repair.cpp	(working copy)
@@ -34,6 +34,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <math.h>
 
 #include "stratagus.h"
 #include "unittype.h"
@@ -164,7 +165,7 @@
 			goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
 
 		int costs[MaxCosts];
-		CalculateRequestedAmount(unit->Type, unit->Orders[0]->Goal->Type->ProductionCosts, costs);
+		CalculateRequestedAmount(unit->Type, unit->Orders[0]->Goal->Data.Built.Progress, unit->Orders[0]->Goal->Type->ProductionCosts, costs);
 		unit->Player->AddToUnitsConsumingResources(unit, costs);
 	} else if (err < 0 || goalReached) {
 		if (goal) { // release reference
@@ -215,6 +216,7 @@
 */
 static bool DoRepair(CUnit *unit, CUnit *goal)
 {
+	int progress = 0;
 	int *pcosts = goal->Type->ProductionCosts;
 	int pcost = pcosts[EnergyCost] ? pcosts[EnergyCost] : pcosts[MagmaCost];
 	bool healed = false;
@@ -237,6 +239,8 @@
 			goal->Variable[HP_INDEX].Value = goal->Variable[HP_INDEX].Max;
 			healed = true;
 		}
+
+		progress = goal->Data.Repair.Progress;
 	} else {
 		// hp is the current damage taken by the unit.
 		int hp = (goal->Data.Built.Progress * goal->Variable[HP_INDEX].Max) / pcost - goal->Variable[HP_INDEX].Value;
@@ -255,7 +259,14 @@
 			goal->Variable[HP_INDEX].Value = goal->Variable[HP_INDEX].Max;
 			healed = true;
 		}
+
+		progress = goal->Data.Built.Progress;
 	}
+
+	int newCosts[MaxCosts];
+	CalculateRequestedAmount(unit->Type, progress, pcosts, newCosts);
+	unit->Player->UpdateUnitsConsumingResourcesRequest(unit, newCosts);
+
 	return healed;
 }
 
Index: engine/action/action_resource.cpp
===================================================================
--- engine/action/action_resource.cpp	(revision 10239)
+++ engine/action/action_resource.cpp	(working copy)
@@ -35,6 +35,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <math.h>
 
 #include "stratagus.h"
 #include "player.h"
@@ -240,10 +241,28 @@
 		}
 
 		// Calculate new resource amounts
-		CalculateRequestedAmount(unit->Type, source->ResourcesHeld, amount);
+		// TODO The code should be redesigned so we don't have to mimic the structure in CalculateRequestedAmount().  Maybe by adding Data.Harvest.Progress like the other progress variables.
+		int progress;
+		if (source->Type->ProductionCosts[EnergyCost] == 0) {
+			progress = source->ResourcesHeld[MagmaCost];
+		} else if (source->Type->ProductionCosts[MagmaCost] == 0) {
+			progress = source->ResourcesHeld[EnergyCost];
+		} else {
+			Assert(unit->Type->MaxUtilizationRate[EnergyCost] != 0);
+			Assert(unit->Type->MaxUtilizationRate[MagmaCost] != 0);
+			int f = 100 * source->Type->ProductionCosts[EnergyCost] * unit->Type->MaxUtilizationRate[MagmaCost] /
+				(source->Type->ProductionCosts[MagmaCost] * unit->Type->MaxUtilizationRate[EnergyCost]);
+			if (f < 100) {
+				progress = source->ResourcesHeld[MagmaCost];
+			} else {
+				progress = source->ResourcesHeld[EnergyCost];
+			}
+		}
+		CalculateRequestedAmount(unit->Type, progress, source->Type->ProductionCosts, amount);
+
 		for (i = 0; i < MaxCosts; ++i) {
 			unit->Player->ProductionRate[i] -= unit->Data.Harvest.CurrentProduction[i];
-			unit->Data.Harvest.CurrentProduction[i] = amount[i] * efficiency[i] / 100;
+			unit->Data.Harvest.CurrentProduction[i] = ceil(amount[i] * efficiency[i] / 100.0);
 			unit->Player->ProductionRate[i] += unit->Data.Harvest.CurrentProduction[i];
 			source->ResourcesHeld[i] -= amount[i];
 		}
@@ -252,7 +271,7 @@
 		if (efficiency != totalEfficiency) {
 			source->Variable[HP_INDEX].Value = source->Variable[HP_INDEX].Max *
 				source->ResourcesHeld[1] / source->Type->ProductionCosts[1];
-			if (source->Variable[HP_INDEX].Value == 0 && source->ResourcesHeld[1] != 0) {
+			if (source->Variable[HP_INDEX].Value == 0 && source->ResourcesHeld[1] > 0) {
 				source->Variable[HP_INDEX].Value = 1;
 			}
 		}
Index: engine/action/action_train.cpp
===================================================================
--- engine/action/action_train.cpp	(revision 10239)
+++ engine/action/action_train.cpp	(working copy)
@@ -149,7 +149,7 @@
 		unit->SubAction = 1;
 
 		int costs[MaxCosts];
-		CalculateRequestedAmount(unit->Type, unit->Orders[0]->Type->ProductionCosts, costs);
+		CalculateRequestedAmount(unit->Type, unit->Data.Train.Ticks, unit->Orders[0]->Type->ProductionCosts, costs);
 		unit->Player->AddToUnitsConsumingResources(unit, costs);
 	} else {
 		int *costs = unit->Player->UnitsConsumingResourcesActual[unit];
@@ -158,6 +158,10 @@
 		if (unit->Data.Train.Ticks > pcost) {
 			unit->Data.Train.Ticks = pcost;
 		}
+
+		int newCosts[MaxCosts];
+		CalculateRequestedAmount(unit->Type, unit->Data.Train.Ticks, unit->Orders[0]->Type->ProductionCosts, newCosts);
+		unit->Player->UpdateUnitsConsumingResourcesRequest(unit, newCosts);
 	}
 
 	unit->Type->Animations->Train ?
Index: engine/game/player.cpp
===================================================================
--- engine/game/player.cpp	(revision 10239)
+++ engine/game/player.cpp	(working copy)
@@ -37,6 +37,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <algorithm>
+#include <math.h>
 
 #include "stratagus.h"
 #include "video.h"
@@ -183,13 +184,30 @@
 }
 
 /**
+ ** Update requested costs for unit in UnitsConsumingResourcesRequest
+ */
+void CPlayer::UpdateUnitsConsumingResourcesRequest(CUnit *unit, int costs[MaxCosts])
+{
+	Assert(UnitsConsumingResourcesRequested[unit] != NULL);
+
+	int *crequested = UnitsConsumingResourcesRequested[unit];
+
+	for (int i = 0; i < MaxCosts; ++i) {
+		RequestedUtilizationRate[i] -= crequested[i];
+		crequested[i] = costs[i];
+		RequestedUtilizationRate[i] += crequested[i];
+	}
+}
+
+/**
 **  Calculate how many resources the unit needs to request
 **
-**  @param utype   builder unit type
-**  @param bcosts  costs of unit type being built or harvested
-**  @param costs   returns the resource amount
+**  @param utype    builder unit type
+**  @param progress amount already built or left to be harvested
+**  @param bcosts   costs of unit type being built or harvested
+**  @param costs    returns the resource amount
 */
-void CalculateRequestedAmount(CUnitType *utype, int bcosts[MaxCosts], int costs[MaxCosts])
+void CalculateRequestedAmount(CUnitType *utype, int progress, int bcosts[MaxCosts], int costs[MaxCosts])
 {
 	if (bcosts[EnergyCost] == 0) {
 		costs[EnergyCost] = 0;
@@ -198,17 +216,33 @@
 		costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
 		costs[MagmaCost] = 0;
 	} else {
+		// Note: Changes to how f is handled might require similar changes in action_resources.cpp.
 		int f = 100 * bcosts[EnergyCost] * utype->MaxUtilizationRate[MagmaCost] /
 			(bcosts[MagmaCost] * utype->MaxUtilizationRate[EnergyCost]);
-		if (f > 100) {
+
+		if (f == 100) {
 			costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
-			costs[MagmaCost] = (utype->MaxUtilizationRate[MagmaCost] * 100 + f / 2) / f;
-		} else if (f < 100) {
-			costs[EnergyCost] = (utype->MaxUtilizationRate[EnergyCost] * f + 50) / 100;
 			costs[MagmaCost] = utype->MaxUtilizationRate[MagmaCost];
 		} else {
-			costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
-			costs[MagmaCost] = utype->MaxUtilizationRate[MagmaCost];
+			int primaryResource = EnergyCost;
+			int otherResources = MagmaCost;
+			if (f < 100) {
+				primaryResource = MagmaCost;
+				otherResources = EnergyCost;
+			}
+
+			costs[primaryResource] = utype->MaxUtilizationRate[primaryResource];
+
+			//adaptive rates for the other resources
+			int time = bcosts[primaryResource] / costs[primaryResource]; // cycles to build
+			int lowerRate = floor(bcosts[otherResources] / time);        // standard usage rate
+			int consumed = time * lowerRate;                             // amount of resources used
+			int stillNeed = bcosts[otherResources] - consumed;           // amount of resources left
+			if (progress < stillNeed * costs[primaryResource]) {
+				costs[otherResources] = lowerRate + 1;
+			} else {
+				costs[otherResources] = lowerRate;
+			}
 		}
 	}
 
@@ -225,15 +259,18 @@
 */
 void CPlayer::RebuildUnitsConsumingResourcesList()
 {
+	CUnit *unit;
+	COrder *order;
 	for (int i = 0; i < TotalNumUnits; ++i) {
 		int costs[MaxCosts];
-		CUnit *unit = Units[i];
+		unit = Units[i];
+		order = unit->Orders[0];
 
-		if (unit->Orders[0]->Action == UnitActionTrain && unit->SubAction != 0) {
-			CalculateRequestedAmount(unit->Type, unit->Orders[0]->Type->ProductionCosts, costs);
+		if (order->Action == UnitActionTrain && unit->SubAction != 0) {
+			CalculateRequestedAmount(unit->Type, unit->Data.Train.Ticks, order->Type->ProductionCosts, costs);
 			AddToUnitsConsumingResources(unit, costs);
-		} else if (unit->Orders[0]->Action == UnitActionRepair && unit->SubAction == 20) {
-			CalculateRequestedAmount(unit->Type, unit->Orders[0]->Goal->Type->ProductionCosts, costs);
+		} else if (order->Action == UnitActionRepair && unit->SubAction == 20) {
+			CalculateRequestedAmount(unit->Type, order->Goal->Data.Repair.Progress, order->Goal->Type->ProductionCosts, costs);
 			AddToUnitsConsumingResources(unit, costs);
 		}
 	}
Index: engine/include/player.h
===================================================================
--- engine/include/player.h	(revision 10239)
+++ engine/include/player.h	(working copy)
@@ -364,6 +364,7 @@
 	void AddToUnitsConsumingResources(CUnit *unit, int costs[MaxCosts]);
 	void RemoveFromUnitsConsumingResources(CUnit *unit);
 	void UpdateUnitsConsumingResources(CUnit *unit, int costs[MaxCosts]);
+	void UpdateUnitsConsumingResourcesRequest(CUnit *unit, int costs[MaxCosts]);
 	void RebuildUnitsConsumingResourcesList();
 	void ClearResourceVariables();
 
@@ -480,7 +481,7 @@
 extern void GraphicPlayerPixels(CPlayer *player, const CGraphic *sprite);
 
 	/// Calculate how many resources the unit needs to request
-void CalculateRequestedAmount(CUnitType *utype, int bcosts[MaxCosts], int costs[MaxCosts]);
+void CalculateRequestedAmount(CUnitType *utype, int progress, int bcosts[MaxCosts], int costs[MaxCosts]);
 
 	/// Output debug informations for players
 extern void DebugPlayers(void);
Index: engine/unit/unit.cpp
===================================================================
--- engine/unit/unit.cpp	(revision 10239)
+++ engine/unit/unit.cpp	(working copy)
@@ -1421,7 +1421,7 @@
 bool UnitHoldsResources(const CUnit *unit)
 {
 	for (int i = 0; i < MaxCosts; ++i) {
-		if (unit->ResourcesHeld[i] != 0) {
+		if (unit->ResourcesHeld[i] > 0) {
 			return true;
 		}
 	}
