(svn r7377) -Fix (r7326): With gradual loading, make sure cargo is only paid for once, and always notify the station the vehicle was present. (Maedhros)
authorpeter1138
Tue, 05 Dec 2006 17:53:33 +0000
changeset 5251 3be755f9ab99
parent 5250 5409d3a866b3
child 5252 6823da581c30
(svn r7377) -Fix (r7326): With gradual loading, make sure cargo is only paid for once, and always notify the station the vehicle was present. (Maedhros)
economy.c
vehicle.h
--- a/economy.c	Tue Dec 05 17:09:57 2006 +0000
+++ b/economy.c	Tue Dec 05 17:53:33 2006 +0000
@@ -1317,10 +1317,16 @@
 	PlayerID old_player;
 	bool completely_empty = true;
 	byte load_amount;
+	bool anything_loaded = false;
 
 	assert(v->current_order.type == OT_LOADING);
 
 	v->cur_speed = 0;
+
+	/* Loading can only have finished when all the cargo has been unloaded, and
+	 * there is nothing left to load. It's easier to clear this if the
+	 * conditions haven't been met than attempting to check them all before
+	 * enabling though. */
 	SETBIT(v->load_status, LS_LOADING_FINISHED);
 
 	old_player = _current_player;
@@ -1339,7 +1345,7 @@
 
 		if (v->cargo_cap == 0) continue;
 
-		/* If the train has just arrived, set it to unload. */
+		/* If the vehicle has just arrived, set it to unload. */
 		if (just_arrived) SETBIT(v->load_status, LS_CARGO_UNLOADING);
 
 		ge = &st->goods[v->cargo_type];
@@ -1347,25 +1353,26 @@
 
 		/* unload? */
 		if (v->cargo_count != 0 && HASBIT(v->load_status, LS_CARGO_UNLOADING)) {
+			uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
+
+			CLRBIT(u->load_status, LS_LOADING_FINISHED);
+
 			if (v->cargo_source != last_visited && ge->waiting_acceptance & 0x8000 && !(u->current_order.flags & OF_TRANSFER)) {
 				// deliver goods to the station
 				st->time_since_unload = 0;
 
 				unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */
-				if (just_arrived) profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
+				if (just_arrived && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
+					profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
+					SETBIT(v->load_status, LS_CARGO_PAID_FOR);
+				}
 				result |= 1;
-				if (_patches.gradual_loading) {
-					v->cargo_count -= min(load_amount, v->cargo_count);
-					if (v->cargo_count != 0 || (count != 0 && !(u->current_order.flags & OF_UNLOAD))) CLRBIT(u->load_status, LS_LOADING_FINISHED);
-					continue;
-				} else {
-					v->cargo_count = 0;
-				}
+				v->cargo_count -= amount_unloaded;
+				if (_patches.gradual_loading) continue;
 			} else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
-				uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
 				/* unload goods and let it wait at the station */
 				st->time_since_unload = 0;
-				if (just_arrived && (u->current_order.flags & OF_TRANSFER)) {
+				if (just_arrived && (u->current_order.flags & OF_TRANSFER) && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
 					v_profit = GetTransportedGoodsIncome(
 						v->cargo_count,
 						DistanceManhattan(GetStation(v->cargo_source)->xy, GetStation(last_visited)->xy),
@@ -1373,6 +1380,7 @@
 						v->cargo_type) * 3 / 2;
 
 					v_profit_total += v_profit;
+					SETBIT(v->load_status, LS_CARGO_PAID_FOR);
 				}
 
 				unloading_time += v->cargo_count;
@@ -1397,22 +1405,20 @@
 				}
 				result |= 2;
 				v->cargo_count -= amount_unloaded;
-				if (_patches.gradual_loading) {
-					if (v->cargo_count != 0 || (count != 0 && !(u->current_order.flags & OF_UNLOAD))) CLRBIT(u->load_status, LS_LOADING_FINISHED);
-					continue;
-				}
+				if (_patches.gradual_loading) continue;
 			}
 
 			if (v->cargo_count != 0) completely_empty = false;
 		}
 
+		/* The vehicle must have been unloaded because it is either empty, or
+		 * the UNLOADING bit is already clear in v->load_status. */
+		CLRBIT(v->load_status, LS_CARGO_UNLOADING);
+		CLRBIT(v->load_status, LS_CARGO_PAID_FOR);
+
 		/* don't pick up goods that we unloaded */
 		if (u->current_order.flags & OF_UNLOAD) continue;
 
-		/* The vehicle must have been unloaded because it is either empty, or
-		 * v->cargo_unloading is already false. */
-		CLRBIT(v->load_status, LS_CARGO_UNLOADING);
-
 		/* update stats */
 		ge->days_since_pickup = 0;
 		switch (u->type) {
@@ -1447,6 +1453,7 @@
 			 * @completely_empty assignment can then be safely
 			 * removed; that's how TTDPatch behaves too. --pasky */
 			completely_empty = false;
+			anything_loaded = true;
 
 			if (cap > count) cap = count;
 			if (_patches.gradual_loading) cap = min(cap, load_amount);
@@ -1476,7 +1483,13 @@
 		uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
 
 		unloading_time = gradual_loading_wait_time[v->type - VEH_Train];
-		if (HASBIT(v->load_status, LS_LOADING_FINISHED)) unloading_time += 20;
+		if (HASBIT(v->load_status, LS_LOADING_FINISHED)) {
+			if (anything_loaded) {
+				unloading_time += 20;
+			} else {
+				unloading_time = 20;
+			}
+		}
 	}
 
 	if (v_profit_total > 0) {
--- a/vehicle.h	Tue Dec 05 17:09:57 2006 +0000
+++ b/vehicle.h	Tue Dec 05 17:53:33 2006 +0000
@@ -31,6 +31,7 @@
 enum LoadStatus {
 	LS_LOADING_FINISHED,
 	LS_CARGO_UNLOADING,
+	LS_CARGO_PAID_FOR,
 };
 
 /* Effect vehicle types */