(svn r10205) -Codechange: refactor returning of cost, so it can be more easily modified.
authorrubidium
Mon, 18 Jun 2007 19:53:50 +0000
changeset 6950 14ecb0acdfb4
parent 6949 5de26c8fe2ef
child 6951 b24e0f108ede
(svn r10205) -Codechange: refactor returning of cost, so it can be more easily modified.
src/ai/ai.cpp
src/ai/default/default.cpp
src/ai/trolly/build.cpp
src/ai/trolly/trolly.cpp
src/aircraft_cmd.cpp
src/autoreplace_cmd.cpp
src/bridge_gui.cpp
src/clear_cmd.cpp
src/command.cpp
src/command.h
src/economy.cpp
src/engine.cpp
src/group_cmd.cpp
src/industry_cmd.cpp
src/landscape.cpp
src/misc_cmd.cpp
src/misc_gui.cpp
src/openttd.h
src/order_cmd.cpp
src/players.cpp
src/rail_cmd.cpp
src/road_cmd.cpp
src/roadveh_cmd.cpp
src/settings.cpp
src/settings_gui.cpp
src/ship_cmd.cpp
src/signs.cpp
src/station_cmd.cpp
src/town_cmd.cpp
src/train_cmd.cpp
src/tree_cmd.cpp
src/tunnelbridge_cmd.cpp
src/unmovable_cmd.cpp
src/vehicle.cpp
src/vehicle_gui.cpp
src/water_cmd.cpp
src/waypoint.cpp
--- a/src/ai/ai.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/ai/ai.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -84,7 +84,7 @@
 CommandCost AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback)
 {
 	PlayerID old_lp;
-	CommandCost res = 0;
+	CommandCost res;
 	const char* tmp_cmdtext;
 
 	/* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
--- a/src/ai/default/default.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/ai/default/default.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -152,7 +152,7 @@
 		}
 
 		ret = DoCommand(tile, i, 0, 0, CMD_BUILD_RAIL_VEHICLE);
-		if (CmdSucceeded(ret) && ret <= money && rvi->ai_rank >= best_veh_score) {
+		if (CmdSucceeded(ret) && ret.GetCost() <= money && rvi->ai_rank >= best_veh_score) {
 			best_veh_score = rvi->ai_rank;
 			best_veh_index = i;
 		}
@@ -189,8 +189,8 @@
 		if (CmdFailed(ret)) continue;
 
 		/* Add the cost of refitting */
-		if (rvi->cargo_type != cargo) ret += GetRefitCost(i);
-		if (ret > money) continue;
+		if (rvi->cargo_type != cargo) ret.AddCost(GetRefitCost(i));
+		if (ret.GetCost() > money) continue;
 
 		best_veh_rating = rating;
 		best_veh_index = i;
@@ -216,8 +216,8 @@
 		if ((AircraftVehInfo(i)->subtype & AIR_CTOL) != flag) continue;
 
 		ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT);
-		if (CmdSucceeded(ret) && ret <= money && ret >= best_veh_cost) {
-			best_veh_cost = ret;
+		if (CmdSucceeded(ret) && ret.GetCost() <= money && ret.GetCost() >= best_veh_cost) {
+			best_veh_cost = ret.GetCost();
 			best_veh_index = i;
 		}
 	}
@@ -1641,7 +1641,7 @@
 static CommandCost AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBlockData* p, RailType railtype, byte flag)
 {
 	CommandCost ret;
-	CommandCost total_cost = 0;
+	CommandCost total_cost;
 	Town *t = NULL;
 	int rating = 0;
 	int i, j, k;
@@ -1662,7 +1662,7 @@
 			}
 
 			if (CmdFailed(ret)) return CMD_ERROR;
-			total_cost += ret;
+			total_cost.AddCost(ret);
 
 clear_town_stuff:;
 			if (_cleared_town != NULL) {
@@ -1684,7 +1684,7 @@
 					k = i;
 					ret = DoCommand(c, railtype, i, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
 					if (CmdFailed(ret)) return CMD_ERROR;
-					total_cost += ret;
+					total_cost.AddCost(ret);
 				}
 			}
 
@@ -1699,17 +1699,18 @@
 						ret = DoCommand(c, k, 0, flag, CMD_BUILD_SIGNALS);
 					} while (--j);
 				} else {
-					ret = _price.build_signals;
+					ret.AddCost(_price.build_signals);
 				}
 				if (CmdFailed(ret)) return CMD_ERROR;
-				total_cost += ret;
+				total_cost.AddCost(ret);
 			}
 		} else if (p->mode == 3) {
 			//Clear stuff and then build single rail.
 			if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR;
 			ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return CMD_ERROR;
-			total_cost += ret + _price.build_rail;
+			total_cost.AddCost(ret);
+			total_cost.AddCost(_price.build_rail);
 
 			if (flag & DC_EXEC) {
 				DoCommand(c, railtype, p->attr & 1, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_SINGLE_RAIL);
@@ -2069,7 +2070,7 @@
 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
 		CommandCost cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL);
 
-		if (CmdSucceeded(cost) && cost <= (arf->player->player_money >> 4)) {
+		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
 			AiBuildRailRecursive(arf, _build_tunnel_endtile, p[0] & 3);
 			if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
 		}
@@ -2210,8 +2211,8 @@
 		 */
 		for (i = MAX_BRIDGES - 1; i != 0; i--) {
 			if (CheckBridge_Stuff(i, bridge_len)) {
-				int32 cost = DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
-				if (CmdSucceeded(cost) && cost < (p->player_money >> 5)) break;
+				CommandCost cost = DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+				if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
 			}
 		}
 
@@ -2629,7 +2630,7 @@
 static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
 {
 	CommandCost ret;
-	CommandCost total_cost = 0;
+	CommandCost total_cost;
 	Town *t = NULL;
 	int rating = 0;
 	int roadflag = 0;
@@ -2651,7 +2652,7 @@
 
 			ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
 			if (CmdFailed(ret)) return CMD_ERROR;
-			total_cost += ret;
+			total_cost.AddCost(ret);
 
 			continue;
 		}
@@ -2671,7 +2672,7 @@
 clear_town_stuff:;
 
 			if (CmdFailed(ret)) return CMD_ERROR;
-			total_cost += ret;
+			total_cost.AddCost(ret);
 
 			if (_cleared_town != NULL) {
 				if (t != NULL && t != _cleared_town) return CMD_ERROR;
@@ -2969,7 +2970,7 @@
 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
 		CommandCost cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
 
-		if (CmdSucceeded(cost) && cost <= (arf->player->player_money >> 4)) {
+		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
 			AiBuildRoadRecursive(arf, _build_tunnel_endtile, p[0] & 3);
 			if (arf->depth == 1)  AiCheckRoadPathBetter(arf, p);
 		}
@@ -3102,7 +3103,7 @@
 		for (i = 10; i != 0; i--) {
 			if (CheckBridge_Stuff(i, bridge_len)) {
 				CommandCost cost = DoCommand(tile, p->ai.cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE);
-				if (CmdSucceeded(cost) && cost < (p->player_money >> 5)) break;
+				if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
 			}
 		}
 
@@ -3390,13 +3391,13 @@
 static CommandCost AiDoBuildDefaultAirportBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
 {
 	uint32 avail_airports = GetValidAirports();
-	CommandCost total_cost = 0, ret;
+	CommandCost total_cost, ret;
 
 	for (; p->mode == 0; p++) {
 		if (!HASBIT(avail_airports, p->attr)) return CMD_ERROR;
 		ret = DoCommand(TILE_MASK(tile + ToTileIndexDiff(p->tileoffs)), p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_AIRPORT);
 		if (CmdFailed(ret)) return CMD_ERROR;
-		total_cost += ret;
+		total_cost.AddCost(ret);
 	}
 
 	return total_cost;
--- a/src/ai/trolly/build.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/ai/trolly/build.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -97,7 +97,7 @@
 	TileIndex *route = PathFinderInfo->route;
 	int dir;
 	int old_dir = -1;
-	CommandCost cost = 0;
+	CommandCost cost;
 	CommandCost res;
 	// We need to calculate the direction with the parent of the parent.. so we skip
 	//  the first pieces and the last piece
@@ -105,30 +105,30 @@
 	// When we are done, stop it
 	if (part >= PathFinderInfo->route_length - 1) {
 		PathFinderInfo->position = -2;
-		return 0;
+		return CommandCost();
 	}
 
 
 	if (PathFinderInfo->rail_or_road) {
 		// Tunnel code
 		if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
-			cost += AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL);
+			cost.AddCost(AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL));
 			PathFinderInfo->position++;
 			// TODO: problems!
 			if (CmdFailed(cost)) {
 				DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
-				return 0;
+				return CommandCost();
 			}
 			return cost;
 		}
 		// Bridge code
 		if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
-			cost += AiNew_Build_Bridge(p, route[part], route[part - 1], flag);
+			cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part - 1], flag));
 			PathFinderInfo->position++;
 			// TODO: problems!
 			if (CmdFailed(cost)) {
 				DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part - 1]);
-				return 0;
+				return CommandCost();
 			}
 			return cost;
 		}
@@ -147,9 +147,9 @@
 				if (CmdFailed(res)) {
 					// Problem.. let's just abort it all!
 					p->ainew.state = AI_STATE_NOTHING;
-					return 0;
+					return CommandCost();
 				}
-				cost += res;
+				cost.AddCost(res);
 				// Go to the next tile
 				part++;
 				// Check if it is still in range..
@@ -162,23 +162,23 @@
 	} else {
 		// Tunnel code
 		if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
-			cost += AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL);
+			cost.AddCost(AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL));
 			PathFinderInfo->position++;
 			// TODO: problems!
 			if (CmdFailed(cost)) {
 				DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
-				return 0;
+				return CommandCost();
 			}
 			return cost;
 		}
 		// Bridge code
 		if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
-			cost += AiNew_Build_Bridge(p, route[part], route[part + 1], flag);
+			cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part + 1], flag));
 			PathFinderInfo->position++;
 			// TODO: problems!
 			if (CmdFailed(cost)) {
 				DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part + 1]);
-				return 0;
+				return CommandCost();
 			}
 			return cost;
 		}
@@ -203,10 +203,10 @@
 						// Problem.. let's just abort it all!
 						DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
 						p->ainew.state = AI_STATE_NOTHING;
-						return 0;
+						return CommandCost();
 					}
 
-					if (CmdSucceeded(res)) cost += res;
+					if (CmdSucceeded(res)) cost.AddCost(res);
 				}
 				// Go to the next tile
 				part++;
@@ -314,11 +314,12 @@
 		return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
 	} else {
 		ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
-		if (CmdFailed(ret)) return ret;
+		if (CmdFailed(ret2)) return ret;
 		// Try to build the road from the depot
 		ret2 = AI_DoCommand(tile + TileOffsByDiagDir(direction), DiagDirToRoadBits(ReverseDiagDir(direction)), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
 		// If it fails, ignore it..
 		if (CmdFailed(ret2)) return ret;
-		return ret + ret2;
+		ret.AddCost(ret2);
+		return ret;
 	}
 }
--- a/src/ai/trolly/trolly.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/ai/trolly/trolly.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -691,7 +691,7 @@
 
 		// See how much it is going to cost us...
 		r = AiNew_Build_Station(p, p->ainew.tbt, new_tile, 0, 0, 0, DC_QUERY_COST);
-		p->ainew.new_cost += r;
+		p->ainew.new_cost += r.GetCost();
 
 		direction = AI_PATHFINDER_NO_DIRECTION;
 	} else if (new_tile == 0 && p->ainew.tbt == AI_TRUCK) {
@@ -850,7 +850,7 @@
 				r = AiNew_Build_Depot(p, t, ReverseDiagDir(j), 0);
 				if (CmdFailed(r)) continue;
 				// Found a spot!
-				p->ainew.new_cost += r;
+				p->ainew.new_cost += r.GetCost();
 				p->ainew.depot_tile = t;
 				p->ainew.depot_direction = ReverseDiagDir(j); // Reverse direction
 				p->ainew.state = AI_STATE_VERIFY_ROUTE;
@@ -935,7 +935,7 @@
 
 	do {
 		p->ainew.path_info.position++;
-		p->ainew.new_cost += AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_QUERY_COST);
+		p->ainew.new_cost += AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_QUERY_COST).GetCost();
 	} while (p->ainew.path_info.position != -2);
 
 	// Now we know the price of build station + path. Now check how many vehicles
@@ -951,7 +951,7 @@
 
 	// Check how much it it going to cost us..
 	for (i=0;i<res;i++) {
-		p->ainew.new_cost += AiNew_Build_Vehicle(p, 0, DC_QUERY_COST);
+		p->ainew.new_cost += AiNew_Build_Vehicle(p, 0, DC_QUERY_COST).GetCost();
 	}
 
 	// Now we know how much the route is going to cost us
@@ -985,7 +985,7 @@
 // Build the stations
 static void AiNew_State_BuildStation(Player *p)
 {
-	CommandCost res = 0;
+	CommandCost res;
 	assert(p->ainew.state == AI_STATE_BUILD_STATION);
 	if (p->ainew.temp == 0) {
 		if (!IsTileType(p->ainew.from_tile, MP_STATION))
@@ -1103,7 +1103,7 @@
 // Builds the depot
 static void AiNew_State_BuildDepot(Player *p)
 {
-	CommandCost res = 0;
+	CommandCost res;
 	assert(p->ainew.state == AI_STATE_BUILD_DEPOT);
 
 	if (IsTileType(p->ainew.depot_tile, MP_STREET) && GetRoadTileType(p->ainew.depot_tile) == ROAD_TILE_DEPOT) {
@@ -1278,7 +1278,7 @@
 
 			if (!AiNew_SetSpecialVehicleFlag(p, v, AI_VEHICLEFLAG_SELL)) return;
 			{
-				CommandCost ret = 0;
+				CommandCost ret;
 				if (v->type == VEH_ROAD)
 					ret = AI_DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
 				// This means we can not find a depot :s
--- a/src/aircraft_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/aircraft_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -229,7 +229,7 @@
 
 static CommandCost EstimateAircraftCost(EngineID engine, const AircraftVehicleInfo *avi)
 {
-	return GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5;
+	return CommandCost(GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5);
 }
 
 
@@ -346,7 +346,7 @@
 
 		v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER);
 		v->UpdateDeltaXY(INVALID_DIR);
-		v->value = value;
+		v->value = (uint32)value.GetCost();
 
 		u->subtype = AIR_SHADOW;
 		u->UpdateDeltaXY(INVALID_DIR);
@@ -493,7 +493,7 @@
 		DoDeleteAircraft(v);
 	}
 
-	return -(int32)v->value;
+	return CommandCost(-(int32)v->value);
 }
 
 /** Start/Stop an aircraft.
@@ -534,7 +534,7 @@
 		InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Send an aircraft to the hangar.
@@ -569,7 +569,7 @@
 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 			}
-			return 0;
+			return CommandCost();
 		}
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
@@ -609,7 +609,7 @@
 		}
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -668,7 +668,7 @@
 	}
 	_returned_refit_capacity = pass;
 
-	CommandCost cost = 0;
+	CommandCost cost;
 	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 		cost = GetRefitCost(v->engine_type);
 	}
@@ -744,9 +744,9 @@
 
 	if (v->vehstatus & VS_STOPPED) return;
 
-	CommandCost cost = GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364;
+	CommandCost cost = CommandCost(GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364);
 
-	v->profit_this_year -= cost >> 8;
+	v->profit_this_year -= cost.GetCost() >> 8;
 
 	SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
 	SubtractMoneyFromPlayerFract(v->owner, cost);
--- a/src/autoreplace_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/autoreplace_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -154,7 +154,7 @@
 	replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type);
 
 	/* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */
-	if (replacement_cargo_type == CT_INVALID) return 0;
+	if (replacement_cargo_type == CT_INVALID) return CommandCost();
 
 	sell_value = DoCommand(0, old_v->index, 0, DC_QUERY_COST, GetCmdSellVeh(old_v));
 
@@ -167,15 +167,17 @@
 	cost = DoCommand(old_v->tile, new_engine_type, 3, flags, GetCmdBuildVeh(old_v));
 	if (CmdFailed(cost)) {
 		SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-		SubtractMoneyFromPlayer(-sell_value); // Take back the money we just gave the player
+		/* Take back the money we just gave the player */
+		sell_value.MultiplyCost(-1);
+		SubtractMoneyFromPlayer(sell_value);
 		return cost;
 	}
 
 	if (replacement_cargo_type != CT_NO_REFIT) {
 		/* add refit cost */
 		CommandCost refit_cost = GetRefitCost(new_engine_type);
-		if (old_v->type == VEH_TRAIN && IsMultiheaded(old_v)) refit_cost += refit_cost; // pay for both ends
-		cost += refit_cost;
+		if (old_v->type == VEH_TRAIN && IsMultiheaded(old_v)) refit_cost.AddCost(refit_cost); // pay for both ends
+		cost.AddCost(refit_cost);
 	}
 
 	if (flags & DC_EXEC) {
@@ -246,7 +248,7 @@
 			GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
 		}
 	} else { // flags & DC_EXEC not set
-		CommandCost tmp_move = 0;
+		CommandCost tmp_move;
 		if (old_v->type == VEH_TRAIN && IsFrontEngine(old_v) && old_v->next != NULL) {
 			/* Verify that the wagons can be placed on the engine in question.
 			 * This is done by building an engine, test if the wagons can be added and then sell the test engine. */
@@ -258,9 +260,11 @@
 
 		/* Ensure that the player will not end up having negative money while autoreplacing
 		 * This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */
-		if (CmdFailed(tmp_move) || p->money64 < (cost + total_cost)) {
+		if (CmdFailed(tmp_move) || p->money64 < (cost.GetCost() + total_cost)) {
 			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-			SubtractMoneyFromPlayer(-sell_value); // Pay back the loan
+			/* Pay back the loan */
+			sell_value.MultiplyCost(-1);
+			SubtractMoneyFromPlayer(sell_value);
 			return CMD_ERROR;
 		}
 	}
@@ -268,10 +272,11 @@
 	/* Take back the money we just gave the player just before building the vehicle
 	 * The player will get the same amount now that the sale actually takes place */
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-	SubtractMoneyFromPlayer(-sell_value);
+	sell_value.MultiplyCost(-1);
+	SubtractMoneyFromPlayer(sell_value);
 
 	/* sell the engine/ find out how much you get for the old engine (income is returned as negative cost) */
-	cost += DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v));
+	cost.AddCost(DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v)));
 
 	if (new_front) {
 		/* now we assign the old unitnumber to the new vehicle */
@@ -300,7 +305,7 @@
 	Vehicle *w;
 	const Player *p = GetPlayer(v->owner);
 	byte flags = 0;
-	CommandCost cost, temp_cost = 0;
+	CommandCost cost, temp_cost;
 	bool stopped;
 
 	/* Remember the length in case we need to trim train later on
@@ -326,7 +331,7 @@
 	v->leave_depot_instantly = false;
 
 	for (;;) {
-		cost = 0;
+		cost = CommandCost();
 		w = v;
 		do {
 			if (w->type == VEH_TRAIN && IsMultiheaded(w) && !IsTrainEngine(w)) {
@@ -352,7 +357,7 @@
 			}
 
 			/* Now replace the vehicle */
-			temp_cost = ReplaceVehicle(&w, flags, cost);
+			temp_cost = ReplaceVehicle(&w, flags, cost.GetCost());
 
 			if (CmdFailed(temp_cost)) break; // replace failed for some reason. Leave the vehicle alone
 
@@ -364,11 +369,11 @@
 				 */
 				v = w;
 			}
-			cost += temp_cost;
+			cost.AddCost(temp_cost);
 		} while (w->type == VEH_TRAIN && (w = GetNextVehicle(w)) != NULL);
 
-		if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost + p->engine_renew_money) || cost == 0)) {
-			if (!check && p->money64 < (int32)(cost + p->engine_renew_money) && ( _local_player == v->owner ) && cost != 0) {
+		if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost.GetCost() + p->engine_renew_money) || cost.GetCost() == 0)) {
+			if (!check && p->money64 < (int32)(cost.GetCost() + p->engine_renew_money) && ( _local_player == v->owner ) && cost.GetCost() != 0) {
 				StringID message;
 				SetDParam(0, v->unitnumber);
 				switch (v->type) {
@@ -418,13 +423,13 @@
 			w = GetNextVehicle(w);
 			DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
 			MoveVehicleCargo(v, temp);
-			cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON);
+			cost.AddCost(DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON));
 		}
 	}
 
 	if (stopped) v->vehstatus &= ~VS_STOPPED;
 	if (display_costs) {
-		if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
+		if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
 		_current_player = OWNER_NONE;
 	}
 	return cost;
--- a/src/bridge_gui.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/bridge_gui.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -145,7 +145,7 @@
 				const Bridge *b = &_bridge[bridge_type];
 				// bridge is accepted, add to list
 				// add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST)
-				_bridgedata.costs[j] = ret + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
+				_bridgedata.costs[j] = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
 				_bridgedata.indexes[j] = bridge_type;
 				j++;
 			}
--- a/src/clear_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/clear_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -148,7 +148,7 @@
 		return -1;
 	}
 
-	ts->cost += ret;
+	ts->cost.AddCost(ret.GetCost());
 
 	if (ts->tile_table_count >= 625) return -1;
 	ts->tile_table[ts->tile_table_count++] = tile;
@@ -198,7 +198,7 @@
 	mod->tile = tile;
 	mod->height = (byte)height;
 
-	ts->cost += _price.terraform;
+	ts->cost.AddCost(_price.terraform);
 
 	{
 		int direction = ts->direction, r;
@@ -248,7 +248,7 @@
 	ts.direction = direction = p2 ? 1 : -1;
 	ts.flags = flags;
 	ts.modheight_count = ts.tile_table_count = 0;
-	ts.cost = 0;
+	ts.cost = CommandCost();
 	ts.modheight = modheight_data;
 	ts.tile_table = tile_table_data;
 
@@ -364,7 +364,7 @@
 	int ey;
 	int sx, sy;
 	uint h, curh;
-	int32 money;
+	CommandCost money;
 	CommandCost ret;
 	CommandCost cost;
 
@@ -387,29 +387,29 @@
 	size_x = ex - sx + 1;
 	size_y = ey - sy + 1;
 
-	money = GetAvailableMoneyForCommand();
-	cost = 0;
+	money.AddCost(GetAvailableMoneyForCommand());
 
 	BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) {
 		curh = TileHeight(tile2);
 		while (curh != h) {
 			ret = DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND);
 			if (CmdFailed(ret)) break;
-			cost += ret;
 
 			if (flags & DC_EXEC) {
-				if ((money -= ret) < 0) {
-					_additional_cash_required = ret;
-					return cost - ret;
+				money.AddCost(-ret.GetCost());
+				if (money.GetCost() < 0) {
+					_additional_cash_required = ret.GetCost();
+					return cost;
 				}
 				DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
 			}
 
+			cost.AddCost(ret);
 			curh += (curh > h) ? -1 : 1;
 		}
 	} END_TILE_LOOP(tile2, size_x, size_y, tile)
 
-	return (cost == 0) ? CMD_ERROR : cost;
+	return (cost.GetCost() == 0) ? CMD_ERROR : cost;
 }
 
 /** Purchase a land area. Actually you only purchase one tile, so
@@ -440,7 +440,7 @@
 		MarkTileDirtyByTile(tile);
 	}
 
-	return cost + _price.purchase_land * 10;
+	return cost.AddCost(_price.purchase_land * 10);
 }
 
 
@@ -457,10 +457,8 @@
 	};
 	CommandCost price;
 
-	if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) {
-		price = 0;
-	} else {
-		price = *clear_price_table[GetClearGround(tile)];
+	if (!IsClearGround(tile, CLEAR_GRASS) || GetClearDensity(tile) != 0) {
+		price.AddCost(*clear_price_table[GetClearGround(tile)]);
 	}
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
@@ -488,7 +486,7 @@
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
 
-	return - _price.purchase_land * 2;
+	return CommandCost(- _price.purchase_land * 2);
 }
 
 
--- a/src/command.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/command.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -372,13 +372,13 @@
 	if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) {
 		res = proc(tile, flags & ~DC_EXEC, p1, p2);
 		if (CmdFailed(res)) {
-			if (res & 0xFFFF) _error_message = res & 0xFFFF;
+			res.SetGlobalErrorMessage();
 			goto error;
 		}
 
 		if (_docommand_recursive == 1 &&
 				!(flags & DC_QUERY_COST) &&
-				res != 0 &&
+				res.GetCost() != 0 &&
 				!CheckPlayerHasMoney(res)) {
 			goto error;
 		}
@@ -394,7 +394,7 @@
 	 * themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */
 	res = proc(tile, flags, p1, p2);
 	if (CmdFailed(res)) {
-		if (res & 0xFFFF) _error_message = res & 0xFFFF;
+		res.SetGlobalErrorMessage();
 error:
 		_docommand_recursive--;
 		_cmd_text = NULL;
@@ -425,7 +425,7 @@
  * the callback is called when the command succeeded or failed. */
 bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd)
 {
-	CommandCost res = 0, res2;
+	CommandCost res, res2;
 	CommandProc *proc;
 	uint32 flags;
 	bool notest;
@@ -497,10 +497,10 @@
 		/* estimate the cost. */
 		res = proc(tile, flags, p1, p2);
 		if (CmdFailed(res)) {
-			if (res & 0xFFFF) _error_message = res & 0xFFFF;
+			res.SetGlobalErrorMessage();
 			ShowErrorMessage(_error_message, error_part1, x, y);
 		} else {
-			ShowEstimatedCostOrIncome(res, x, y);
+			ShowEstimatedCostOrIncome(res.GetCost(), x, y);
 		}
 
 		_docommand_recursive = 0;
@@ -513,11 +513,11 @@
 		/* first test if the command can be executed. */
 		res = proc(tile, flags, p1, p2);
 		if (CmdFailed(res)) {
-			if (res & 0xFFFF) _error_message = res & 0xFFFF;
+			res.SetGlobalErrorMessage();
 			goto show_error;
 		}
 		/* no money? Only check if notest is off */
-		if (!notest && res != 0 && !CheckPlayerHasMoney(res)) goto show_error;
+		if (!notest && res.GetCost() != 0 && !CheckPlayerHasMoney(res)) goto show_error;
 	}
 
 #ifdef ENABLE_NETWORK
@@ -552,10 +552,10 @@
 	/* If notest is on, it means the result of the test can be different than
 	 *  the real command.. so ignore the test */
 	if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
-		assert(res == res2); // sanity check
+		assert(res.GetCost() == res2.GetCost() && CmdFailed(res) == CmdFailed(res2)); // sanity check
 	} else {
 		if (CmdFailed(res2)) {
-			if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF;
+			res.SetGlobalErrorMessage();
 			goto show_error;
 		}
 	}
@@ -563,11 +563,11 @@
 	SubtractMoneyFromPlayer(res2);
 
 	if (IsLocalPlayer() && _game_mode != GM_EDITOR) {
-		if (res2 != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2);
+		if (res2.GetCost() != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2.GetCost());
 		if (_additional_cash_required) {
 			SetDParam(0, _additional_cash_required);
 			ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, error_part1, x, y);
-			if (res2 == 0) goto callb_err;
+			if (res2.GetCost() == 0) goto callb_err;
 		}
 	}
 
@@ -590,3 +590,47 @@
 	_cmd_text = NULL;
 	return false;
 }
+
+
+CommandCost CommandCost::AddCost(CommandCost ret)
+{
+	this->cost += ret.cost;
+	if (this->success && !ret.success) {
+		this->message = ret.message;
+		this->success = false;
+	}
+	return *this;
+}
+
+CommandCost CommandCost::AddCost(int32 cost)
+{
+	this->cost += cost;
+	return *this;
+}
+
+CommandCost CommandCost::MultiplyCost(int factor)
+{
+	this->cost *= factor;
+	return *this;
+}
+
+int32 CommandCost::GetCost() const
+{
+	return this->cost;
+}
+
+void CommandCost::SetGlobalErrorMessage() const
+{
+	extern StringID _error_message;
+	if (this->message != INVALID_STRING_ID) _error_message = this->message;
+}
+
+bool CommandCost::Succeeded() const
+{
+	return this->success;
+}
+
+bool CommandCost::Failed() const
+{
+	return !this->success;
+}
--- a/src/command.h	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/command.h	Mon Jun 18 19:53:50 2007 +0000
@@ -164,8 +164,6 @@
 	DC_AI_BUILDING     = 0x20, ///< special building rules for AI
 	DC_NO_TOWN_RATING  = 0x40, ///< town rating does not disallow you from building
 	DC_FORCETEST       = 0x80, ///< force test too.
-
-	CMD_ERROR = ((int32)0x80000000),
 };
 
 #define CMD_MSG(x) ((x) << 16)
@@ -191,21 +189,12 @@
 	byte flags;
 };
 
-//#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0)
-#define return_cmd_error(errcode) do { return CMD_ERROR | (errcode); } while (0)
+static inline bool CmdFailed(CommandCost cost) { return cost.Failed(); }
+static inline bool CmdSucceeded(CommandCost cost) { return cost.Succeeded(); }
 
-/**
- * Check the return value of a DoCommand*() function
- * @param res the resulting value from the command to be checked
- * @return Return true if the command failed, false otherwise
- */
-static inline bool CmdFailed(CommandCost res)
-{
-	/* lower 16bits are the StringID of the possible error */
-	return res <= (CMD_ERROR | INVALID_STRING_ID);
-}
+static const CommandCost CMD_ERROR = CommandCost((StringID)INVALID_STRING_ID);
 
-static inline bool CmdSucceeded(CommandCost res) { return !CmdFailed(res); }
+#define return_cmd_error(errcode) do { return CommandCost((StringID)(errcode)); } while (0)
 
 /* command.cpp */
 typedef void CommandCallback(bool success, TileIndex tile, uint32 p1, uint32 p2);
--- a/src/economy.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/economy.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -710,7 +710,7 @@
 		_current_player = p->index;
 		SET_EXPENSES_TYPE(EXPENSES_LOAN_INT);
 
-		SubtractMoneyFromPlayer(BIGMULUS(p->current_loan, interest, 16));
+		SubtractMoneyFromPlayer(CommandCost(BIGMULUS(p->current_loan, interest, 16)));
 
 		SET_EXPENSES_TYPE(EXPENSES_OTHER);
 		SubtractMoneyFromPlayer(_price.station_value >> 2);
@@ -1823,12 +1823,12 @@
 	if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
 
 	/* Those lines are here for network-protection (clients can be slow) */
-	if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0) return 0;
+	if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0) return cost;
 
 	/* We can not buy out a real player (temporarily). TODO: well, enable it obviously */
-	if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return 0;
+	if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return cost;
 
-	cost = CalculateCompanyValue(p) >> 2;
+	cost.AddCost(CalculateCompanyValue(p) >> 2);
 	if (flags & DC_EXEC) {
 		PlayerByte* b = p->share_owners;
 		int i;
@@ -1866,7 +1866,7 @@
 	p = GetPlayer((PlayerID)p1);
 
 	/* Those lines are here for network-protection (clients can be slow) */
-	if (GetAmountOwnedBy(p, _current_player) == 0) return 0;
+	if (GetAmountOwnedBy(p, _current_player) == 0) return CommandCost();
 
 	/* adjust it a little to make it less profitable to sell and buy */
 	cost = CalculateCompanyValue(p) >> 2;
@@ -1878,7 +1878,7 @@
 		*b = PLAYER_SPECTATOR;
 		InvalidateWindow(WC_COMPANY, p1);
 	}
-	return cost;
+	return CommandCost((int32)cost);
 }
 
 /** Buy up another company.
@@ -1909,7 +1909,7 @@
 	if (flags & DC_EXEC) {
 		DoAcquireCompany(p);
 	}
-	return p->bankrupt_value;
+	return CommandCost(p->bankrupt_value);
 }
 
 /** Prices */
--- a/src/engine.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/engine.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -276,7 +276,7 @@
 
 	if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player);
 
-	return 0;
+	return CommandCost();
 }
 
 /* Determine if an engine type is a wagon (and not a loco) */
@@ -393,7 +393,7 @@
 		DeleteName(str);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -541,7 +541,7 @@
 	er = GetEngineReplacement(*erl, old_engine, group);
 	if (er != NULL) {
 		if (flags & DC_EXEC) er->to = new_engine;
-		return 0;
+		return CommandCost();
 	}
 
 	er = AllocateEngineRenew();
@@ -557,7 +557,7 @@
 		*erl = (EngineRenewList)er;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags)
@@ -578,7 +578,7 @@
 				}
 				DeleteEngineRenew(er);
 			}
-			return 0;
+			return CommandCost();
 		}
 		prev = er;
 		er = er->next;
--- a/src/group_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/group_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -110,7 +110,7 @@
 		InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -156,7 +156,7 @@
 		InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -187,7 +187,7 @@
 		InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -235,7 +235,7 @@
 		InvalidateWindowData(GetWCForVT(v->type), (v->type << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /**
@@ -271,7 +271,7 @@
 		InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -307,7 +307,7 @@
 		InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -332,7 +332,7 @@
 		InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /**
--- a/src/industry_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/industry_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -354,7 +354,7 @@
 	}
 
 	if (flags & DC_EXEC) DeleteIndustry(i);
-	return 0;
+	return CommandCost();
 }
 
 static void TransportIndustryGoods(TileIndex tile)
@@ -1505,7 +1505,7 @@
 
 	if (CreateNewIndustryHelper(tile, p1, flags, indspec, it) == NULL) return CMD_ERROR;
 
-	return (_price.build_industry >> 8) * indspec->cost_multiplier;
+	return CommandCost((_price.build_industry >> 8) * indspec->cost_multiplier);
 }
 
 
--- a/src/landscape.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/landscape.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -401,20 +401,19 @@
 	if (ex < sx) Swap(ex, sx);
 	if (ey < sy) Swap(ey, sy);
 
-	money = GetAvailableMoneyForCommand();
-	cost = 0;
+	money.AddCost(GetAvailableMoneyForCommand());
 
 	for (x = sx; x <= ex; ++x) {
 		for (y = sy; y <= ey; ++y) {
 			ret = DoCommand(TileXY(x, y), 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) continue;
-			cost += ret;
 			success = true;
 
 			if (flags & DC_EXEC) {
-				if (ret > 0 && (money -= ret) < 0) {
-					_additional_cash_required = ret;
-					return cost - ret;
+				money.AddCost(-ret.GetCost());
+				if (ret.GetCost() > 0 && money.GetCost() < 0) {
+					_additional_cash_required = ret.GetCost();
+					return cost;
 				}
 				DoCommand(TileXY(x, y), 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
@@ -426,6 +425,7 @@
 					);
 				}
 			}
+			cost.AddCost(ret);
 		}
 	}
 
--- a/src/misc_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/misc_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -34,7 +34,7 @@
 		GetPlayer(_current_player)->face = pf;
 		MarkWholeScreenDirty();
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Change the player's company-colour
@@ -114,7 +114,7 @@
 		}
 		MarkWholeScreenDirty();
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Increase the loan of your company.
@@ -151,7 +151,7 @@
 		InvalidatePlayerWindows(p);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Decrease the loan of your company.
@@ -190,7 +190,7 @@
 		UpdatePlayerMoney32(p);
 		InvalidatePlayerWindows(p);
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Change the name of the company.
@@ -218,7 +218,7 @@
 		DeleteName(str);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Change the name of the president.
@@ -254,7 +254,7 @@
 		DeleteName(str);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Pause/Unpause the game (server-only).
@@ -274,7 +274,7 @@
 		InvalidateWindow(WC_STATUS_BAR, 0);
 		InvalidateWindow(WC_MAIN_TOOLBAR, 0);
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Change the financial flow of your company.
@@ -291,7 +291,7 @@
 	if (_networking) return CMD_ERROR;
 #endif
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-	return -(int32)p1;
+	return CommandCost(-(int32)p1);
 }
 
 /** Transfer funds (money) from one player to another.
@@ -306,19 +306,19 @@
 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	const Player *p = GetPlayer(_current_player);
-	CommandCost amount = min((int32)p1, 20000000);
+	CommandCost amount(min((int32)p1, 20000000));
 
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
 	/* You can only transfer funds that is in excess of your loan */
-	if (p->money64 - p->current_loan < amount || amount <= 0) return CMD_ERROR;
+	if (p->money64 - p->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
 	if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
 		/* Add money to player */
 		PlayerID old_cp = _current_player;
 		_current_player = (PlayerID)p2;
-		SubtractMoneyFromPlayer(-amount);
+		SubtractMoneyFromPlayer(CommandCost(-amount.GetCost()));
 		_current_player = old_cp;
 	}
 
@@ -354,5 +354,5 @@
 		if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL)
 			ShowGameDifficulty();
 	}
-	return 0;
+	return CommandCost();
 }
--- a/src/misc_gui.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/misc_gui.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -90,7 +90,7 @@
 	Window *w;
 	Town *t;
 	int64 old_money;
-	int64 costclear;
+	CommandCost costclear;
 	AcceptedCargo ac;
 	TileDesc td;
 	StringID str;
@@ -123,7 +123,7 @@
 
 	str = STR_01A4_COST_TO_CLEAR_N_A;
 	if (CmdSucceeded(costclear)) {
-		SetDParam(0, costclear);
+		SetDParam(0, costclear.GetCost());
 		str = STR_01A5_COST_TO_CLEAR;
 	}
 	GetString(_landinfo_data[2], str, lastof(_landinfo_data[2]));
--- a/src/openttd.h	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/openttd.h	Mon Jun 18 19:53:50 2007 +0000
@@ -52,6 +52,8 @@
 typedef uint16 EngineID;
 typedef uint16 UnitID;
 typedef uint16 StringID;
+#define INVALID_STRING_ID 0xFFFF
+
 typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp)
 
 /* IDs used in Pools */
@@ -67,7 +69,6 @@
 typedef uint16 GroupID;
 typedef uint16 EngineRenewID;
 typedef uint16 DestinationID;
-typedef int32 CommandCost;
 
 /* DestinationID must be at least as large as every these below, because it can
  * be any of them
@@ -359,10 +360,84 @@
 	byte width_1, width_2;
 };
 
+/**
+ * Common return value for all commands. Wraps the cost and
+ * a possible error message/state together.
+ */
+class CommandCost {
+	int32 cost;       ///< The cost of this action
+	StringID message; ///< Warning message for when success is unset
+	bool success;     ///< Whether the comment went fine up to this moment
+
+public:
+	/**
+	 * Creates a command cost return with no cost and no error
+	 */
+	CommandCost() : cost(0), message(INVALID_STRING_ID), success(true) {}
+
+	/**
+	 * Creates a command return value the is failed with the given message
+	 */
+	CommandCost(StringID msg) : cost(0), message(msg), success(false) {}
+
+	/**
+	 * Creates a command return value with the given start cost
+	 * @param cst the initial cost of this command
+	 */
+	CommandCost(int32 cst) : cost(cst), message(INVALID_STRING_ID), success(true) {}
+	/** "Hack" to make everything compile nicely, not needed when cost is int64 */
+	CommandCost(uint cst) : cost(cst), message(INVALID_STRING_ID), success(true) {}
+
+	/**
+	 * Adds the cost of the given command return value to this cost.
+	 * Also takes a possible error message when it is set.
+	 * @param ret the command to add the cost of.
+	 * @return this class.
+	 */
+	CommandCost AddCost(CommandCost ret);
+
+	/**
+	 * Adds the given cost to the cost of the command.
+	 * @param cost the cost to add
+	 * @return this class.
+	 */
+	CommandCost AddCost(int32 cost);
+
+	/**
+	 * Multiplies the cost of the command by the given factor.
+	 * @param cost factor to multiply the costs with
+	 * @return this class
+	 */
+	CommandCost MultiplyCost(int factor);
+
+	/**
+	 * The costs as made up to this moment
+	 * @return the costs
+	 */
+	int32 GetCost() const;
+
+	/**
+	 * Sets the global error message *if* this class has one.
+	 */
+	void SetGlobalErrorMessage() const;
+
+	/**
+	 * Did this command succeed?
+	 * @return true if and only if it succeeded
+	 */
+	bool Succeeded() const;
+
+	/**
+	 * Did this command fail?
+	 * @return true if and only if it failed
+	 */
+	bool Failed() const;
+};
+
 
 typedef void DrawTileProc(TileInfo *ti);
 typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y);
-typedef int32 ClearTileProc(TileIndex tile, byte flags);
+typedef CommandCost ClearTileProc(TileIndex tile, byte flags);
 typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res);
 typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
 /**
@@ -589,8 +664,6 @@
 
 VARDEF byte _savegame_sort_order;
 
-#define INVALID_STRING_ID 0xFFFF
-
 enum {
 	MAX_SCREEN_WIDTH  = 2048,
 	MAX_SCREEN_HEIGHT = 1200,
--- a/src/order_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/order_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -441,7 +441,7 @@
 		RebuildVehicleLists();
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Declone an order-list
@@ -455,7 +455,7 @@
 		InvalidateVehicleOrder(dst);
 		RebuildVehicleLists();
 	}
-	return 0;
+	return CommandCost();
 }
 
 /**
@@ -554,7 +554,7 @@
 		RebuildVehicleLists();
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Goto order of order-list.
@@ -595,7 +595,7 @@
 	if (v->type == VEH_AIRCRAFT) InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 	if (v->type == VEH_SHIP) InvalidateWindowClasses(WC_SHIPS_LIST);
 
-	return 0;
+	return CommandCost();
 }
 
 /**
@@ -681,7 +681,7 @@
 		RebuildVehicleLists();
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Modify an order in the orderlist of a vehicle.
@@ -763,7 +763,7 @@
 		}
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Clone/share/copy an order-list of an other vehicle.
@@ -896,7 +896,7 @@
 		default: return CMD_ERROR;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Add/remove refit orders from an order
@@ -945,7 +945,7 @@
 		}
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /**
@@ -1058,7 +1058,7 @@
 		v->service_interval = serv_int;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
--- a/src/players.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/players.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -175,10 +175,10 @@
 
 bool CheckPlayerHasMoney(CommandCost cost)
 {
-	if (cost > 0) {
+	if (cost.GetCost() > 0) {
 		PlayerID pid = _current_player;
-		if (IsValidPlayer(pid) && cost > GetPlayer(pid)->player_money) {
-			SetDParam(0, cost);
+		if (IsValidPlayer(pid) && cost.GetCost() > GetPlayer(pid)->player_money) {
+			SetDParam(0, cost.GetCost());
 			_error_message = STR_0003_NOT_ENOUGH_CASH_REQUIRES;
 			return false;
 		}
@@ -188,23 +188,23 @@
 
 static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost)
 {
-	p->money64 -= cost;
+	p->money64 -= cost.GetCost();
 	UpdatePlayerMoney32(p);
 
-	p->yearly_expenses[0][_yearly_expenses_type] += cost;
+	p->yearly_expenses[0][_yearly_expenses_type] += cost.GetCost();
 
 	if (HASBIT(1 << EXPENSES_TRAIN_INC    |
 	           1 << EXPENSES_ROADVEH_INC  |
 	           1 << EXPENSES_AIRCRAFT_INC |
 	           1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
-		p->cur_economy.income -= cost;
+		p->cur_economy.income -= cost.GetCost();
 	} else if (HASBIT(1 << EXPENSES_TRAIN_RUN    |
 	                  1 << EXPENSES_ROADVEH_RUN  |
 	                  1 << EXPENSES_AIRCRAFT_RUN |
 	                  1 << EXPENSES_SHIP_RUN     |
 	                  1 << EXPENSES_PROPERTY     |
 	                  1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) {
-		p->cur_economy.expenses -= cost;
+		p->cur_economy.expenses -= cost.GetCost();
 	}
 
 	InvalidatePlayerWindows(p);
@@ -217,15 +217,16 @@
 	if (IsValidPlayer(pid)) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost);
 }
 
-void SubtractMoneyFromPlayerFract(PlayerID player, CommandCost cost)
+void SubtractMoneyFromPlayerFract(PlayerID player, CommandCost cst)
 {
 	Player *p = GetPlayer(player);
 	byte m = p->player_money_fraction;
+	int32 cost = cst.GetCost();
 
 	p->player_money_fraction = m - (byte)cost;
 	cost >>= 8;
 	if (p->player_money_fraction > m) cost++;
-	if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost);
+	if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cost));
 }
 
 /** the player_money field is kept as it is, but money64 contains the actual amount of money. */
@@ -782,7 +783,7 @@
 		break;
 
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Control the players: add, delete, etc.
@@ -827,9 +828,9 @@
 		if (!_networking) return CMD_ERROR;
 
 		/* Has the network client a correct ClientID? */
-		if (!(flags & DC_EXEC)) return 0;
+		if (!(flags & DC_EXEC)) return CommandCost();
 #ifdef ENABLE_NETWORK
-		if (cid >= MAX_CLIENT_INFO) return 0;
+		if (cid >= MAX_CLIENT_INFO) return CommandCost();
 #endif /* ENABLE_NETWORK */
 
 		/* Delete multiplayer progress bar */
@@ -903,7 +904,7 @@
 	} break;
 
 	case 1: /* Make a new AI player */
-		if (!(flags & DC_EXEC)) return 0;
+		if (!(flags & DC_EXEC)) return CommandCost();
 
 		DoStartupNewPlayer(true);
 		break;
@@ -913,7 +914,7 @@
 
 		if (!IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
 
-		if (!(flags & DC_EXEC)) return 0;
+		if (!(flags & DC_EXEC)) return CommandCost();
 
 		p = GetPlayer((PlayerID)p2);
 
@@ -951,7 +952,7 @@
 	default: return CMD_ERROR;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 static const StringID _endgame_perf_titles[] = {
--- a/src/rail_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/rail_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -207,7 +207,7 @@
 
 		/* no special foundation */
 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) {
-			return 0;
+			return CommandCost();
 		} else if (!_patches.build_on_slopes || _is_old_ai_player) {
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 		}
@@ -216,7 +216,7 @@
 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
 					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
 				)) { // partly up
-			return (existing != 0) ? 0 : _price.terraform;
+			return CommandCost((existing != 0) ? 0 : _price.terraform);
 		}
 	}
 	return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
@@ -237,7 +237,7 @@
 	RailType railtype;
 	Track track;
 	TrackBits trackbit;
-	CommandCost cost = 0;
+	CommandCost cost;
 	CommandCost ret;
 
 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@@ -263,14 +263,14 @@
 
 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			/* If the rail types don't match, try to convert only if engines of
 			 * the present rail type are powered on the new rail type. */
 			if (GetRailType(tile) != railtype && HasPowerOnRail(GetRailType(tile), railtype)) {
 				ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
 				if (CmdFailed(ret)) return ret;
-				cost += ret;
+				cost.AddCost(ret);
 			}
 
 			if (flags & DC_EXEC) {
@@ -330,11 +330,11 @@
 		default:
 			ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype);
 			break;
@@ -346,7 +346,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return cost + _price.build_rail;
+	return cost.AddCost(_price.build_rail);
 }
 
 /** Remove a single piece of track
@@ -359,7 +359,7 @@
 {
 	Track track = (Track)p2;
 	TrackBits trackbit;
-	CommandCost cost = _price.remove_rail;
+	CommandCost cost(_price.remove_rail);
 	bool crossing = false;
 
 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@@ -397,7 +397,7 @@
 
 			/* Charge extra to remove signals on the track, if they are there */
 			if (HasSignalOnTrack(tile, track))
-				cost += DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS);
+				cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
 
 			if (flags & DC_EXEC) {
 				present ^= trackbit;
@@ -492,7 +492,7 @@
 			return CMD_ERROR;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Build a stretch of railroad tracks.
@@ -506,7 +506,7 @@
  */
 static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost ret, total_cost = 0;
+	CommandCost ret, total_cost;
 	Track track = (Track)GB(p2, 4, 3);
 	Trackdir trackdir;
 	byte mode = HASBIT(p2, 7);
@@ -531,7 +531,7 @@
 			if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) break;
 			_error_message = INVALID_STRING_ID;
 		} else {
-			total_cost += ret;
+			total_cost.AddCost(ret);
 		}
 
 		if (tile == end_tile) break;
@@ -542,7 +542,7 @@
 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
 	}
 
-	return (total_cost == 0) ? CMD_ERROR : total_cost;
+	return (total_cost.GetCost() == 0) ? CMD_ERROR : total_cost;
 }
 
 /** Build rail on a stretch of track.
@@ -589,7 +589,7 @@
 CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Depot *d;
-	CommandCost cost, ret;
+	CommandCost cost;
 	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@@ -618,9 +618,8 @@
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
-	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
-	if (CmdFailed(ret)) return CMD_ERROR;
-	cost = ret;
+	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+	if (CmdFailed(cost)) return CMD_ERROR;
 
 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
@@ -638,7 +637,7 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return cost + _price.build_train_depot;
+	return cost.AddCost(_price.build_train_depot);
 }
 
 /** Build signals, alternate between double/single, signal/semaphore,
@@ -687,14 +686,14 @@
 
 	if (!HasSignalOnTrack(tile, track)) {
 		/* build new signals */
-		cost = _price.build_signals;
+		cost = CommandCost(_price.build_signals);
 	} else {
 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
 			/* convert signals <-> semaphores */
-			cost = _price.build_signals + _price.remove_signals;
+			cost = CommandCost(_price.build_signals + _price.remove_signals);
 		} else {
 			/* it is free to change orientation/pre-exit-combo signals */
-			cost = 0;
+			cost = CommandCost();
 		}
 	}
 
@@ -800,7 +799,7 @@
 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
 	 *              and convert all others to semaphore/signal
 	 * remove     - 1 remove signals, 0 build signals */
-	signal_ctr = total_cost = 0;
+	signal_ctr = 0;
 	for (;;) {
 		/* only build/remove signals with the specified density */
 		if (signal_ctr % signal_density == 0) {
@@ -812,7 +811,7 @@
 			/* Be user-friendly and try placing signals as much as possible */
 			if (CmdSucceeded(ret)) {
 				error = false;
-				total_cost += ret;
+				total_cost.AddCost(ret);
 			}
 		}
 
@@ -888,7 +887,7 @@
 		MarkTileDirtyByTile(tile);
 	}
 
-	return _price.remove_signals;
+	return CommandCost(_price.remove_signals);
 }
 
 /** Remove signals on a stretch of track.
@@ -958,7 +957,7 @@
 		}
 	}
 
-	return _price.build_rail / 2;
+	return CommandCost(_price.build_rail / 2);
 }
 
 extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
@@ -994,8 +993,6 @@
 	if (ey < sy) Swap(ey, sy);
 
 	money = GetAvailableMoneyForCommand();
-	cost = 0;
-	ret = 0;
 
 	for (x = sx; x <= ex; ++x) {
 		for (y = sy; y <= ey; ++y) {
@@ -1012,20 +1009,20 @@
 
 			ret = proc(tile, (RailType)p2, false);
 			if (CmdFailed(ret)) continue;
-			cost += ret;
 
 			if (flags & DC_EXEC) {
-				money -= ret;
+				money -= ret.GetCost();
 				if (money < 0) {
-					_additional_cash_required = ret;
-					return cost - ret;
+					_additional_cash_required = ret.GetCost();
+					return cost;
 				}
 				proc(tile, (RailType)p2, true);
 			}
+			cost.AddCost(ret);
 		}
 	}
 
-	return (cost == 0) ? ret : cost;
+	return (cost.GetCost() == 0) ? ret : cost;
 }
 
 static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
@@ -1044,7 +1041,7 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return _price.remove_train_depot;
+	return CommandCost(_price.remove_train_depot);
 }
 
 static CommandCost ClearTile_Track(TileIndex tile, byte flags)
@@ -1063,8 +1060,6 @@
 		}
 	}
 
-	cost = 0;
-
 	switch (GetRailTileType(tile)) {
 		case RAIL_TILE_SIGNALS:
 		case RAIL_TILE_NORMAL: {
@@ -1073,7 +1068,7 @@
 				Track track = RemoveFirstTrack(&tracks);
 				ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
 				if (CmdFailed(ret)) return CMD_ERROR;
-				cost += ret;
+				cost.AddCost(ret);
 			}
 			return cost;
 		}
--- a/src/road_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/road_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -170,7 +170,7 @@
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 			TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
 			/* Pay for *every* tile of the bridge or tunnel */
-			cost = (DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road;
+			cost.AddCost((DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road);
 			if (flags & DC_EXEC) {
 				SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
 				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
@@ -185,13 +185,13 @@
 				}
 			}
 		} else {
-			cost = _price.remove_road;
+			cost.AddCost(_price.remove_road);
 			if (flags & DC_EXEC) {
 				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 				MarkTileDirtyByTile(tile);
 			}
 		}
-		return cost;
+		return CommandCost(cost);
 	}
 
 	switch (GetRoadTileType(tile)) {
@@ -232,7 +232,7 @@
 					MarkTileDirtyByTile(tile);
 				}
 			}
-			return CountRoadBits(c) * _price.remove_road;
+			return CommandCost(CountRoadBits(c) * _price.remove_road);
 		}
 
 		case ROAD_TILE_CROSSING: {
@@ -258,7 +258,7 @@
 				MarkTileDirtyByTile(tile);
 				YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
 			}
-			return _price.remove_road * 2;
+			return CommandCost(_price.remove_road * 2);
 		}
 
 		default:
@@ -320,12 +320,12 @@
 	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
 		/* force that all bits are set when we have slopes */
 		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
-		return 0; // no extra cost
+		return CommandCost(); // no extra cost
 	}
 
 	/* foundation is used. Whole tile is leveled up */
 	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
-		return existing != 0 ? 0 : _price.terraform;
+		return CommandCost(existing != 0 ? 0 : _price.terraform);
 	}
 
 	/* partly leveled up tile, only if there's no road on that tile */
@@ -348,7 +348,7 @@
  */
 CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost = 0;
+	CommandCost cost;
 	CommandCost ret;
 	RoadBits existing = ROAD_NONE;
 	RoadBits all_bits = ROAD_NONE;
@@ -396,7 +396,7 @@
 								SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
 								MarkTileDirtyByTile(tile);
 							}
-							return 0;
+							return CommandCost();
 						}
 						return_cmd_error(STR_1007_ALREADY_BUILT);
 					}
@@ -451,7 +451,7 @@
 				MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
 				MarkTileDirtyByTile(tile);
 			}
-			return _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4);
+			return CommandCost(_price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
 		}
 
 		case MP_STATION:
@@ -473,7 +473,7 @@
 do_clear:;
 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 	}
 
 	if (all_bits != pieces) {
@@ -481,10 +481,10 @@
 		ret = CheckRoadSlope(tileh, &pieces, all_bits | existing);
 		/* Return an error if we need to build a foundation (ret != 0) but the
 		 * current patch-setting is turned off (or stupid AI@work) */
-		if (CmdFailed(ret) || (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) {
+		if (CmdFailed(ret) || (ret.GetCost() != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) {
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 		}
-		cost += ret;
+		cost.AddCost(ret);
 	}
 
 	if (IsTileType(tile, MP_STREET)) {
@@ -492,10 +492,10 @@
 		pieces &= ComplementRoadBits(existing);
 	}
 
-	cost += CountRoadBits(pieces) * _price.build_road;
+	cost.AddCost(CountRoadBits(pieces) * _price.build_road);
 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 		/* Pay for *every* tile of the bridge or tunnel */
-		cost *= DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile);
+		cost.MultiplyCost(DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile));
 	}
 
 	if (flags & DC_EXEC) {
@@ -572,7 +572,7 @@
 		YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile)));
 	}
 
-	return _price.build_rail / 2;
+	return CommandCost(_price.build_rail / 2);
 }
 
 
@@ -623,7 +623,6 @@
 	/* No disallowed direction bits have to be toggled */
 	if (!HASBIT(p2, 5)) drd = DRD_NONE;
 
-	cost = 0;
 	tile = start_tile;
 	/* Start tile is the small number. */
 	for (;;) {
@@ -641,11 +640,11 @@
 			/* Only pay for the upgrade on one side of the bridge */
 			if (IsBridgeTile(tile)) {
 				if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) {
-					cost += ret;
+					cost.AddCost(ret);
 				}
 				had_bridge = true;
 			} else {
-				cost += ret;
+				cost.AddCost(ret);
 			}
 		}
 
@@ -692,7 +691,6 @@
 		p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
 	}
 
-	cost = 0;
 	tile = start_tile;
 	/* Start tile is the small number. */
 	for (;;) {
@@ -704,7 +702,7 @@
 		/* try to remove the halves. */
 		if (bits != 0) {
 			ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
-			if (CmdSucceeded(ret)) cost += ret;
+			if (CmdSucceeded(ret)) cost.AddCost(ret);
 		}
 
 		if (tile == end_tile) break;
@@ -712,7 +710,7 @@
 		tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
 	}
 
-	return (cost == 0) ? CMD_ERROR : cost;
+	return (cost.GetCost() == 0) ? CMD_ERROR : cost;
 }
 
 /** Build a road depot.
@@ -762,7 +760,7 @@
 		MakeRoadDepot(tile, _current_player, dir, rt);
 		MarkTileDirtyByTile(tile);
 	}
-	return cost + _price.build_road_depot;
+	return cost.AddCost(_price.build_road_depot);
 }
 
 static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
@@ -774,7 +772,7 @@
 
 	if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
 
-	return _price.remove_road_depot;
+	return CommandCost(_price.remove_road_depot);
 }
 
 static CommandCost ClearTile_Road(TileIndex tile, byte flags)
@@ -791,12 +789,12 @@
 			    !(flags & DC_AUTO)
 				) {
 				RoadTypes rts = GetRoadTypes(tile);
-				CommandCost ret = 0;
+				CommandCost ret;
 				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 					if (HASBIT(rts, rt)) {
 						CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
 						if (CmdFailed(tmp_ret)) return tmp_ret;
-						ret += tmp_ret;
+						ret.AddCost(tmp_ret);
 					}
 				}
 				return ret;
@@ -807,7 +805,7 @@
 
 		case ROAD_TILE_CROSSING: {
 			RoadTypes rts = GetRoadTypes(tile);
-			CommandCost ret = 0;
+			CommandCost ret;
 
 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 
@@ -817,7 +815,7 @@
 				if (HASBIT(rts, rt)) {
 					CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
 					if (CmdFailed(tmp_ret)) return tmp_ret;
-					ret += tmp_ret;
+					ret.AddCost(tmp_ret);
 				}
 			}
 
--- a/src/roadveh_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/roadveh_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -118,7 +118,7 @@
 
 static CommandCost EstimateRoadVehCost(EngineID engine_type)
 {
-	return ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5;
+	return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
 }
 
 byte GetRoadVehLength(const Vehicle *v)
@@ -219,7 +219,7 @@
 		v->cargo_subtype = 0;
 		v->cargo_cap = rvi->capacity;
 //		v->cargo_count = 0;
-		v->value = cost;
+		v->value = cost.GetCost();
 //		v->day_counter = 0;
 //		v->next_order_param = v->next_order = 0;
 //		v->load_unload_time_rem = 0;
@@ -273,7 +273,7 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
-	return cost;
+	return CommandCost(cost);
 }
 
 /** Start/Stop a road vehicle.
@@ -312,7 +312,7 @@
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 void ClearSlot(Vehicle *v)
@@ -373,7 +373,7 @@
 		DeleteVehicle(v);
 	}
 
-	return -(int32)v->value;
+	return CommandCost(-(int32)v->value);
 }
 
 struct RoadFindDepotData {
@@ -478,7 +478,7 @@
 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 			}
-			return 0;
+			return CommandCost();
 		}
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@@ -492,7 +492,7 @@
 			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		}
-		return 0;
+		return CommandCost();
 	}
 
 	dep = FindClosestRoadDepot(v);
@@ -511,7 +511,7 @@
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Turn a roadvehicle around.
@@ -548,7 +548,7 @@
 
 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -1968,10 +1968,10 @@
 
 	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
 
-	v->profit_this_year -= cost >> 8;
+	v->profit_this_year -= cost.GetCost() >> 8;
 
 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
-	SubtractMoneyFromPlayerFract(v->owner, cost);
+	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	InvalidateWindowClasses(WC_ROADVEH_LIST);
@@ -2060,7 +2060,6 @@
 	}
 	_returned_refit_capacity = capacity;
 
-	cost = 0;
 	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 		cost = GetRefitCost(v->engine_type);
 	}
--- a/src/settings.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/settings.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -1782,7 +1782,7 @@
 		InvalidateWindow(WC_GAME_OPTIONS, 0);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Top function to save the new value of an element of the Patches struct
--- a/src/settings_gui.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/settings_gui.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -261,7 +261,7 @@
 		_opt_ptr->road_side = p1;
 		InvalidateWindow(WC_GAME_OPTIONS,0);
 	}
-	return 0;
+	return CommandCost();
 }
 
 static const Widget _game_options_widgets[] = {
--- a/src/ship_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/ship_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -188,11 +188,11 @@
 
 	if (v->vehstatus & VS_STOPPED) return;
 
-	cost = GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _price.ship_running / 364;
-	v->profit_this_year -= cost >> 8;
+	cost.AddCost(GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _price.ship_running / 364);
+	v->profit_this_year -= cost.GetCost() >> 8;
 
 	SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
-	SubtractMoneyFromPlayerFract(v->owner, cost);
+	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	/* we need this for the profit */
@@ -405,7 +405,7 @@
 
 static CommandCost EstimateShipCost(EngineID engine_type)
 {
-	return GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5;
+	return CommandCost(GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5);
 }
 
 static void ShipArrivesAt(const Vehicle* v, Station* st)
@@ -857,7 +857,7 @@
 		v->cargo_type = svi->cargo_type;
 		v->cargo_subtype = 0;
 		v->cargo_cap = svi->capacity;
-		v->value = value;
+		v->value = value.GetCost();
 
 		v->last_station_visited = INVALID_STATION;
 		v->max_speed = svi->max_speed;
@@ -929,7 +929,7 @@
 		DeleteVehicle(v);
 	}
 
-	return -(int32)v->value;
+	return CommandCost(-(int32)v->value);
 }
 
 /** Start/Stop a ship.
@@ -968,7 +968,7 @@
 		InvalidateWindowClasses(WC_SHIPS_LIST);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Send a ship to the depot.
@@ -1010,7 +1010,7 @@
 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 			}
-			return 0;
+			return CommandCost();
 		}
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@@ -1024,7 +1024,7 @@
 			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		}
-		return 0;
+		return CommandCost();
 	}
 
 	dep = FindClosestShipDepot(v);
@@ -1042,7 +1042,7 @@
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -1100,7 +1100,6 @@
 	}
 	_returned_refit_capacity = capacity;
 
-	cost = 0;
 	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 		cost = GetRefitCost(v->engine_type);
 	}
--- a/src/signs.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/signs.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -147,7 +147,7 @@
 		_new_sign = si;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Rename a sign. If the new name of the sign is empty, we assume
@@ -201,7 +201,7 @@
 		}
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /**
--- a/src/station_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/station_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -618,7 +618,7 @@
 // Or an error code if it failed.
 CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station, bool check_clear = true)
 {
-	CommandCost cost = 0;
+	CommandCost cost;
 	int allowed_z = -1;
 
 	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
@@ -653,7 +653,7 @@
 					(invalid_dirs & 8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
 				return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 			}
-			cost += _price.terraform;
+			cost.AddCost(_price.terraform);
 			flat_z += TILE_HEIGHT;
 		}
 
@@ -682,7 +682,7 @@
 		} else if (check_clear) {
 			CommandCost ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 		}
 	} END_TILE_LOOP(tile_cur, w, h, tile)
 
@@ -838,7 +838,7 @@
 	//  for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
 	ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
 	if (CmdFailed(ret)) return ret;
-	CommandCost cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
+	CommandCost cost(ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
 
 	Station *st = NULL;
 	bool check_surrounding = true;
@@ -1121,7 +1121,7 @@
 	/* If we've not removed any tiles, give an error */
 	if (quantity == 0) return CMD_ERROR;
 
-	return _price.remove_rail_station * quantity;
+	return CommandCost(_price.remove_rail_station * quantity);
 }
 
 
@@ -1142,7 +1142,7 @@
 
 	assert(w != 0 && h != 0);
 
-	CommandCost cost = 0;
+	CommandCost cost;
 	/* clear all areas of the station */
 	do {
 		int w_bak = w;
@@ -1151,7 +1151,7 @@
 			if (st->TileBelongsToRailStation(tile)) {
 				if (!EnsureNoVehicle(tile))
 					return CMD_ERROR;
-				cost += _price.remove_rail_station;
+				cost.AddCost(_price.remove_rail_station);
 				if (flags & DC_EXEC) {
 					Track track = GetRailStationTrack(tile);
 					DoClearSquare(tile);
@@ -1211,7 +1211,7 @@
 		YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile));
 	}
 
-	return _price.build_rail / 2;
+	return CommandCost(_price.build_rail / 2);
 }
 
 /**
@@ -1267,7 +1267,7 @@
 
 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
 
-	CommandCost cost = 0;
+	CommandCost cost;
 
 	/* Not allowed to build over this road */
 	if (build_over_road) {
@@ -1340,7 +1340,7 @@
 		st->sign.width_1 = 0;
 	}
 
-	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
+	cost.AddCost((type) ? _price.build_truck_station : _price.build_bus_station);
 
 	if (flags & DC_EXEC) {
 		// Insert into linked list of RoadStops
@@ -1416,7 +1416,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
+	return CommandCost((is_truck) ? _price.remove_truck_station : _price.remove_bus_station);
 }
 
 /** Remove a bus or truck stop
@@ -1584,7 +1584,7 @@
 
 	CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
 	if (CmdFailed(ret)) return ret;
-	CommandCost cost = ret;
+	CommandCost cost(ret.GetCost());
 
 	Station *st = NULL;
 
@@ -1638,7 +1638,7 @@
 		}
 	}
 
-	cost += _price.build_airport * w * h;
+	cost.AddCost(_price.build_airport * w * h);
 
 	if (flags & DC_EXEC) {
 		st->airport_tile = tile;
@@ -1687,7 +1687,7 @@
 	int w = afc->size_x;
 	int h = afc->size_y;
 
-	CommandCost cost = w * h * _price.remove_airport;
+	CommandCost cost(w * h * _price.remove_airport);
 
 	Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
@@ -1769,7 +1769,7 @@
 		st_auto_delete.Release();
 	}
 
-	return _price.build_dock;
+	return CommandCost(_price.build_dock);
 }
 
 /* Checks if any ship is servicing the buoy specified. Returns yes or no */
@@ -1821,7 +1821,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return _price.remove_truck_station;
+	return CommandCost(_price.remove_truck_station);
 }
 
 static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
@@ -1935,7 +1935,7 @@
 		/* success, so don't delete the new station */
 		st_auto_delete.Release();
 	}
-	return _price.build_dock;
+	return CommandCost(_price.build_dock);
 }
 
 static CommandCost RemoveDock(Station *st, uint32 flags)
@@ -1964,7 +1964,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return _price.remove_dock;
+	return CommandCost(_price.remove_dock);
 }
 
 #include "table/station_land.h"
@@ -2516,7 +2516,7 @@
 		DeleteName(str);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
--- a/src/town_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/town_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -488,7 +488,7 @@
 	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 	if (!CanDeleteHouse(tile)) return CMD_ERROR;
 
-	cost = _price.remove_house * hs->removal_cost >> 8;
+	cost.AddCost(_price.remove_house * hs->removal_cost >> 8);
 
 	rating = hs->remove_rating_decrease;
 	_cleared_town_rating += rating;
@@ -735,7 +735,7 @@
 	TILE_ASSERT(tile);
 
 	r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
-	if (CmdFailed(r) || r >= 126 * 16) return false;
+	if (CmdFailed(r) || r.GetCost() >= 126 * 16) return false;
 	DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
 	return true;
 }
@@ -1502,7 +1502,7 @@
 		DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
 		_generating_world = false;
 	}
-	return 0;
+	return CommandCost();
 }
 
 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
@@ -1869,7 +1869,7 @@
 	} else {
 		DeleteName(str);
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Called from GUI */
@@ -2063,7 +2063,7 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
-	cost = (_price.build_industry >> 8) * _town_action_costs[p2];
+	cost.AddCost((_price.build_industry >> 8) * _town_action_costs[p2]);
 
 	if (flags & DC_EXEC) {
 		_town_action_proc[p2](t);
--- a/src/train_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/train_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -507,7 +507,7 @@
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
 	const RailVehicleInfo *rvi = RailVehInfo(engine);
-	CommandCost value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8;
+	CommandCost value((GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
 
 	uint num_vehicles = 1 + CountArticulatedParts(engine);
 
@@ -565,7 +565,7 @@
 			v->cargo_type = rvi->cargo_type;
 			v->cargo_subtype = 0;
 			v->cargo_cap = rvi->capacity;
-			v->value = value;
+			v->value = value.GetCost();
 //			v->day_counter = 0;
 
 			v->u.rail.railtype = rvi->railtype;
@@ -592,7 +592,7 @@
 		}
 	}
 
-	return value;
+	return CommandCost(value);
 }
 
 /** Move all free vehicles in the depot to the train */
@@ -613,7 +613,7 @@
 
 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
 {
-	return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5;
+	return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
 }
 
 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
@@ -712,7 +712,7 @@
 			v->cargo_subtype = 0;
 			v->cargo_cap = rvi->capacity;
 			v->max_speed = rvi->max_speed;
-			v->value = value;
+			v->value = value.GetCost();
 			v->last_station_visited = INVALID_STATION;
 			v->dest_tile = 0;
 
@@ -937,7 +937,7 @@
 	}
 
 	/* don't move the same vehicle.. */
-	if (src == dst) return 0;
+	if (src == dst) return CommandCost();
 
 	/* locate the head of the two chains */
 	Vehicle *src_head = GetFirstVehicleInChain(src);
@@ -954,7 +954,7 @@
 	if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
 
 	/* when moving all wagons, we can't have the same src_head and dst_head */
-	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
+	if (HASBIT(p2, 0) && src_head == dst_head) return CommandCost();
 
 	{
 		int max_len = _patches.mammoth_trains ? 100 : 9;
@@ -1153,7 +1153,7 @@
 		RebuildVehicleLists();
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Start/Stop a train.
@@ -1189,7 +1189,7 @@
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Sell a (single) train wagon/engine.
@@ -1235,7 +1235,7 @@
 		RebuildVehicleLists();
 	}
 
-	CommandCost cost = 0;
+	CommandCost cost;
 	switch (p2) {
 		case 0: case 2: { /* Delete given wagon */
 			bool switch_engine = false;    // update second wagon to engine?
@@ -1247,7 +1247,7 @@
 				IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
 
 			if (rear != NULL) {
-				cost -= rear->value;
+				cost.AddCost(-(int64)rear->value);
 				if (flags & DC_EXEC) {
 					UnlinkWagon(rear, first);
 					DeleteDepotHighlightOfVehicle(rear);
@@ -1302,7 +1302,7 @@
 			}
 
 			/* 3. Delete the requested wagon */
-			cost -= v->value;
+			cost.AddCost(-v->value);
 			if (flags & DC_EXEC) {
 				first = UnlinkWagon(v, first);
 				DeleteDepotHighlightOfVehicle(v);
@@ -1352,7 +1352,7 @@
 						Vehicle *rear = v->u.rail.other_multiheaded_part;
 
 						if (rear != NULL) {
-							cost -= rear->value;
+							cost.AddCost(-rear->value);
 
 							/* If this is a multiheaded vehicle with nothing
 							 * between the parts, tmp will be pointing to the
@@ -1374,7 +1374,7 @@
 					}
 				}
 
-				cost -= v->value;
+				cost.AddCost(-v->value);
 				if (flags & DC_EXEC) {
 					first = UnlinkWagon(v, first);
 					DeleteDepotHighlightOfVehicle(v);
@@ -1656,7 +1656,7 @@
 			}
 		}
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Force a train through a red signal
@@ -1675,7 +1675,7 @@
 
 	if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
 
-	return 0;
+	return CommandCost();
 }
 
 /** Refits a train to the specified cargo type.
@@ -1706,7 +1706,7 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
 
-	CommandCost cost = 0;
+	CommandCost cost;
 	uint num = 0;
 
 	do {
@@ -1755,7 +1755,7 @@
 
 			if (amount != 0) {
 				if (new_cid != v->cargo_type) {
-					cost += GetRefitCost(v->engine_type);
+					cost.AddCost(GetRefitCost(v->engine_type));
 				}
 
 				num += amount;
@@ -1897,7 +1897,7 @@
 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 			}
-			return 0;
+			return CommandCost();
 		}
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@@ -1910,7 +1910,7 @@
 			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		}
-		return 0;
+		return CommandCost();
 	}
 
 	/* check if at a standstill (not stopped only) in a depot
@@ -1934,7 +1934,7 @@
 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -3389,9 +3389,9 @@
 
 		if ((v->vehstatus & VS_STOPPED) == 0) {
 			/* running costs */
-			CommandCost cost = GetTrainRunningCost(v) / 364;
-
-			v->profit_this_year -= cost >> 8;
+			CommandCost cost(GetTrainRunningCost(v) / 364);
+
+			v->profit_this_year -= cost.GetCost() >> 8;
 
 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
 			SubtractMoneyFromPlayerFract(v->owner, cost);
--- a/src/tree_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/tree_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -235,8 +235,6 @@
 	if (ex < sx) Swap(ex, sx);
 	if (ey < sy) Swap(ey, sy);
 
-	cost = 0; // total cost
-
 	for (x = sx; x <= ex; x++) {
 		for (y = sy; y <= ey; y++) {
 			TileIndex tile = TileXY(x, y);
@@ -254,7 +252,7 @@
 						MarkTileDirtyByTile(tile);
 					}
 					/* 2x as expensive to add more trees to an existing tile */
-					cost += _price.build_trees * 2;
+					cost.AddCost(_price.build_trees * 2);
 					break;
 
 				case MP_CLEAR:
@@ -265,8 +263,8 @@
 					}
 
 					switch (GetClearGround(tile)) {
-						case CLEAR_FIELDS: cost += _price.clear_3; break;
-						case CLEAR_ROCKS:  cost += _price.clear_2; break;
+						case CLEAR_FIELDS: cost.AddCost(_price.clear_3); break;
+						case CLEAR_ROCKS:  cost.AddCost(_price.clear_2); break;
 						default: break;
 					}
 
@@ -297,7 +295,7 @@
 						if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TREE_RAINFOREST, TREE_CACTUS))
 							SetTropicZone(tile, TROPICZONE_RAINFOREST);
 					}
-					cost += _price.build_trees;
+					cost.AddCost(_price.build_trees);
 					break;
 
 				default:
@@ -307,7 +305,7 @@
 		}
 	}
 
-	if (cost == 0) {
+	if (cost.GetCost() == 0) {
 		return_cmd_error(msg);
 	} else {
 		return cost;
@@ -443,7 +441,7 @@
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
 
-	return num * _price.remove_trees;
+	return CommandCost(num * _price.remove_trees);
 }
 
 static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)
--- a/src/tunnelbridge_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -115,12 +115,12 @@
 	uint32 valid;
 
 	valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW));
-	if (HASBIT(valid, tileh)) return 0;
+	if (HASBIT(valid, tileh)) return CommandCost();
 
 	valid =
 		BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_N) | M(SLOPE_STEEP_N) |
 		(axis == AXIS_X ? M(SLOPE_E) | M(SLOPE_STEEP_E) : M(SLOPE_W) | M(SLOPE_STEEP_W));
-	if (HASBIT(valid, tileh)) return _price.terraform;
+	if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
 
 	return CMD_ERROR;
 }
@@ -130,12 +130,12 @@
 	uint32 valid;
 
 	valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE));
-	if (HASBIT(valid, tileh)) return 0;
+	if (HASBIT(valid, tileh)) return CommandCost();
 
 	valid =
 		BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_S) | M(SLOPE_STEEP_S) |
 		(axis == AXIS_X ? M(SLOPE_W) | M(SLOPE_STEEP_W) : M(SLOPE_E) | M(SLOPE_STEEP_E));
-	if (HASBIT(valid, tileh)) return _price.terraform;
+	if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
 
 	return CMD_ERROR;
 }
@@ -301,7 +301,7 @@
 			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
 		}
 
-		cost = (bridge_len + 1) * _price.clear_bridge; // The cost of clearing the current bridge.
+		cost.AddCost((bridge_len + 1) * _price.clear_bridge); // The cost of clearing the current bridge.
 		replace_bridge = true;
 		replaced_bridge_type = GetBridgeType(tile_start);
 
@@ -316,20 +316,20 @@
 		cost = ret;
 
 		terraformcost = CheckBridgeSlopeNorth(direction, tileh_start);
-		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+		if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
-		cost += terraformcost;
+		cost.AddCost(terraformcost);
 
 		/* Try and clear the end landscape */
 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 		if (CmdFailed(ret)) return ret;
-		cost += ret;
+		cost.AddCost(ret);
 
 		/* false - end tile slope check */
 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
-		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+		if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
-		cost += terraformcost;
+		cost.AddCost(terraformcost);
 	}
 
 	if (!replace_bridge) {
@@ -412,7 +412,7 @@
 				/* try and clear the middle landscape */
 				ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 				if (CmdFailed(ret)) return ret;
-				cost += ret;
+				cost.AddCost(ret);
 				break;
 		}
 
@@ -440,7 +440,7 @@
 		if (IsValidPlayer(_current_player) && !_is_old_ai_player)
 			bridge_len = CalcBridgeLenCostFactor(bridge_len);
 
-		cost += (int64)bridge_len * _price.build_bridge * b->price >> 8;
+		cost.AddCost((int64)bridge_len * _price.build_bridge * b->price >> 8);
 	}
 
 	return cost;
@@ -489,7 +489,7 @@
 	 * for the clearing of the entrance of the tunnel. Assigning it to
 	 * cost before the loop will yield different costs depending on start-
 	 * position, because of increased-cost-by-length: 'cost += cost >> 3' */
-	cost = 0;
+
 	delta = TileOffsByDiagDir(direction);
 	end_tile = start_tile;
 	for (;;) {
@@ -502,13 +502,14 @@
 			return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY);
 		}
 
-		cost += _price.build_tunnel;
-		cost += cost >> 3; // add a multiplier for longer tunnels
-		if (cost >= 400000000) cost = 400000000;
+		cost.AddCost(_price.build_tunnel);
+		cost.AddCost(cost.GetCost() >> 3); // add a multiplier for longer tunnels
+		if (cost.GetCost() >= 400000000) cost.AddCost(400000000 - cost.GetCost());
 	}
 
 	/* Add the cost of the entrance */
-	cost += _price.build_tunnel + ret;
+	cost.AddCost(_price.build_tunnel);
+	cost.AddCost(ret);
 
 	/* if the command fails from here on we want the end tile to be highlighted */
 	_build_tunnel_endtile = end_tile;
@@ -521,7 +522,8 @@
 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 		if (CmdFailed(ret)) return ret;
 	}
-	cost += _price.build_tunnel + ret;
+	cost.AddCost(_price.build_tunnel);
+	cost.AddCost(ret);
 
 	if (flags & DC_EXEC) {
 		if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
@@ -622,7 +624,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
-	return _price.clear_tunnel * (length + 1);
+	return CommandCost(_price.clear_tunnel * (length + 1));
 }
 
 
@@ -695,7 +697,7 @@
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
 
-	return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge;
+	return CommandCost((DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge);
 }
 
 static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
@@ -749,7 +751,7 @@
 			YapfNotifyTrackLayoutChange(tile, track);
 			YapfNotifyTrackLayoutChange(endtile, track);
 		}
-		return (length + 1) * (_price.build_rail / 2);
+		return CommandCost((length + 1) * (_price.build_rail / 2));
 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
@@ -784,7 +786,7 @@
 			}
 		}
 
-		return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2);
+		return CommandCost((DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2));
 	} else {
 		return CMD_ERROR;
 	}
--- a/src/unmovable_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/unmovable_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -49,7 +49,7 @@
 	}
 
 	/* cost of relocating company is 1% of company value */
-	return CalculateCompanyValue(p) / 100;
+	return CommandCost((int32)(CalculateCompanyValue(p) / 100));
 }
 
 void UpdateCompanyHQ(Player *p, uint score)
@@ -85,16 +85,14 @@
 {
 	Player *p = GetPlayer(_current_player);
 	CommandCost cost;
-	CommandCost ret;
 
 	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
 
-	ret = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
-	if (CmdFailed(ret)) return ret;
-	cost = ret;
+	cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
+	if (CmdFailed(cost)) return cost;
 
 	if (p->location_of_house != 0) { // Moving HQ
-		cost += DestroyCompanyHQ(_current_player, flags);
+		cost.AddCost(DestroyCompanyHQ(_current_player, flags));
 	}
 
 	if (flags & DC_EXEC) {
@@ -244,7 +242,7 @@
 		DoClearSquare(tile);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac)
--- a/src/vehicle.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/vehicle.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -847,19 +847,19 @@
 */
 CommandCost GetRefitCost(EngineID engine_type)
 {
-	CommandCost base_cost = 0;
+	CommandCost base_cost;
 
 	switch (GetEngine(engine_type)->type) {
-		case VEH_SHIP: base_cost = _price.ship_base; break;
-		case VEH_ROAD: base_cost = _price.roadveh_base; break;
-		case VEH_AIRCRAFT: base_cost = _price.aircraft_base; break;
+		case VEH_SHIP: base_cost.AddCost(_price.ship_base); break;
+		case VEH_ROAD: base_cost.AddCost(_price.roadveh_base); break;
+		case VEH_AIRCRAFT: base_cost.AddCost(_price.aircraft_base); break;
 		case VEH_TRAIN:
-			base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
-							 _price.build_railwagon : _price.build_railvehicle);
+			base_cost.AddCost(2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
+							 _price.build_railwagon : _price.build_railvehicle));
 			break;
 		default: NOT_REACHED(); break;
 	}
-	return (EngInfo(engine_type)->refit_cost * base_cost) >> 10;
+	return CommandCost((EngInfo(engine_type)->refit_cost * base_cost.GetCost()) >> 10);
 }
 
 static void DoDrawVehicle(const Vehicle *v)
@@ -1726,7 +1726,7 @@
 		ret = DoCommand(tile, v->index, 0, flags, stop_command);
 
 		if (CmdSucceeded(ret)) {
-			return_value = 0;
+			return_value = CommandCost();
 			/* We know that the command is valid for at least one vehicle.
 			 * If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */
 			if (!(flags & DC_EXEC)) break;
@@ -1752,7 +1752,7 @@
 	uint16 wagon_list_length = 0;
 	uint16 wagon_count = 0;
 
-	CommandCost cost = 0;
+	CommandCost cost;
 	uint i, sell_command, total_number_vehicles;
 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
 
@@ -1781,12 +1781,12 @@
 
 		ret = DoCommand(tile, v->index, 1, flags, sell_command);
 
-		if (CmdSucceeded(ret)) cost += ret;
+		if (CmdSucceeded(ret)) cost.AddCost(ret);
 	}
 
 	free(engines);
 	free(wagons);
-	if (cost == 0) return CMD_ERROR; // no vehicles to sell
+	if (cost.GetCost() == 0) return CMD_ERROR; // no vehicles to sell
 	return cost;
 }
 
@@ -1802,7 +1802,7 @@
 	uint16 engine_list_length = 0;
 	uint16 engine_count = 0;
 	uint i, x = 0, y = 0, z = 0;
-	CommandCost cost = 0;
+	CommandCost cost;
 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
 
 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
@@ -1830,7 +1830,7 @@
 		ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false);
 
 		if (CmdSucceeded(ret)) {
-			cost += ret;
+			cost.AddCost(ret);
 			if (!(flags & DC_EXEC)) break;
 			/* There is a problem with autoreplace and newgrf
 			 * It's impossible to tell the length of a train after it's being replaced before it's actually done
@@ -1842,14 +1842,14 @@
 		}
 	}
 
-	if (cost == 0) {
+	if (cost.GetCost() == 0) {
 		cost = CMD_ERROR;
 	} else {
 		if (flags & DC_EXEC) {
 			/* Display the cost animation now that DoCommandP() can't do it for us (see previous comments) */
-			if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost);
+			if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost.GetCost());
 		}
-		cost = 0;
+		cost = CommandCost();
 	}
 
 	free(vl);
@@ -1866,7 +1866,7 @@
 {
 	Vehicle *v_front, *v;
 	Vehicle *w_front, *w, *w_rear;
-	CommandCost cost, total_cost = 0;
+	CommandCost cost, total_cost;
 	uint32 build_argument = 2;
 
 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
@@ -1914,7 +1914,7 @@
 
 		if (CmdFailed(cost)) return cost;
 
-		total_cost += cost;
+		total_cost.AddCost(cost);
 
 		if (flags & DC_EXEC) {
 			w = GetVehicle(_new_vehicle_id);
@@ -1972,7 +1972,7 @@
 
 				if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) {
 					cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v));
-					if (CmdSucceeded(cost)) total_cost += cost;
+					if (CmdSucceeded(cost)) total_cost.AddCost(cost);
 				}
 
 				if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
@@ -1986,7 +1986,7 @@
 				CargoID initial_cargo = GetEngineCargoType(v->engine_type);
 
 				if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) {
-					total_cost += GetRefitCost(v->engine_type);
+					total_cost.AddCost(GetRefitCost(v->engine_type));
 				}
 			}
 
@@ -2242,12 +2242,12 @@
 			* it will succeed at least once. With DC_EXEC we really need to send them to the depot */
 		if (CmdSucceeded(ret) && !(flags & DC_EXEC)) {
 			free((void*)sort_list);
-			return 0;
+			return CommandCost();
 		}
 	}
 
 	free((void*)sort_list);
-	return (flags & DC_EXEC) ? 0 : CMD_ERROR;
+	return (flags & DC_EXEC) ? CommandCost() : CMD_ERROR;
 }
 
 bool IsVehicleInDepot(const Vehicle *v)
@@ -2327,8 +2327,8 @@
 					SetDParam(1, v->unitnumber);
 					AddNewsItem(STR_ORDER_REFIT_FAILED, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 				}
-			} else if (v->owner == _local_player && cost != 0) {
-				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
+			} else if (v->owner == _local_player && cost.GetCost() != 0) {
+				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
 			}
 		}
 
@@ -2386,7 +2386,7 @@
 		DeleteName(str);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
@@ -2412,7 +2412,7 @@
 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 
--- a/src/vehicle_gui.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/vehicle_gui.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -346,7 +346,7 @@
 				if (CmdSucceeded(cost)) {
 					SetDParam(0, WP(w, refit_d).cargo->cargo);
 					SetDParam(1, _returned_refit_capacity);
-					SetDParam(2, cost);
+					SetDParam(2, cost.GetCost());
 					DrawString(2, w->widget[5].top + 1, STR_9840_NEW_CAPACITY_COST_OF_REFIT, 0);
 				}
 			}
--- a/src/water_cmd.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/water_cmd.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -82,9 +82,6 @@
 	ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(ret)) return CMD_ERROR;
 
-	/* pretend that we're not making land from the water even though we actually are. */
-	cost = 0;
-
 	depot = AllocateDepot();
 	if (depot == NULL) return CMD_ERROR;
 
@@ -98,7 +95,7 @@
 		MarkTileDirtyByTile(tile2);
 	}
 
-	return cost + _price.build_ship_depot;
+	return cost.AddCost(_price.build_ship_depot);
 }
 
 static CommandCost RemoveShipDepot(TileIndex tile, uint32 flags)
@@ -123,7 +120,7 @@
 		MarkTileDirtyByTile(tile2);
 	}
 
-	return _price.remove_ship_depot;
+	return CommandCost(_price.remove_ship_depot);
 }
 
 /** build a shiplift */
@@ -164,7 +161,7 @@
 		MarkTileDirtyByTile(tile + delta);
 	}
 
-	return _price.clear_water * 22 >> 3;
+	return CommandCost(_price.clear_water * 22 >> 3);
 }
 
 static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
@@ -183,7 +180,7 @@
 		DoClearSquare(tile - delta);
 	}
 
-	return _price.clear_water * 2;
+	return CommandCost(_price.clear_water * 2);
 }
 
 static void MarkTilesAroundDirty(TileIndex tile)
@@ -249,7 +246,6 @@
 	/* Outside the editor you can only drag canals, and not areas */
 	if (_game_mode != GM_EDITOR && (sx != x && sy != y)) return CMD_ERROR;
 
-	cost = 0;
 	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
 		CommandCost ret;
 
@@ -262,7 +258,7 @@
 
 		ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 		if (CmdFailed(ret)) return ret;
-		cost += ret;
+		cost.AddCost(ret);
 
 		if (flags & DC_EXEC) {
 			if (TileHeight(tile) == 0 && HASBIT(p2, 0)) {
@@ -274,10 +270,10 @@
 			MarkTilesAroundDirty(tile);
 		}
 
-		cost += _price.clear_water;
+		cost.AddCost(_price.clear_water);
 	} END_TILE_LOOP(tile, size_x, size_y, 0);
 
-	if (cost == 0) {
+	if (cost.GetCost() == 0) {
 		return_cmd_error(STR_1007_ALREADY_BUILT);
 	} else {
 		return cost;
@@ -302,7 +298,7 @@
 			if (GetTileOwner(tile) != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
-			return _price.clear_water;
+			return CommandCost(_price.clear_water);
 
 		case WATER_TILE_COAST: {
 			Slope slope = GetTileSlope(tile, NULL);
@@ -318,9 +314,9 @@
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
 			if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
-				return _price.clear_water;
+				return CommandCost(_price.clear_water);
 			} else {
-				return _price.purchase_land;
+				return CommandCost(_price.purchase_land);
 			}
 		}
 
@@ -343,7 +339,6 @@
 
 		default:
 			NOT_REACHED();
-			return 0;
 	}
 }
 
--- a/src/waypoint.cpp	Mon Jun 18 19:42:48 2007 +0000
+++ b/src/waypoint.cpp	Mon Jun 18 19:53:50 2007 +0000
@@ -272,7 +272,7 @@
 		YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
 	}
 
-	return _price.build_train_depot;
+	return CommandCost(_price.build_train_depot);
 }
 
 /**
@@ -324,7 +324,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return _price.remove_train_depot;
+	return CommandCost(_price.remove_train_depot);
 }
 
 /**
@@ -382,7 +382,7 @@
 			MarkWholeScreenDirty();
 		}
 	}
-	return 0;
+	return CommandCost();
 }
 
 /**