(svn r11793) -Codechange: pass the expense type via the CommandCost instead of a global variable. Patch by Noldo (FS#1114).
authorrubidium
Wed, 09 Jan 2008 16:55:48 +0000
changeset 8230 64f28fe2d5c8
parent 8229 00e7467ceeee
child 8231 d98af7a3fecb
(svn r11793) -Codechange: pass the expense type via the CommandCost instead of a global variable. Patch by Noldo (FS#1114).
src/ai/default/default.cpp
src/aircraft_cmd.cpp
src/autoreplace_cmd.cpp
src/clear_cmd.cpp
src/command.cpp
src/command_type.h
src/economy.cpp
src/economy_type.h
src/industry_cmd.cpp
src/landscape.cpp
src/misc_cmd.cpp
src/players.cpp
src/rail_cmd.cpp
src/road_cmd.cpp
src/roadveh_cmd.cpp
src/ship_cmd.cpp
src/station_cmd.cpp
src/terraform_cmd.cpp
src/town_cmd.cpp
src/train_cmd.cpp
src/tree_cmd.cpp
src/tunnelbridge_cmd.cpp
src/unmovable_cmd.cpp
src/variables.h
src/vehicle.cpp
src/water_cmd.cpp
src/waypoint.cpp
--- a/src/ai/default/default.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/ai/default/default.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -1616,7 +1616,7 @@
 static CommandCost AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBlockData* p, RailType railtype, byte flag)
 {
 	CommandCost ret;
-	CommandCost total_cost;
+	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 	Town *t = NULL;
 	int rating = 0;
 	int i, j, k;
@@ -2605,7 +2605,7 @@
 static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
 {
 	CommandCost ret;
-	CommandCost total_cost;
+	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 	Town *t = NULL;
 	int rating = 0;
 	int roadflag = 0;
@@ -3366,7 +3366,7 @@
 static CommandCost AiDoBuildDefaultAirportBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
 {
 	uint32 avail_airports = GetValidAirports();
-	CommandCost total_cost, ret;
+	CommandCost ret,total_cost(EXPENSES_CONSTRUCTION);
 
 	for (; p->mode == 0; p++) {
 		if (!HasBit(avail_airports, p->attr)) return CMD_ERROR;
--- a/src/aircraft_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/aircraft_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -234,7 +234,7 @@
 
 static CommandCost EstimateAircraftCost(EngineID engine, const AircraftVehicleInfo *avi)
 {
-	return CommandCost(GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5);
+	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5);
 }
 
 
@@ -282,8 +282,6 @@
 
 	if (!IsHangarTile(tile) || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	/* Prevent building aircraft types at places which can't handle them */
 	if (!CanAircraftUseStation(p1, tile)) return CMD_ERROR;
 
@@ -492,9 +490,7 @@
 
 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
-	CommandCost ret(-v->value);
+	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 
 	if (flags & DC_EXEC) {
 		// Invalidate depot
@@ -650,8 +646,6 @@
 	CargoID new_cid = GB(p2, 0, 8);
 	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
-
 	/* Check the refit capacity callback */
 	uint16 callback = CALLBACK_FAILED;
 	if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
@@ -741,11 +735,10 @@
 
 	if (v->vehstatus & VS_STOPPED) return;
 
-	CommandCost cost = CommandCost(GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364);
+	CommandCost cost = CommandCost(EXPENSES_AIRCRAFT_RUN, GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364);
 
 	v->profit_this_year -= cost.GetCost() >> 8;
 
-	SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
 	SubtractMoneyFromPlayerFract(v->owner, cost);
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
--- a/src/autoreplace_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/autoreplace_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -161,12 +161,10 @@
 	/* We give the player a loan of the same amount as the sell value.
 	 * This is needed in case he needs the income from the sale to build the new vehicle.
 	 * We take it back if building fails or when we really sell the old engine */
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 	SubtractMoneyFromPlayer(sell_value);
 
 	cost = DoCommand(old_v->tile, new_engine_type, 3, flags, GetCmdBuildVeh(old_v));
 	if (CmdFailed(cost)) {
-		SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 		/* Take back the money we just gave the player */
 		sell_value.MultiplyCost(-1);
 		SubtractMoneyFromPlayer(sell_value);
@@ -266,7 +264,6 @@
 		/* 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->player_money < (cost.GetCost() + total_cost)) {
-			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 			/* Pay back the loan */
 			sell_value.MultiplyCost(-1);
 			SubtractMoneyFromPlayer(sell_value);
@@ -276,7 +273,6 @@
 
 	/* 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);
 	sell_value.MultiplyCost(-1);
 	SubtractMoneyFromPlayer(sell_value);
 
@@ -336,7 +332,7 @@
 	v->leave_depot_instantly = false;
 
 	for (;;) {
-		cost = CommandCost();
+		cost = CommandCost(EXPENSES_NEW_VEHICLES);
 		w = v;
 		do {
 			if (w->type == VEH_TRAIN && IsRearDualheaded(w)) {
--- a/src/clear_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/clear_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -32,7 +32,7 @@
 		&_price.clear_roughland,
 		&_price.clear_roughland,
 	};
-	CommandCost price;
+	CommandCost price(EXPENSES_CONSTRUCTION);
 
 	if (!IsClearGround(tile, CLEAR_GRASS) || GetClearDensity(tile) != 0) {
 		price.AddCost(*clear_price_table[GetClearGround(tile)]);
--- a/src/command.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/command.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -441,7 +441,7 @@
 	}
 
 	/* Execute the command here. All cost-relevant functions set the expenses type
-	 * themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */
+	 * themselves to the cost object at some point */
 	res = proc(tile, flags, p1, p2);
 	if (CmdFailed(res)) {
 		res.SetGlobalErrorMessage();
@@ -622,7 +622,6 @@
 
 	/* Actually try and execute the command. If no cost-type is given
 	 * use the construction one */
-	_yearly_expenses_type = EXPENSES_CONSTRUCTION;
 	res2 = proc(tile, flags | DC_EXEC, p1, p2);
 
 	/* If notest is on, it means the result of the test can be different than
@@ -697,6 +696,11 @@
 	return this->cost;
 }
 
+ExpensesType CommandCost::GetExpensesType() const
+{
+	return this->expense_type;
+}
+
 void CommandCost::SetGlobalErrorMessage() const
 {
 	extern StringID _error_message;
--- a/src/command_type.h	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/command_type.h	Wed Jan 09 16:55:48 2008 +0000
@@ -14,6 +14,7 @@
  * a possible error message/state together.
  */
 class CommandCost {
+	ExpensesType expense_type; ///< the type of expence as shown on the finances view
 	Money 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
@@ -22,18 +23,25 @@
 	/**
 	 * Creates a command cost return with no cost and no error
 	 */
-	CommandCost() : cost(0), message(INVALID_STRING_ID), success(true) {}
+	CommandCost() : expense_type(INVALID_EXPENSES), 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) {}
+	CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false) {}
 
 	/**
-	 * Creates a command return value with the given start cost
+	 * Creates a command cost with given expense type and start cost of 0
+	 * @param ex_t the expense type
+	 */
+	CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true) {}
+
+	/**
+	 * Creates a command return value with the given start cost and expense type
+	 * @param ex_t the expense type
 	 * @param cst the initial cost of this command
 	 */
-	CommandCost(Money cst) : cost(cst), message(INVALID_STRING_ID), success(true) {}
+	CommandCost(ExpensesType ex_t, Money cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true) {}
 
 	/**
 	 * Adds the cost of the given command return value to this cost.
@@ -64,6 +72,12 @@
 	Money GetCost() const;
 
 	/**
+	 * The expense type of the cost
+	 * @return the expense type
+	 */
+	ExpensesType GetExpensesType() const;
+
+	/**
 	 * Sets the global error message *if* this class has one.
 	 */
 	void SetGlobalErrorMessage() const;
--- a/src/economy.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/economy.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -103,7 +103,6 @@
 Money CalculateCompanyValue(const Player* p)
 {
 	PlayerID owner = p->index;
-	/* Do a little nasty by using CommandCost, so we can use the "overflow" protection of CommandCost */
 	Money value = 0;
 
 	Station *st;
@@ -662,8 +661,8 @@
 
 	FOR_ALL_STATIONS(st) {
 		_current_player = st->owner;
-		SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
-		SubtractMoneyFromPlayer(_price.station_value >> 1);
+		CommandCost cost(EXPENSES_PROPERTY, _price.station_value >> 1);
+		SubtractMoneyFromPlayer(cost);
 	}
 
 	if (!HasBit(1<<0|1<<3|1<<6|1<<9, _cur_month))
@@ -763,12 +762,10 @@
 		if (!p->is_active) continue;
 
 		_current_player = p->index;
-		SET_EXPENSES_TYPE(EXPENSES_LOAN_INT);
 
-		SubtractMoneyFromPlayer(CommandCost((Money)BigMulSU(p->current_loan, interest, 16)));
+		SubtractMoneyFromPlayer(CommandCost(EXPENSES_LOAN_INT, (Money)BigMulSU(p->current_loan, interest, 16)));
 
-		SET_EXPENSES_TYPE(EXPENSES_OTHER);
-		SubtractMoneyFromPlayer(_price.station_value >> 2);
+		SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, _price.station_value >> 2));
 	}
 }
 
@@ -1516,7 +1513,7 @@
 
 	if (route_profit != 0) {
 		front_v->profit_this_year += vehicle_profit;
-		SubtractMoneyFromPlayer(-route_profit);
+		SubtractMoneyFromPlayer(CommandCost(front_v->GetExpenseType(true), -route_profit));
 
 		if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
 			SndPlayVehicleFx(SND_14_CASHTILL, front_v);
@@ -1825,9 +1822,8 @@
 	PlayerID old_player = _current_player;
 	for (i = 0; i != 4; i++) {
 		if (p->share_owners[i] != PLAYER_SPECTATOR) {
-			SET_EXPENSES_TYPE(EXPENSES_OTHER);
 			_current_player = p->share_owners[i];
-			SubtractMoneyFromPlayer(CommandCost(-value));
+			SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, -value));
 		}
 	}
 	_current_player = old_player;
@@ -1849,7 +1845,7 @@
 CommandCost CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Player *p;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_OTHER);
 
 	/* Check if buying shares is allowed (protection against modified clients) */
 	/* Cannot buy own shares */
@@ -1860,8 +1856,6 @@
 	/* Cannot buy shares of non-existent nor bankrupted company */
 	if (!p->is_active) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
 	/* Protect new companies from hostile takeovers */
 	if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
 
@@ -1911,8 +1905,6 @@
 	/* Cannot sell shares of non-existent nor bankrupted company */
 	if (!p->is_active) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
 	/* Those lines are here for network-protection (clients can be slow) */
 	if (GetAmountOwnedBy(p, _current_player) == 0) return CommandCost();
 
@@ -1926,7 +1918,7 @@
 		*b = PLAYER_SPECTATOR;
 		InvalidateWindow(WC_COMPANY, p1);
 	}
-	return CommandCost(cost);
+	return CommandCost(EXPENSES_OTHER, cost);
 }
 
 /** Buy up another company.
@@ -1949,7 +1941,6 @@
 	/* Do not allow players to take over themselves */
 	if (pid == _current_player) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 	p = GetPlayer(pid);
 
 	if (!p->is_ai) return CMD_ERROR;
@@ -1957,7 +1948,7 @@
 	if (flags & DC_EXEC) {
 		DoAcquireCompany(p);
 	}
-	return CommandCost(p->bankrupt_value);
+	return CommandCost(EXPENSES_OTHER, p->bankrupt_value);
 }
 
 /** Prices */
--- a/src/economy_type.h	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/economy_type.h	Wed Jan 09 16:55:48 2008 +0000
@@ -124,6 +124,7 @@
 	EXPENSES_SHIP_INC     = 10,
 	EXPENSES_LOAN_INT     = 11,
 	EXPENSES_OTHER        = 12,
+	INVALID_EXPENSES      = 0xFF,
 };
 
 #endif /* ECONOMY_TYPE_H */
--- a/src/industry_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/industry_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -400,7 +400,7 @@
 	}
 
 	if (flags & DC_EXEC) delete i;
-	return CommandCost(indspec->GetRemovalCost());
+	return CommandCost(EXPENSES_CONSTRUCTION, indspec->GetRemovalCost());
 }
 
 static void TransportIndustryGoods(TileIndex tile)
@@ -1590,8 +1590,6 @@
 {
 	const IndustrySpec *indspec;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
 	indspec = GetIndustrySpec(p1);
 
 	/* Check if the to-be built/founded industry is available for this climate. */
@@ -1646,7 +1644,7 @@
 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
 	}
 
-	return CommandCost(indspec->GetConstructionCost());
+	return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
 }
 
 
@@ -2263,10 +2261,10 @@
 			if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
 				/* If the callback fails, allow autoslope. */
 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
-				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
+				if ((res == 0) || (res == CALLBACK_FAILED)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 			} else {
 				/* allow autoslope */
-				return _price.terraform;
+				return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 			}
 		}
 	}
--- a/src/landscape.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/landscape.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -524,8 +524,6 @@
  */
 CommandCost CmdLandscapeClear(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	return _tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags);
 }
 
@@ -537,7 +535,8 @@
  */
 CommandCost CmdClearArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost, ret, money;
+	CommandCost ret, money;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	int ex;
 	int ey;
 	int sx, sy;
@@ -546,8 +545,6 @@
 
 	if (p1 >= MapSize()) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* make sure sx,sy are smaller than ex,ey */
 	ex = TileX(tile);
 	ey = TileY(tile);
--- a/src/misc_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/misc_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -157,7 +157,7 @@
 		InvalidatePlayerWindows(p);
 	}
 
-	return CommandCost();
+	return CommandCost(EXPENSES_OTHER);
 }
 
 /** Decrease the loan of your company.
@@ -357,8 +357,7 @@
 #ifndef _DEBUG
 	if (_networking) return CMD_ERROR;
 #endif
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-	return CommandCost(-(Money)p1);
+	return CommandCost(EXPENSES_OTHER, -(Money)p1);
 }
 
 /** Transfer funds (money) from one player to another.
@@ -375,9 +374,7 @@
 	if (!_patches.give_money) return CMD_ERROR;
 
 	const Player *p = GetPlayer(_current_player);
-	CommandCost amount(min((Money)p1, (Money)20000000LL));
-
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
+	CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
 
 	/* You can only transfer funds that is in excess of your loan */
 	if (p->player_money - p->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
@@ -387,7 +384,7 @@
 		/* Add money to player */
 		PlayerID old_cp = _current_player;
 		_current_player = (PlayerID)p2;
-		SubtractMoneyFromPlayer(CommandCost(-amount.GetCost()));
+		SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
 		_current_player = old_cp;
 	}
 
--- a/src/players.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/players.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -192,30 +192,24 @@
 
 static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost)
 {
-	CommandCost tmp(p->player_money);
-	tmp.AddCost(-cost.GetCost());
-	p->player_money = tmp.GetCost();
+	if (cost.GetCost() == 0) return;
+	assert(cost.GetExpensesType() != INVALID_EXPENSES);
 
-	tmp = CommandCost(p->yearly_expenses[0][_yearly_expenses_type]);
-	tmp.AddCost(cost);
-	p->yearly_expenses[0][_yearly_expenses_type] = tmp.GetCost();
+	p->player_money -= cost.GetCost();
+	p->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();
 
 	if (HasBit(1 << EXPENSES_TRAIN_INC    |
 	           1 << EXPENSES_ROADVEH_INC  |
 	           1 << EXPENSES_AIRCRAFT_INC |
-	           1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
-		tmp = CommandCost(p->cur_economy.income);
-		tmp.AddCost(-cost.GetCost());
-		p->cur_economy.income = tmp.GetCost();
+	           1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
+		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)) {
-		tmp = CommandCost(p->cur_economy.expenses);
-		tmp.AddCost(-cost.GetCost());
-		p->cur_economy.expenses = tmp.GetCost();
+	                  1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
+		p->cur_economy.expenses += cost.GetCost();
 	}
 
 	InvalidatePlayerWindows(p);
@@ -237,7 +231,7 @@
 	p->player_money_fraction = m - (byte)cost;
 	cost >>= 8;
 	if (p->player_money_fraction > m) cost++;
-	if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cost));
+	if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cst.GetExpensesType(), cost));
 }
 
 void GetNameOfOwner(Owner owner, TileIndex tile)
--- a/src/rail_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/rail_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -288,7 +288,7 @@
 	   ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
 	Foundation f_old = GetRailFoundation(tileh, existing);
-	return CommandCost(f_new != f_old ? _price.terraform : (Money)0);
+	return CommandCost(EXPENSES_CONSTRUCTION, f_new != f_old ? _price.terraform : (Money)0);
 }
 
 /* Validate functions for rail building */
@@ -306,7 +306,7 @@
 	RailType railtype;
 	Track track;
 	TrackBits trackbit;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
 
 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@@ -316,8 +316,6 @@
 	tileh = GetTileSlope(tile, NULL);
 	trackbit = TrackToTrackBits(track);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	switch (GetTileType(tile)) {
 		case MP_RAILWAY:
 			if (!CheckTrackCombination(tile, trackbit, flags) ||
@@ -438,14 +436,12 @@
 {
 	Track track = (Track)p2;
 	TrackBits trackbit;
-	CommandCost cost(_price.remove_rail);
+	CommandCost cost(EXPENSES_CONSTRUCTION, _price.remove_rail );
 	bool crossing = false;
 
 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
 	trackbit = TrackToTrackBits(track);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	switch (GetTileType(tile)) {
 		case MP_ROAD: {
 			if (!IsLevelCrossing(tile) ||
@@ -624,7 +620,7 @@
  */
 static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost ret, total_cost;
+	CommandCost ret, total_cost(EXPENSES_CONSTRUCTION);
 	Track track = (Track)GB(p2, 4, 3);
 	Trackdir trackdir;
 	byte mode = HasBit(p2, 7);
@@ -636,8 +632,6 @@
 	end_tile = p1;
 	trackdir = TrackToTrackdir(track);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
 
 	if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, tile);
@@ -706,11 +700,8 @@
  */
 CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
 	Slope tileh;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
 	if (!ValParamRailtype(p1)) return CMD_ERROR;
 
@@ -735,7 +726,7 @@
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
-	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+	CommandCost 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);
@@ -806,21 +797,19 @@
 	/* you can not convert a signal if no signal is on track */
 	if (convert_signal && !HasSignalOnTrack(tile, track)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!HasSignalOnTrack(tile, track)) {
 		/* build new signals */
-		cost = CommandCost(_price.build_signals);
+		cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals);
 	} else {
 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
 			/* convert signals <-> semaphores */
-			cost = CommandCost(_price.build_signals + _price.remove_signals);
+			cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals + _price.remove_signals);
 
 		} else if (convert_signal) {
 			/* convert button pressed */
 			if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
 				/* convert electric <-> semaphore */
-				cost = CommandCost(_price.build_signals + _price.remove_signals);
+				cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals + _price.remove_signals);
 			} else {
 				/* it is free to change signal type: normal-pre-exit-combo */
 				cost = CommandCost();
@@ -956,7 +945,7 @@
  */
 static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost ret, total_cost;
+	CommandCost ret, total_cost(EXPENSES_CONSTRUCTION);
 	int signal_ctr;
 	byte signals;
 	bool error = true;
@@ -977,8 +966,6 @@
 
 	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* for vertical/horizontal tracks, double the given signals density
 	 * since the original amount will be too dense (shorter tracks) */
 	signal_density *= 2;
@@ -1101,8 +1088,6 @@
 	/* Only water can remove signals from anyone */
 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Do it? */
 	if (flags & DC_EXEC) {
 		SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
@@ -1120,7 +1105,7 @@
 		MarkTileDirtyByTile(tile);
 	}
 
-	return CommandCost(_price.remove_signals);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_signals);
 }
 
 /** Remove signals on a stretch of track.
@@ -1164,7 +1149,7 @@
  */
 CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 
 	if (!ValParamRailtype(p2)) return CMD_ERROR;
 	if (p1 >= MapSize()) return CMD_ERROR;
@@ -1180,8 +1165,6 @@
 	if (ex < sx) Swap(ex, sx);
 	if (ey < sy) Swap(ey, sy);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	_error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK; // by default, there is no track to convert
 
 	for (uint x = sx; x <= ex; ++x) {
@@ -1331,12 +1314,12 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return CommandCost(_price.remove_train_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);
 }
 
 static CommandCost ClearTile_Track(TileIndex tile, byte flags)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
 
 	if (flags & DC_AUTO) {
@@ -2433,7 +2416,7 @@
 		case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
 
 		/* Surface slope must not be changed */
-		default: return (((z_old != z_new) || (tileh_old != tileh_new)) ? CMD_ERROR : _price.terraform);
+		default: return (((z_old != z_new) || (tileh_old != tileh_new)) ? CMD_ERROR : CommandCost(EXPENSES_CONSTRUCTION, _price.terraform));
 	}
 
 	/* The height of the track_corner must not be changed. The rest ensures GetRailFoundation() already. */
@@ -2441,7 +2424,7 @@
 	z_new += GetSlopeZInCorner((Slope)(tileh_new & ~SLOPE_HALFTILE_MASK), track_corner);
 	if (z_old != z_new) return CMD_ERROR;
 
-	CommandCost cost = CommandCost(_price.terraform);
+	CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	/* Make the ground dirty, if surface slope has changed */
 	if (tileh_old != tileh_new) {
 		if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water);
@@ -2488,7 +2471,7 @@
 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
 
 		/* allow terraforming */
-		return (was_water ? CommandCost(_price.clear_water) : CommandCost());
+		return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price.clear_water : (Money)0);
 	} else {
 		if (_patches.build_on_slopes && AutoslopeEnabled()) {
 			switch (GetRailTileType(tile)) {
@@ -2499,7 +2482,7 @@
 				}
 
 				case RAIL_TILE_DEPOT:
-					if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return _price.terraform;
+					if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 					break;
 
 				default: NOT_REACHED();
--- a/src/road_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/road_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -114,8 +114,6 @@
 	 * false if it was a center piece. Affects town ratings drop */
 	bool edge_road;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	RoadType rt = (RoadType)GB(p1, 4, 2);
 	if (!IsValidRoadType(rt)) return CMD_ERROR;
 
@@ -156,7 +154,7 @@
 		/* If it's the last roadtype, just clear the whole tile */
 		if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
-		CommandCost cost;
+		CommandCost cost(EXPENSES_CONSTRUCTION);
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 			TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 			/* Pay for *every* tile of the bridge or tunnel */
@@ -181,7 +179,7 @@
 				MarkTileDirtyByTile(tile);
 			}
 		}
-		return CommandCost(cost);
+		return cost;
 	}
 
 	switch (GetRoadTileType(tile)) {
@@ -224,7 +222,7 @@
 					MarkTileDirtyByTile(tile);
 				}
 			}
-			return CommandCost(CountBits(c) * _price.remove_road);
+			return CommandCost(EXPENSES_CONSTRUCTION, CountBits(c) * _price.remove_road);
 		}
 
 		case ROAD_TILE_CROSSING: {
@@ -250,7 +248,7 @@
 				MarkTileDirtyByTile(tile);
 				YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
 			}
-			return CommandCost(_price.remove_road * 2);
+			return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_road * 2);
 		}
 
 		default:
@@ -346,7 +344,7 @@
 		*pieces |= MirrorRoadBits(*pieces);
 
 		if (existing == ROAD_NONE || existing == *pieces) {
-			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+			if (*pieces == ROAD_X || *pieces == ROAD_Y) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 		}
 		return CMD_ERROR;
 	}
@@ -358,7 +356,7 @@
 	if (_patches.build_on_slopes && !_is_old_ai_player &&
 			existing == ROAD_NONE && CountBits(*pieces) == 1 &&
 			(_valid_tileh_slopes_road[2][tileh] & *pieces) == ROAD_NONE) {
-		return CommandCost(_price.terraform);
+		return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 
 	/* no special foundation */
@@ -370,7 +368,7 @@
 
 	/* foundation is used. Whole tile is leveled up */
 	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == ROAD_NONE) {
-		return CommandCost(existing != ROAD_NONE ? (Money)0 : _price.terraform);
+		return CommandCost(EXPENSES_CONSTRUCTION, existing != ROAD_NONE ? (Money)0 : _price.terraform);
 	}
 
 	/* Force straight roads. */
@@ -378,7 +376,7 @@
 
 	/* partly leveled up tile, only if there's no road on that tile */
 	if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
-		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+		if (*pieces == ROAD_X || *pieces == ROAD_Y) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 	return CMD_ERROR;
 }
@@ -393,14 +391,12 @@
  */
 CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
 	RoadBits existing = ROAD_NONE;
 	RoadBits all_bits = ROAD_NONE;
 	Slope tileh;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 	 * if a non-player is building the road */
 	if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
@@ -494,7 +490,7 @@
 				MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
 				MarkTileDirtyByTile(tile);
 			}
-			return CommandCost(_price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
+			return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
 		}
 
 		case MP_STATION:
@@ -604,14 +600,12 @@
 CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	TileIndex start_tile, tile;
-	CommandCost cost, ret;
+	CommandCost ret, cost(EXPENSES_CONSTRUCTION);
 	bool had_bridge = false;
 	bool had_tunnel = false;
 	bool had_success = false;
 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (p1 >= MapSize()) return CMD_ERROR;
 
 	start_tile = p1;
@@ -691,9 +685,8 @@
 CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	TileIndex start_tile, tile;
-	CommandCost cost, ret, money;
-
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+	CommandCost ret, cost(EXPENSES_CONSTRUCTION);
+	Money money;
 
 	if (p1 >= MapSize()) return CMD_ERROR;
 
@@ -713,7 +706,7 @@
 		p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0;
 	}
 
-	money.AddCost(GetAvailableMoneyForCommand());
+	money = GetAvailableMoneyForCommand();
 	tile = start_tile;
 	/* Start tile is the small number. */
 	for (;;) {
@@ -727,8 +720,8 @@
 			ret = DoCommand(tile, rt << 4 | bits, 0, flags & ~DC_EXEC, CMD_REMOVE_ROAD);
 			if (CmdSucceeded(ret)) {
 				if (flags & DC_EXEC) {
-					money.AddCost(-ret.GetCost());
-					if (money.GetCost() < 0) {
+					money -= ret.GetCost();
+					if (money < 0) {
 						_additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
 						return cost;
 					}
@@ -761,8 +754,6 @@
 	CommandCost cost;
 	Slope tileh;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	DiagDirection dir = Extract<DiagDirection, 0>(p1);
 	RoadType rt = (RoadType)GB(p1, 2, 2);
 
@@ -808,7 +799,7 @@
 		delete GetDepotByTile(tile);
 	}
 
-	return CommandCost(_price.remove_road_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_road_depot);
 }
 
 static CommandCost ClearTile_Road(TileIndex tile, byte flags)
@@ -824,7 +815,7 @@
 			    !(flags & DC_AUTO)
 				) {
 				RoadTypes rts = GetRoadTypes(tile);
-				CommandCost ret;
+				CommandCost ret(EXPENSES_CONSTRUCTION);
 				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);
@@ -839,7 +830,7 @@
 
 		case ROAD_TILE_CROSSING: {
 			RoadTypes rts = GetRoadTypes(tile);
-			CommandCost ret;
+			CommandCost ret(EXPENSES_CONSTRUCTION);
 
 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 
@@ -1420,11 +1411,11 @@
 	if (_patches.build_on_slopes && AutoslopeEnabled()) {
 		switch (GetRoadTileType(tile)) {
 			case ROAD_TILE_CROSSING:
-				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return _price.terraform;
+				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				break;
 
 			case ROAD_TILE_DEPOT:
-				if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRoadDepotDirection(tile))) return _price.terraform;
+				if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRoadDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				break;
 
 			case ROAD_TILE_NORMAL: {
@@ -1442,7 +1433,7 @@
 						z_new += ApplyFoundationToSlope(GetRoadFoundation(tileh_new, bits), &tileh_new);
 
 						/* The surface slope must not be changed */
-						if ((z_old == z_new) && (tileh_old == tileh_new)) return _price.terraform;
+						if ((z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 					}
 				}
 				break;
--- a/src/roadveh_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/roadveh_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -125,7 +125,7 @@
 
 static CommandCost EstimateRoadVehCost(EngineID engine_type)
 {
-	return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
+	return CommandCost(EXPENSES_NEW_VEHICLES, ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
 }
 
 byte GetRoadVehLength(const Vehicle *v)
@@ -172,8 +172,6 @@
 
 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	cost = EstimateRoadVehCost(p1);
 	if (flags & DC_QUERY_COST) return cost;
 
@@ -279,7 +277,7 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
-	return CommandCost(cost);
+	return cost;
 }
 
 /** Start/Stop a road vehicle.
@@ -366,13 +364,11 @@
 
 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	if (!CheckRoadVehInDepotStopped(v)) {
 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
 	}
 
-	CommandCost ret(-v->value);
+	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 
 	if (flags & DC_EXEC) {
 		// Invalidate depot
@@ -2006,7 +2002,7 @@
 
 void OnNewDay_RoadVeh(Vehicle *v)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_ROADVEH_RUN);
 
 	if (!IsRoadVehFront(v)) return;
 
@@ -2086,12 +2082,11 @@
 		}
 	}
 
-	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
+	cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364);
 
 	v->profit_this_year -= cost.GetCost() >> 8;
 
-	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
-	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
+	SubtractMoneyFromPlayerFract(v->owner, cost);
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	InvalidateWindowClasses(WC_ROADVEH_LIST);
@@ -2124,7 +2119,7 @@
 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_ROADVEH_RUN);
 	CargoID new_cid = GB(p2, 0, 8);
 	byte new_subtype = GB(p2, 8, 8);
 	bool only_this = HasBit(p2, 16);
@@ -2141,8 +2136,6 @@
 
 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
-
 	for (; v != NULL; v = v->Next()) {
 		/* XXX: We refit all the attached wagons en-masse if they can be
 		 * refitted. This is how TTDPatch does it.  TODO: Have some nice
--- a/src/ship_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/ship_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -170,7 +170,7 @@
 
 void OnNewDay_Ship(Vehicle *v)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_SHIP_RUN);
 
 	if ((++v->day_counter & 7) == 0)
 		DecreaseVehicleValue(v);
@@ -186,8 +186,7 @@
 	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, CommandCost(cost));
+	SubtractMoneyFromPlayerFract(v->owner, cost);
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	/* we need this for the profit */
@@ -401,7 +400,7 @@
 
 static CommandCost EstimateShipCost(EngineID engine_type)
 {
-	return CommandCost(GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5);
+	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5);
 }
 
 static void ShipArrivesAt(const Vehicle* v, Station* st)
@@ -815,8 +814,6 @@
 
 	if (!IsEngineBuildable(p1, VEH_SHIP, _current_player)) return_cmd_error(STR_SHIP_NOT_AVAILABLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	value = EstimateShipCost(p1);
 	if (flags & DC_QUERY_COST) return value;
 
@@ -912,13 +909,11 @@
 
 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	if (!v->IsStoppedInDepot()) {
 		return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
 	}
 
-	CommandCost ret(-v->value);
+	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 
 	if (flags & DC_EXEC) {
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
@@ -1061,7 +1056,7 @@
 CommandCost CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_SHIP_RUN);
 	CargoID new_cid = GB(p2, 0, 8); //gets the cargo number
 	byte new_subtype = GB(p2, 8, 8);
 	uint16 capacity = CALLBACK_FAILED;
@@ -1078,8 +1073,6 @@
 	if (!ShipVehInfo(v->engine_type)->refittable) return CMD_ERROR;
 	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
-
 	/* Check the refit capacity callback */
 	if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 		/* Back up the existing cargo type */
--- a/src/station_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/station_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -706,7 +706,7 @@
  */
 CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID *station, bool check_clear = true)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	int allowed_z = -1;
 
 	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
@@ -903,8 +903,6 @@
 	int w_org, h_org;
 	CommandCost ret;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Does the authority allow this? */
 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
 	if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
@@ -936,7 +934,7 @@
 	 * 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.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
+	CommandCost cost(EXPENSES_CONSTRUCTION, ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
 
 	Station *st = NULL;
 	bool check_surrounding = true;
@@ -1176,8 +1174,6 @@
 	int size_x = ex - sx + 1;
 	int size_y = ey - sy + 1;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Do the action for every tile into the area */
 	BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) {
 		/* Make sure the specified tile is a railroad station */
@@ -1234,7 +1230,7 @@
 	/* If we've not removed any tiles, give an error */
 	if (quantity == 0) return CMD_ERROR;
 
-	return CommandCost(_price.remove_rail_station * quantity);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_rail_station * quantity);
 }
 
 
@@ -1255,7 +1251,7 @@
 
 	assert(w != 0 && h != 0);
 
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	/* clear all areas of the station */
 	do {
 		int w_bak = w;
@@ -1346,8 +1342,6 @@
 	/* Road bits in the wrong direction */
 	if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
 
 	CommandCost cost;
@@ -1506,7 +1500,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return CommandCost((is_truck) ? _price.remove_truck_station : _price.remove_bus_station);
+	return CommandCost(EXPENSES_CONSTRUCTION, (is_truck) ? _price.remove_truck_station : _price.remove_bus_station);
 }
 
 /** Remove a bus or truck stop
@@ -1645,8 +1639,6 @@
 {
 	bool airport_upgrade = true;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Check if a valid, buildable airport was chosen for construction */
 	if (p1 > lengthof(_airport_sections) || !HasBit(GetValidAirports(), p1)) return CMD_ERROR;
 
@@ -1673,9 +1665,8 @@
 	int w = afc->size_x;
 	int h = afc->size_y;
 
-	CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
-	if (CmdFailed(ret)) return ret;
-	CommandCost cost(ret.GetCost());
+	CommandCost cost = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
+	if (CmdFailed(cost)) return cost;
 
 	Station *st = NULL;
 
@@ -1780,7 +1771,7 @@
 	int w = afc->size_x;
 	int h = afc->size_y;
 
-	CommandCost cost(w * h * _price.remove_airport);
+	CommandCost cost(EXPENSES_CONSTRUCTION, w * h * _price.remove_airport);
 
 	Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
@@ -1826,8 +1817,6 @@
  */
 CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!IsWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
@@ -1864,7 +1853,7 @@
 		st_auto_delete.Detach();
 	}
 
-	return CommandCost(_price.build_dock);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
 }
 
 /**
@@ -1918,7 +1907,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return CommandCost(_price.remove_truck_station);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_truck_station);
 }
 
 static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
@@ -1940,8 +1929,6 @@
 {
 	CommandCost cost;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	DiagDirection direction;
 	switch (GetTileSlope(tile, NULL)) {
 		case SLOPE_SW: direction = DIAGDIR_NE; break;
@@ -2033,7 +2020,7 @@
 		/* success, so don't delete the new station */
 		st_auto_delete.Detach();
 	}
-	return CommandCost(_price.build_dock);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
 }
 
 static CommandCost RemoveDock(Station *st, uint32 flags)
@@ -2063,7 +2050,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return CommandCost(_price.remove_dock);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_dock);
 }
 
 #include "table/station_land.h"
@@ -2981,11 +2968,11 @@
 					DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile));
 					if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
 					if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
-					return _price.terraform;
+					return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				}
 
 				case STATION_AIRPORT:
-					return _price.terraform;
+					return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
 				case STATION_TRUCK:
 				case STATION_BUS: {
@@ -2994,7 +2981,7 @@
 					if (IsDriveThroughStopTile(tile)) {
 						if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
 					}
-					return _price.terraform;
+					return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				}
 
 				default: break;
--- a/src/terraform_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/terraform_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -148,7 +148,7 @@
  */
 static CommandCost TerraformTileHeight(TerraformerState *ts, TileIndex tile, int height)
 {
-	CommandCost total_cost = CommandCost();
+	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 
 	assert(tile < MapSize());
 
@@ -228,11 +228,9 @@
 CommandCost CmdTerraformLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	TerraformerState ts;
-	CommandCost total_cost = CommandCost();
+	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 	int direction = (p2 != 0 ? 1 : -1);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	_terraform_err_tile = 0;
 
 	ts.modheight_count = ts.tile_table_count = 0;
@@ -358,12 +356,10 @@
 	uint h, oldh, curh;
 	CommandCost money;
 	CommandCost ret;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 
 	if (p1 >= MapSize()) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* remember level height */
 	oldh = TileHeight(p1);
 
--- a/src/town_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/town_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -502,7 +502,7 @@
 static CommandCost ClearTile_Town(TileIndex tile, byte flags)
 {
 	int rating;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	Town *t;
 	HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
 
@@ -1496,8 +1496,6 @@
 	if (_game_mode != GM_EDITOR) return CMD_ERROR;
 	if (p2 > TSM_CITY) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
 	/* Check if too close to the edge of map */
 	if (DistanceFromEdge(tile) < 12)
 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
@@ -2097,7 +2095,6 @@
  */
 CommandCost CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
 	Town *t;
 
 	if (!IsValidTownID(p1) || p2 > lengthof(_town_action_proc)) return CMD_ERROR;
@@ -2106,9 +2103,7 @@
 
 	if (!HasBit(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
-	cost.AddCost((_price.build_industry >> 8) * _town_action_costs[p2]);
+	CommandCost cost(EXPENSES_OTHER, (_price.build_industry >> 8) * _town_action_costs[p2]);
 
 	if (flags & DC_EXEC) {
 		_town_action_proc[p2](t);
@@ -2364,7 +2359,7 @@
 
 		/* Here we differ from TTDP by checking TILE_NOT_SLOPED */
 		if (((hs->building_flags & TILE_NOT_SLOPED) == 0) && !IsSteepSlope(tileh_new) &&
-			(GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) return _price.terraform;
+			(GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 
 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
--- a/src/train_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/train_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -511,10 +511,8 @@
 
 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
 {
-	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(EXPENSES_NEW_VEHICLES, (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
 
 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
 
@@ -600,7 +598,7 @@
 		}
 	}
 
-	return CommandCost(value);
+	return value;
 }
 
 /** Move all free vehicles in the depot to the train */
@@ -621,7 +619,7 @@
 
 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
 {
-	return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
+	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
 }
 
 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
@@ -671,8 +669,6 @@
 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
 	}
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	const RailVehicleInfo *rvi = RailVehInfo(p1);
 
 	/* Check if depot and new engine uses the same kind of tracks */
@@ -1313,8 +1309,6 @@
 
 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	while (IsArticulatedPart(v)) v = v->Previous();
 	Vehicle *first = v->First();
 
@@ -1334,7 +1328,7 @@
 		RebuildVehicleLists();
 	}
 
-	CommandCost cost;
+	CommandCost cost(EXPENSES_NEW_VEHICLES);
 	switch (p2) {
 		case 0: case 2: { /* Delete given wagon */
 			bool switch_engine = false;    // update second wagon to engine?
@@ -1804,9 +1798,7 @@
 	/* Check cargo */
 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
-
-	CommandCost cost;
+	CommandCost cost(EXPENSES_TRAIN_RUN);
 	uint num = 0;
 
 	do {
@@ -3481,11 +3473,10 @@
 
 		if ((v->vehstatus & VS_STOPPED) == 0) {
 			/* running costs */
-			CommandCost cost(v->GetRunningCost() / 364);
+			CommandCost cost(EXPENSES_TRAIN_RUN, v->GetRunningCost() / 364);
 
 			v->profit_this_year -= cost.GetCost() >> 8;
 
-			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
 			SubtractMoneyFromPlayerFract(v->owner, cost);
 
 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
--- a/src/tree_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/tree_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -273,7 +273,7 @@
 CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	StringID msg = INVALID_STRING_ID;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_OTHER);
 	int ex;
 	int ey;
 	int sx, sy, x, y;
@@ -282,8 +282,6 @@
 	/* Check the tree type. It can be random or some valid value within the current climate */
 	if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_opt.landscape] >= _tree_count_by_landscape[_opt.landscape]) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_OTHER);
-
 	// make sure sx,sy are smaller than ex,ey
 	ex = TileX(tile);
 	ey = TileY(tile);
@@ -499,7 +497,7 @@
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
 
-	return CommandCost(num * _price.remove_trees);
+	return CommandCost(EXPENSES_CONSTRUCTION, num * _price.remove_trees);
 }
 
 static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)
--- a/src/tunnelbridge_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/tunnelbridge_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -123,7 +123,7 @@
 	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 CommandCost(_price.terraform);
+	if (HasBit(valid, tileh)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
 	return CMD_ERROR;
 }
@@ -138,7 +138,7 @@
 	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 CommandCost(_price.terraform);
+	if (HasBit(valid, tileh)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
 	return CMD_ERROR;
 }
@@ -197,13 +197,12 @@
 	TileIndexDiff delta;
 	uint bridge_len;
 	Axis direction;
-	CommandCost cost, terraformcost, ret;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
+	CommandCost terraformcost, ret;
 	bool allow_on_slopes;
 	bool replace_bridge = false;
 	uint replaced_bridge_type;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* unpack parameters */
 	bridge_type = GB(p2, 0, 8);
 
@@ -458,7 +457,7 @@
 	Slope end_tileh;
 	uint start_z;
 	uint end_z;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
 
 	_build_tunnel_endtile = 0;
@@ -578,8 +577,6 @@
 	Town *t = NULL;
 	TileIndex endtile;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
 
 	endtile = GetOtherTunnelEnd(tile);
@@ -617,7 +614,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
-	return CommandCost(_price.clear_tunnel * (DistanceManhattan(tile, endtile) + 1));
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_tunnel * (DistanceManhattan(tile, endtile) + 1));
 }
 
 
@@ -628,8 +625,6 @@
 	TileIndex endtile;
 	Town *t = NULL;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
 
 	endtile = GetOtherBridgeEnd(tile);
@@ -673,7 +668,7 @@
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
 
-	return CommandCost((DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge);
+	return CommandCost(EXPENSES_CONSTRUCTION, (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge);
 }
 
 static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
@@ -1398,7 +1393,7 @@
 			z_new += ApplyFoundationToSlope(GetBridgeFoundation(tileh_new, axis), &tileh_new);
 
 			/* Surface slope remains unchanged? */
-			if ((z_old == z_new) && (tileh_old == tileh_new)) return _price.terraform;
+			if ((z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 		}
 	}
 
--- a/src/unmovable_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/unmovable_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -38,8 +38,6 @@
 {
 	Player* p = GetPlayer(pid);
 
-	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
-
 	if (flags & DC_EXEC) {
 		TileIndex t = p->location_of_house;
 
@@ -52,7 +50,7 @@
 	}
 
 	/* cost of relocating company is 1% of company value */
-	return CommandCost(CalculateCompanyValue(p) / 100);
+	return CommandCost(EXPENSES_PROPERTY, CalculateCompanyValue(p) / 100);
 }
 
 void UpdateCompanyHQ(Player *p, uint score)
@@ -87,9 +85,7 @@
 CommandCost CmdBuildCompanyHQ(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Player *p = GetPlayer(_current_player);
-	CommandCost cost;
-
-	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
+	CommandCost cost(EXPENSES_PROPERTY);
 
 	cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
 	if (CmdFailed(cost)) return cost;
@@ -122,9 +118,7 @@
  */
 CommandCost CmdPurchaseLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
-
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 
 	if (IsOwnedLandTile(tile) && IsTileOwner(tile, _current_player)) {
 		return_cmd_error(STR_5807_YOU_ALREADY_OWN_IT);
@@ -151,8 +145,6 @@
  */
 CommandCost CmdSellLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (!IsOwnedLandTile(tile)) return CMD_ERROR;
 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) return CMD_ERROR;
 
@@ -161,7 +153,7 @@
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
 
-	return CommandCost(- _price.clear_roughland * 2);
+	return CommandCost(EXPENSES_CONSTRUCTION,- _price.clear_roughland * 2);
 }
 
 static Foundation GetFoundation_Unmovable(TileIndex tile, Slope tileh);
@@ -463,7 +455,7 @@
 	if (IsOwnedLand(tile) && CheckTileOwnership(tile)) return CommandCost();
 
 	if (AutoslopeEnabled() && (IsStatue(tile) || IsCompanyHQ(tile))) {
-		if (!IsSteepSlope(tileh_new) && (z_new + GetSlopeMaxZ(tileh_new) == GetTileMaxZ(tile))) return _price.terraform;
+		if (!IsSteepSlope(tileh_new) && (z_new + GetSlopeMaxZ(tileh_new) == GetTileMaxZ(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 
 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
--- a/src/variables.h	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/variables.h	Wed Jan 09 16:55:48 2008 +0000
@@ -89,7 +89,6 @@
 VARDEF PlayerFace _player_face; ///< for player face storage in openttd.cfg
 
 /* IN/OUT parameters to commands */
-VARDEF byte _yearly_expenses_type;
 VARDEF TileIndex _build_tunnel_endtile;
 VARDEF bool _generating_world;
 
@@ -110,8 +109,6 @@
 VARDEF char *_log_file;
 
 
-#define SET_EXPENSES_TYPE(x) _yearly_expenses_type = x;
-
 /* landscape.cpp */
 extern const byte _tileh_to_sprite[32];
 
--- a/src/vehicle.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/vehicle.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -706,19 +706,33 @@
 */
 CommandCost GetRefitCost(EngineID engine_type)
 {
-	CommandCost base_cost;
-
+	Money base_cost;
+	ExpensesType expense_type;
 	switch (GetEngine(engine_type)->type) {
-		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_SHIP:
+			base_cost = _price.ship_base;
+			expense_type = EXPENSES_SHIP_RUN;
+			break;
+
+		case VEH_ROAD:
+			base_cost = _price.roadveh_base;
+			expense_type = EXPENSES_ROADVEH_RUN;
+			break;
+
+		case VEH_AIRCRAFT:
+			base_cost = _price.aircraft_base;
+			expense_type = EXPENSES_AIRCRAFT_RUN;
+			break;
+
 		case VEH_TRAIN:
-			base_cost.AddCost(2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
-							 _price.build_railwagon : _price.build_railvehicle));
+			base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
+							 _price.build_railwagon : _price.build_railvehicle);
+			expense_type = EXPENSES_TRAIN_RUN;
 			break;
-		default: NOT_REACHED(); break;
+
+		default: NOT_REACHED();
 	}
-	return CommandCost((EngInfo(engine_type)->refit_cost * base_cost.GetCost()) >> 10);
+	return CommandCost(expense_type, (EngInfo(engine_type)->refit_cost * base_cost) >> 10);
 }
 
 static void DoDrawVehicle(const Vehicle *v)
@@ -1697,7 +1711,6 @@
 			 * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually
 			 * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money
 			 * we should never reach a condition where the player will end up with negative money from doing this */
-			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 			SubtractMoneyFromPlayer(ret);
 		}
 	}
@@ -1726,7 +1739,7 @@
 {
 	Vehicle *v_front, *v;
 	Vehicle *w_front, *w, *w_rear;
-	CommandCost cost, total_cost;
+	CommandCost cost, total_cost(EXPENSES_NEW_VEHICLES);
 	uint32 build_argument = 2;
 
 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
@@ -1880,9 +1893,6 @@
 		return CMD_ERROR;
 	}
 
-	/* Set the expense type last as refitting will make the cost go towards
-	 * running costs... */
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 	return total_cost;
 }
 
@@ -3105,7 +3115,6 @@
 	current_order.type = OT_LOADING;
 	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
 
-	SET_EXPENSES_TYPE(this->GetExpenseType(true));
 	VehiclePayment(this);
 
 	InvalidateWindow(this->GetVehicleListWindowClass(), this->owner);
--- a/src/water_cmd.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/water_cmd.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -86,9 +86,7 @@
 {
 	TileIndex tile2;
 
-	CommandCost cost, ret;
-
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+	CommandCost ret;
 
 	Axis axis = Extract<Axis, 0>(p1);
 
@@ -120,7 +118,7 @@
 		d_auto_delete.Detach();
 	}
 
-	return cost.AddCost(_price.build_ship_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_ship_depot);
 }
 
 void MakeWaterOrCanalDependingOnOwner(TileIndex tile, Owner o)
@@ -154,7 +152,7 @@
 		MarkTileDirtyByTile(tile2);
 	}
 
-	return CommandCost(_price.remove_ship_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_ship_depot);
 }
 
 /** build a shiplift */
@@ -195,7 +193,7 @@
 		MarkTileDirtyByTile(tile + delta);
 	}
 
-	return CommandCost(_price.clear_water * 22 >> 3);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_water * 22 >> 3);
 }
 
 static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
@@ -214,7 +212,7 @@
 		MakeWaterOrCanalDependingOnSurroundings(tile - delta, _current_player);
 	}
 
-	return CommandCost(_price.clear_water * 2);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_water * 2);
 }
 
 /**
@@ -244,8 +242,6 @@
 {
 	DiagDirection dir;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	switch (GetTileSlope(tile, NULL)) {
 		case SLOPE_SW: dir = DIAGDIR_SW; break;
 		case SLOPE_SE: dir = DIAGDIR_SE; break;
@@ -264,7 +260,7 @@
  */
 CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	int size_x, size_y;
 	int x;
 	int y;
@@ -279,8 +275,6 @@
 	sx = TileX(p1);
 	sy = TileY(p1);
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (x < sx) Swap(x, sx);
 	if (y < sy) Swap(y, sy);
 	size_x = (x - sx) + 1;
@@ -341,7 +335,7 @@
 			if (GetTileOwner(tile) != OWNER_WATER && GetTileOwner(tile) != OWNER_NONE && !CheckTileOwnership(tile)) return CMD_ERROR;
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
-			return CommandCost(_price.clear_water);
+			return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_water);
 
 		case WATER_TILE_COAST: {
 			Slope slope = GetTileSlope(tile, NULL);
@@ -351,9 +345,9 @@
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
 			if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
-				return CommandCost(_price.clear_water);
+				return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_water);
 			} else {
-				return CommandCost(_price.clear_roughland);
+				return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_roughland);
 			}
 		}
 
--- a/src/waypoint.cpp	Wed Jan 09 16:40:02 2008 +0000
+++ b/src/waypoint.cpp	Wed Jan 09 16:55:48 2008 +0000
@@ -163,8 +163,6 @@
 	Slope tileh;
 	Axis axis;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* if custom gfx are used, make sure it is within bounds */
 	if (p1 >= GetNumCustomStations(STAT_CLASS_WAYP)) return CMD_ERROR;
 
@@ -247,7 +245,7 @@
 		wp_auto_delete.Detach();
 	}
 
-	return CommandCost(_price.build_train_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_train_depot);
 }
 
 /**
@@ -299,7 +297,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return CommandCost(_price.remove_train_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);
 }
 
 /**
@@ -312,7 +310,6 @@
  */
 CommandCost CmdRemoveTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 	return RemoveTrainWaypoint(tile, flags, true);
 }