(svn r9534) [gamebalance] -Codechange: Made the prices a member of the Economy and removed all global variables concerning prices (INCOMPLETE). gamebalance
authorcelestar
Sat, 31 Mar 2007 12:34:36 +0000
branchgamebalance
changeset 9903 dc85aaa556ae
parent 9902 ed8f92929297
child 9904 e7d15ae60d43
(svn r9534) [gamebalance] -Codechange: Made the prices a member of the Economy and removed all global variables concerning prices (INCOMPLETE).
src/ai/default/default.cpp
src/aircraft_cmd.cpp
src/aircraft_gui.cpp
src/bridge_gui.cpp
src/build_vehicle_gui.cpp
src/clear_cmd.cpp
src/economy.cpp
src/economy_new.cpp
src/economy_new.h
src/engine_gui.cpp
src/industry_cmd.cpp
src/industry_gui.cpp
src/newgrf.cpp
src/oldloader.cpp
src/openttd.h
src/rail_cmd.cpp
src/road_cmd.cpp
src/roadveh_cmd.cpp
src/roadveh_gui.cpp
src/ship_cmd.cpp
src/ship_gui.cpp
src/station_cmd.cpp
src/town.cpp
src/town_cmd.cpp
src/town_gui.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	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/ai/default/default.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -99,7 +99,7 @@
 				v->type == VEH_SHIP) {
 			/* replace engine? */
 			if (v->type == VEH_TRAIN && v->engine_type < 3 &&
-					(_price.build_railvehicle >> 3) < p->player_money) {
+					(_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) < p->player_money) {
 				p->ai.state = AIS_VEH_CHECK_REPLACE_VEHICLE;
 				p->ai.cur_veh = v;
 				return;
@@ -107,8 +107,8 @@
 
 			/* not profitable? */
 			if (v->age >= 730 &&
-					v->profit_last_year < _price.station_value * 5 &&
-					v->profit_this_year < _price.station_value * 5) {
+					v->profit_last_year < _eco->GetPrice(CEconomy::STATION_VALUE) * 5 &&
+					v->profit_this_year < _eco->GetPrice(CEconomy::STATION_VALUE) * 5) {
 				p->ai.state_counter = 0;
 				p->ai.state = AIS_SELL_VEHICLE;
 				p->ai.cur_veh = v;
@@ -226,7 +226,7 @@
 
 static int32 AiGetBasePrice(const Player* p)
 {
-	int32 base = _price.station_value;
+	int32 base = _eco->GetPrice(CEconomy::STATION_VALUE);
 
 	// adjust base price when more expensive vehicles are available
 	switch (p->ai.railtype_to_use) {
@@ -1628,7 +1628,7 @@
 						ret = DoCommand(c, k, 0, flag, CMD_BUILD_SIGNALS);
 					} while (--j);
 				} else {
-					ret = _price.build_signals;
+					ret = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
 				}
 				if (CmdFailed(ret)) return CMD_ERROR;
 				total_cost += ret;
@@ -1638,7 +1638,7 @@
 			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 += ret + _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD, c);
 
 			if (flag & DC_EXEC) {
 				DoCommand(c, railtype, p->attr&1, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_SINGLE_RAIL);
--- a/src/aircraft_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/aircraft_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -198,7 +198,7 @@
 
 static int32 EstimateAircraftCost(const AircraftVehicleInfo *avi)
 {
-	return avi->base_cost * (_price.aircraft_base >> 3) >> 5;
+	return avi->base_cost * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5;
 }
 
 
@@ -713,7 +713,7 @@
 
 	if (v->vehstatus & VS_STOPPED) return;
 
-	int32 cost = AircraftVehInfo(v->engine_type)->running_cost * _price.aircraft_running / 364;
+	int32 cost = AircraftVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) / 364;
 
 	v->profit_this_year -= cost >> 8;
 
--- a/src/aircraft_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/aircraft_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -78,7 +78,7 @@
 
 			SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
 			SetDParam(2, v->max_age / 366);
-			SetDParam(3, _price.aircraft_running * AircraftVehInfo(v->engine_type)->running_cost >> 8);
+			SetDParam(3, _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) * AircraftVehInfo(v->engine_type)->running_cost >> 8);
 			DrawString(2, 15, STR_A00D_AGE_RUNNING_COST_YR, 0);
 		}
 
--- a/src/bridge_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/bridge_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -15,6 +15,7 @@
 #include "sound.h"
 #include "variables.h"
 #include "bridge.h"
+#include "economy_new.h"
 
 static struct BridgeData {
 	uint count;
@@ -145,7 +146,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 + (((int64)tot_bridgedata_len * _eco->GetPrice(CEconomy::BUILD_BRIDGE) * b->price) >> 8);
 				_bridgedata.indexes[j] = bridge_type;
 				j++;
 			}
--- a/src/build_vehicle_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/build_vehicle_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -201,9 +201,24 @@
 {
 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
+	uint32 cost_class_a, cost_class_b;
 
-	int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
-	int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
+	switch (rvi_a->running_cost_class) {
+		default:
+		case 0: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
+
+	switch (rvi_b->running_cost_class) {
+		default:
+		case 0: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
+
+	int va = rvi_a->running_cost_base * cost_class_a * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
+	int vb = rvi_b->running_cost_base * cost_class_b * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 	int r = va - vb;
 
 	return _internal_sort_order ? -r : r;
@@ -213,6 +228,21 @@
 {
 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
+	uint32 cost_class_a, cost_class_b;
+
+	switch (rvi_a->running_cost_class) {
+		default:
+		case 0: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class_a = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
+
+	switch (rvi_b->running_cost_class) {
+		default:
+		case 0: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class_b = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
 
 	/* Here we are using a few tricks to get the right sort.
 		* We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
@@ -220,8 +250,8 @@
 		* Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
 		* Another thing is that both power and running costs should be doubled for multiheaded engines.
 		* Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
-	int va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power);
-	int vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power);
+	int va = rvi_a->running_cost_base * cost_class_a / max((uint16)1, rvi_a->power);
+	int vb = rvi_b->running_cost_base * cost_class_b / max((uint16)1, rvi_b->power);
 	int r = vb - va;
 
 	return _internal_sort_order ? -r : r;
@@ -378,7 +408,7 @@
 static int DrawRailWagonPurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi)
 {
 	/* Purchase cost */
-	SetDParam(0, (rvi->base_cost * _price.build_railwagon) >> 8);
+	SetDParam(0, (rvi->base_cost * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8);
 	DrawString(x, y, STR_PURCHASE_INFO_COST, 0);
 	y += 10;
 
@@ -403,7 +433,7 @@
 	int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0);
 
 	/* Purchase Cost - Engine weight */
-	SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
+	SetDParam(0, rvi->base_cost * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5);
 	SetDParam(1, rvi->weight << multihead);
 	DrawString(x,y, STR_PURCHASE_INFO_COST_WEIGHT, 0);
 	y += 10;
@@ -421,8 +451,17 @@
 		y += 10;
 	}
 
+	uint32 cost_class;
+
+	switch (rvi->running_cost_class) {
+		default:
+		case 0: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
+
 	/* Running cost */
-	SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead);
+	SetDParam(0, (rvi->running_cost_base * cost_class >> 8) << multihead);
 	DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
 	y += 10;
 
@@ -443,13 +482,13 @@
 	bool refittable = (_engine_info[engine_number].refit_mask != 0);
 
 	/* Purchase cost - Max speed */
-	SetDParam(0, rvi->base_cost * (_price.roadveh_base>>3)>>5);
+	SetDParam(0, rvi->base_cost * (_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) >> 5);
 	SetDParam(1, rvi->max_speed * 10 / 32);
 	DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
 	y += 10;
 
 	/* Running cost */
-	SetDParam(0, rvi->running_cost * _price.roadveh_running >> 8);
+	SetDParam(0, rvi->running_cost * _eco->GetPrice(CEconomy::ROADVEH_RUNNING) >> 8);
 	DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
 	y += 10;
 
@@ -467,7 +506,7 @@
 static int DrawShipPurchaseInfo(int x, int y, EngineID engine_number, const ShipVehicleInfo *svi)
 {
 	/* Purchase cost - Max speed */
-	SetDParam(0, svi->base_cost * (_price.ship_base>>3)>>5);
+	SetDParam(0, svi->base_cost * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5);
 	SetDParam(1, svi->max_speed * 10 / 32);
 	DrawString(x,y, STR_PURCHASE_INFO_COST_SPEED, 0);
 	y += 10;
@@ -480,7 +519,7 @@
 	y += 10;
 
 	/* Running cost */
-	SetDParam(0, svi->running_cost * _price.ship_running >> 8);
+	SetDParam(0, svi->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) >> 8);
 	DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
 	y += 10;
 
@@ -493,7 +532,7 @@
 	CargoID cargo;
 
 	/* Purchase cost - Max speed */
-	SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
+	SetDParam(0, avi->base_cost * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5);
 	SetDParam(1, avi->max_speed * 10 / 16);
 	DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
 	y += 10;
@@ -515,7 +554,7 @@
 	y += 10;
 
 	/* Running cost */
-	SetDParam(0, avi->running_cost * _price.aircraft_running >> 8);
+	SetDParam(0, avi->running_cost * _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) >> 8);
 	DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
 	y += 10;
 
--- a/src/clear_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/clear_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -198,7 +198,7 @@
 	mod->tile = tile;
 	mod->height = (byte)height;
 
-	ts->cost += _price.terraform;
+	ts->cost += _eco->GetPrice(CEconomy::TERRAFORM);
 
 	{
 		int direction = ts->direction, r;
@@ -444,21 +444,21 @@
 
 static int32 ClearTile_Clear(TileIndex tile, byte flags)
 {
-	static const int32* clear_price_table[] = {
-		&_price.clear_1,
-		&_price.purchase_land,
-		&_price.clear_2,
-		&_price.clear_3,
-		&_price.purchase_land,
-		&_price.purchase_land,
-		&_price.clear_2, // XXX unused?
+	static const int32 clear_price_table[] = {
+		_eco->GetPrice(CEconomy::CLEAR_1),
+		_eco->GetPrice(CEconomy::PURCHASE_LAND),
+		_eco->GetPrice(CEconomy::CLEAR_2),
+		_eco->GetPrice(CEconomy::CLEAR_3),
+		_eco->GetPrice(CEconomy::PURCHASE_LAND),
+		_eco->GetPrice(CEconomy::PURCHASE_LAND),
+		_eco->GetPrice(CEconomy::CLEAR_2), // XXX unused?
 	};
 	int32 price;
 
 	if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) {
 		price = 0;
 	} else {
-		price = *clear_price_table[GetClearGround(tile)];
+		price = clear_price_table[GetClearGround(tile)];
 	}
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
--- a/src/economy.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/economy.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -70,7 +70,7 @@
 			}
 		}
 
-		value = num * _price.station_value * 25;
+		value = num * _eco->GetPrice(CEconomy::STATION_VALUE) * 25;
 	}
 
 	{
@@ -597,7 +597,7 @@
 	FOR_ALL_STATIONS(st) {
 		_current_player = st->owner;
 		SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
-		SubtractMoneyFromPlayer(_price.station_value >> 1);
+		SubtractMoneyFromPlayer(_eco->GetPrice(CEconomy::STATION_VALUE) >> 1);
 	}
 
 	if (!HASBIT(1<<0|1<<3|1<<6|1<<9, _cur_month))
@@ -626,46 +626,6 @@
 	InvalidateWindow(WC_COMPANY_LEAGUE, 0);
 }
 
-static void AddSingleInflation(int32 *value, uint16 *frac, int32 amt)
-{
-	int64 tmp = (int64)*value * amt + *frac;
-	*frac   = GB(tmp, 0, 16);
-	*value += tmp >> 16;
-}
-
-static void AddInflation()
-{
-	/* Approximation for (100 + infl_amount)% ** (1 / 12) - 100%
-	 * scaled by 65536
-	 * 12 -> months per year
-	 * This is only a good approxiamtion for small values
-	 */
-	int32 inf = _economy.infl_amount * 54;
-
-	for (uint i = 0; i != NUM_PRICES; i++) {
-		AddSingleInflation((int32*)&_price + i, _price_frac + i, inf);
-	}
-
-	_economy.max_loan_unround += BIGMULUS(_economy.max_loan_unround, inf, 16);
-
-	if (_economy.max_loan + 50000 <= _economy.max_loan_unround)
-		_economy.max_loan += 50000;
-
-	inf = _economy.infl_amount_pr * 54;
-	for (uint i = 0; i != NUM_CARGO; i++) {
-		AddSingleInflation(
-			(int32*)_cargo_payment_rates + i,
-			_cargo_payment_rates_frac + i,
-			inf
-		);
-	}
-
-	InvalidateWindowClasses(WC_BUILD_VEHICLE);
-	InvalidateWindowClasses(WC_REPLACE_VEHICLE);
-	InvalidateWindowClasses(WC_VEHICLE_DETAILS);
-	InvalidateWindow(WC_PAYMENT_RATES, 0);
-}
-
 static void PlayersPayInterest()
 {
 	const Player* p;
@@ -680,7 +640,7 @@
 		SubtractMoneyFromPlayer(BIGMULUS(p->current_loan, interest, 16));
 
 		SET_EXPENSES_TYPE(EXPENSES_OTHER);
-		SubtractMoneyFromPlayer(_price.station_value >> 2);
+		SubtractMoneyFromPlayer(_eco->GetPrice(CEconomy::STATION_VALUE) >> 2);
 	}
 }
 
@@ -697,120 +657,8 @@
 	}
 }
 
-static byte _price_category[NUM_PRICES] = {
-	0, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 1, 1, 1, 1, 1, 1,
-	2,
-};
-
-static const int32 _price_base[NUM_PRICES] = {
-	    100, ///< station_value
-	    100, ///< build_rail
-	     95, ///< build_road
-	     65, ///< build_signals
-	    275, ///< build_bridge
-	    600, ///< build_train_depot
-	    500, ///< build_road_depot
-	    700, ///< build_ship_depot
-	    450, ///< build_tunnel
-	    200, ///< train_station_track
-	    180, ///< train_station_length
-	    600, ///< build_airport
-	    200, ///< build_bus_station
-	    200, ///< build_truck_station
-	    350, ///< build_dock
-	 400000, ///< build_railvehicle
-	   2000, ///< build_railwagon
-	 700000, ///< aircraft_base
-	  14000, ///< roadveh_base
-	  65000, ///< ship_base
-	     20, ///< build_trees
-	    250, ///< terraform
-	     20, ///< clear_1
-	     40, ///< purchase_land
-	    200, ///< clear_2
-	    500, ///< clear_3
-	     20, ///< remove_trees
-	    -70, ///< remove_rail
-	     10, ///< remove_signals
-	     50, ///< clear_bridge
-	     80, ///< remove_train_depot
-	     80, ///< remove_road_depot
-	     90, ///< remove_ship_depot
-	     30, ///< clear_tunnel
-	  10000, ///< clear_water
-	     50, ///< remove_rail_station
-	     30, ///< remove_airport
-	     50, ///< remove_bus_station
-	     50, ///< remove_truck_station
-	     55, ///< remove_dock
-	   1600, ///< remove_house
-	     40, ///< remove_road
-	   5600, ///< running_rail[0] railroad
-	   5200, ///< running_rail[1] monorail
-	   4800, ///< running_rail[2] maglev
-	   9600, ///< aircraft_running
-	   1600, ///< roadveh_running
-	   5600, ///< ship_running
-	1000000, ///< build_industry
-};
-
-static byte price_base_multiplier[NUM_PRICES];
-
-/**
- * Reset changes to the price base multipliers.
- */
-void ResetPriceBaseMultipliers()
-{
-	uint i;
-
-	/* 8 means no multiplier. */
-	for (i = 0; i < NUM_PRICES; i++)
-		price_base_multiplier[i] = 8;
-}
-
-/**
- * Change a price base by the given factor.
- * The price base is altered by factors of two, with an offset of 8.
- * NewBaseCost = OldBaseCost * 2^(n-8)
- * @param price Index of price base to change.
- * @param factor Amount to change by.
- */
-void SetPriceBaseMultiplier(uint price, byte factor)
-{
-	assert(price < NUM_PRICES);
-	price_base_multiplier[price] = factor;
-}
-
 void StartupEconomy()
 {
-	int i;
-
-	assert(sizeof(_price) == NUM_PRICES * sizeof(int32));
-
-	for (i = 0; i != NUM_PRICES; i++) {
-		int32 price = _price_base[i];
-		if (_price_category[i] != 0) {
-			uint mod = _price_category[i] == 1 ? _opt.diff.vehicle_costs : _opt.diff.construction_cost;
-			if (mod < 1) {
-				price = price * 3 >> 2;
-			} else if (mod > 1) {
-				price = price * 9 >> 3;
-			}
-		}
-		if (price_base_multiplier[i] > 8) {
-			price <<= price_base_multiplier[i] - 8;
-		} else {
-			price >>= 8 - price_base_multiplier[i];
-		}
-		((int32*)&_price)[i] = price;
-		_price_frac[i] = 0;
-	}
-
 	_economy.interest_rate = _opt.diff.initial_interest;
 	_economy.infl_amount = _opt.diff.initial_interest;
 	_economy.infl_amount_pr = max(0, _opt.diff.initial_interest - 1);
@@ -1625,8 +1473,6 @@
 void PlayersMonthlyLoop()
 {
 	PlayersGenStatistics();
-	if (_patches.inflation && _cur_year < MAX_YEAR)
-		AddInflation();
 	PlayersPayInterest();
 	/* Reset the _current_player flag */
 	_current_player = OWNER_NONE;
@@ -1779,8 +1625,7 @@
 /** Prices */
 static void SaveLoad_PRIC()
 {
-	SlArray(&_price,      NUM_PRICES, SLE_INT32);
-	SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
+	_eco->SaveLoad_PRIC();
 }
 
 /** Cargo payment rates */
--- a/src/economy_new.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/economy_new.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -8,6 +8,88 @@
 /** The global economy */
 CEconomy *_eco;
 
+/** Base prices used at game startup, reference year 1800 */
+static const int32 price_base[CEconomy::MAX_PRICE] = {
+	    100, ///< station_value
+	    100, ///< build_rail
+	     95, ///< build_road
+	     65, ///< build_signals
+	    275, ///< build_bridge
+	    600, ///< build_train_depot
+	    500, ///< build_road_depot
+	    700, ///< build_ship_depot
+	    450, ///< build_tunnel
+	    200, ///< train_station_track
+	    180, ///< train_station_length
+	    600, ///< build_airport
+	    200, ///< build_bus_station
+	    200, ///< build_truck_station
+	    350, ///< build_dock
+	 400000, ///< build_railvehicle
+	   2000, ///< build_railwagon
+	 700000, ///< aircraft_base
+	  14000, ///< roadveh_base
+	  65000, ///< ship_base
+	     20, ///< build_trees
+	    250, ///< terraform
+	     20, ///< clear_1
+	     40, ///< purchase_land
+	    200, ///< clear_2
+	    500, ///< clear_3
+	     20, ///< remove_trees
+	    -70, ///< remove_rail
+	     10, ///< remove_signals
+	     50, ///< clear_bridge
+	     80, ///< remove_train_depot
+	     80, ///< remove_road_depot
+	     90, ///< remove_ship_depot
+	     30, ///< clear_tunnel
+	  10000, ///< clear_water
+	     50, ///< remove_rail_station
+	     30, ///< remove_airport
+	     50, ///< remove_bus_station
+	     50, ///< remove_truck_station
+	     55, ///< remove_dock
+	   1600, ///< remove_house
+	     40, ///< remove_road
+	   5600, ///< running_rail[0] railroad
+	   5200, ///< running_rail[1] monorail
+	   4800, ///< running_rail[2] maglev
+	   9600, ///< aircraft_running
+	   1600, ///< roadveh_running
+	   5600, ///< ship_running
+	1000000, ///< build_industry
+};
+
+/**
+ * Starts the economy. This sets the basic growth by the difficulty level and adjust the current
+ * EAL by the year of the game. We also set the economic cycles and initialize the prices here
+ * @warning This should be run once per game only
+ */
+CEconomy::CEconomy()
+{
+	/* Set basic growth */
+	FixedT<int32, 16> growth(_opt.diff.economic_growth, 2);
+	m_basic_growth = (growth + 1) / 100 + 1;
+	DEBUG(eco, 3, "Starting a new economy with a basic growth factor of %.3f in the year %d", (double)m_basic_growth, _cur_year);
+
+	/* Set up the economic cycles */
+	m_long_term_cycle   = RandomRange(15) + 45;
+	m_short_term_cycle  = RandomRange( 4) +  6;
+	m_long_term_ampl    = RandomRange( 5) + 10;
+	m_short_term_ampl   = RandomRange(10) + 15;
+	m_long_term_ampl   /= 1000;
+	m_short_term_ampl  /= 1000;
+	DEBUG(eco, 4, "Adjusting economic cycles to %d and %d years", m_long_term_cycle, m_short_term_cycle);
+	DEBUG(eco, 4, "Adjusting economic cycles to %f and %f (amplitude)", (double)m_long_term_ampl, (double)m_short_term_ampl);
+
+	m_activity_level = 1;
+	m_activity_level = pow(m_basic_growth, _cur_year - 1820);
+	DEBUG(eco, 4, "Adjusting basic EAL for current year (offset %d) to %.3f", _cur_year - 1820, (double)m_activity_level);
+
+	/* Initalize prices */
+	for (int i = 0; i < MAX_PRICE; i++) m_prices[i] = price_base[i];
+}
 /**
  * Adjust the global activity level by the cumulative activity level of all towns.
  * This is to iron out the difference between the sum of all economic activites of
@@ -35,6 +117,34 @@
 }
 
 /**
+ * Obtains the costs that a certain user operation at a tile would generate.
+ * This function takes into account that cost that arise from obtaining ownership
+ * of the tile in question.
+ * @warning         This function needs to be called BEFORE the tile actions
+ *                  are performed. Otherwise you'll get an assertion on the command
+ *                  because the computed prices for the test and the exec run are
+ *                  different
+ * @todo            Implement inflation
+ * @todo            Make this work with "overbuilding" owned land
+ * @todo            Implement multipliers (for newgrf)
+ * @param operation The operation that is to be performed on the tile
+ * @param tile      The tile on which we want to operate, if omitted
+ *                  no change of ownership is assumed.
+ * @param release   Set to true when the owner releases ownership of tile
+ * @return          The cost (positive) or income (negative) for the operation
+ */
+int32 CEconomy::GetPrice(Price operation, TileIndex tile, bool release) const
+{
+	int32 cost = m_prices[operation];
+
+	if (tile == INVALID_TILE) return cost;
+	if (release) cost -= Town::GetTilePrice(tile);
+	else if (_current_player < MAX_PLAYERS && _current_player != GetTileOwner(tile)) cost += Town::GetTilePrice(tile);
+
+	return cost;
+}
+
+/**
  * Descriptor for the new economy within the savegame
  */
 /* static */
@@ -45,6 +155,7 @@
 	SLE_VAR(CEconomy, m_short_term_cycle, SLE_INT8),
 	SLE_VAR(CEconomy, m_long_term_ampl,   SLE_INT32),
 	SLE_VAR(CEconomy, m_short_term_ampl,  SLE_INT32),
+	SLE_ARR(CEconomy, m_prices,           SLE_INT32, MAX_PRICE),
 	SLE_END()
 };
 
--- a/src/economy_new.h	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/economy_new.h	Sat Mar 31 12:34:36 2007 +0000
@@ -46,40 +46,81 @@
  * Handles all the economic data and events
  */
 class CEconomy : public EconomicObject {
-private:
-	FixedT<int32, 16> m_basic_growth;     ///< Basic growth number, depends solely on difficulty setting
-	byte              m_long_term_cycle;  ///< The period of the long-term cycle suggested by Kondratiev
-	byte              m_short_term_cycle; ///< The period of the short-term cycle (see Juglar, others)
-	FixedT<int32, 16> m_long_term_ampl;   ///< Amplitude of the long-term cycle
-	FixedT<int32, 16> m_short_term_ampl;  ///< Amplitude of the short-term cycle
-
 public:
 	/**
-	 * Starts the economy. This sets the basic growth by the difficulty level and adjust the current
-	 * EAL by the year of the game. We also set the economic cycles here.
-	 * @warning This should be run once per game only
+	 * Enumerator for the different costs for operations a player can perform.
+	 * Should be used to access the array of prices.
 	 */
-	CEconomy() {
-		/* Set basic growth */
-		FixedT<int32, 16> growth(_opt.diff.economic_growth, 2);
-		m_basic_growth = (growth + 1) / 100 + 1;
-		DEBUG(eco, 3, "Starting a new economy with a basic growth factor of %.3f in the year %d", (double)m_basic_growth, _cur_year);
+	enum Price {
+		STATION_VALUE,
+		PRICE_RAIL_BUILD,      /**< Cost of placing a single piece of track (a vertical or horizontal one.
+								 *  @todo make sure the longer pieces of track cost a bit more
+								 */
+		BUILD_ROAD,
+		BUILD_SIGNALS,
+		BUILD_BRIDGE,
+		BUILD_TRAIN_DEPOT,
+		BUILD_ROAD_DEPOT,
+		BUILD_SHIP_DEPOT,
+		BUILD_TUNNEL,
+		TRAIN_STATION_TRACK,
+		TRAIN_STATION_LENGTH,
+		BUILD_AIRPORT,
+		BUILD_BUS_STATION,
+		BUILD_TRUCK_STATION,
+		BUILD_DOCK,
+		BUILD_RAILVEHICLE,
+		BUILD_RAILWAGON,
+		AIRCRAFT_BASE,
+		ROADVEH_BASE,
+		SHIP_BASE,
+		BUILD_TREES,
+		TERRAFORM,
+		CLEAR_1,
+		PURCHASE_LAND,
+		CLEAR_2,
+		CLEAR_3,
+		REMOVE_TREES,
+		PRICE_RAIL_REMOVE,     /**< cost for removing a piece of track. Less than for building because one
+								 *  might be able to reuse stuff
+						 		 */
+		REMOVE_SIGNALS,
+		CLEAR_BRIDGE,
+		REMOVE_TRAIN_DEPOT,
+		REMOVE_ROAD_DEPOT,
+		REMOVE_SHIP_DEPOT,
+		CLEAR_TUNNEL,
+		CLEAR_WATER,
+		REMOVE_RAIL_STATION,
+		REMOVE_AIRPORT,
+		REMOVE_BUS_STATION,
+		REMOVE_TRUCK_STATION,
+		REMOVE_DOCK,
+		REMOVE_HOUSE,
+		REMOVE_ROAD,
+		RUNNING_RAIL0,
+		RUNNING_RAIL1,
+		RUNNING_RAIL2,
+		AIRCRAFT_RUNNING,
+		ROADVEH_RUNNING,
+		SHIP_RUNNING,
+		BUILD_INDUSTRY,
 
-		/* Set up the economic cycles */
-		m_long_term_cycle  = RandomRange(15) + 45;
-		m_short_term_cycle = RandomRange(4) + 6;
-		m_long_term_ampl = RandomRange(5) + 10;
-		m_short_term_ampl = RandomRange(10) + 15;
-		m_long_term_ampl /= 1000;
-		m_short_term_ampl /= 1000;
-		DEBUG(eco, 4, "Adjusting economic cycles to %d and %d years", m_long_term_cycle, m_short_term_cycle);
-		DEBUG(eco, 4, "Adjusting economic cycles to %f and %f (amplitude)", (double)m_long_term_ampl, (double)m_short_term_ampl);
+		MAX_PRICE              ///< end marker; use with for loops and arrays for example
+	};
 
-		m_activity_level = 1;
-		m_activity_level = pow(m_basic_growth, _cur_year - 1820);
-		DEBUG(eco, 4, "Adjusting basic EAL for current year (offset %d) to %.3f", _cur_year - 1820, (double)m_activity_level);
 
-	}
+private:
+	FixedT<int32, 16> m_basic_growth;                 ///< Basic growth number, depends solely on difficulty setting
+	byte              m_long_term_cycle;              ///< The period of the long-term cycle suggested by Kondratiev
+	byte              m_short_term_cycle;             ///< The period of the short-term cycle (see Juglar, others)
+	FixedT<int32, 16> m_long_term_ampl;               ///< Amplitude of the long-term cycle
+	FixedT<int32, 16> m_short_term_ampl;              ///< Amplitude of the short-term cycle
+
+	FixedT<int32, 16> m_prices[MAX_PRICE];            ///< Cost of operations for the player. Positive for cost, negative for income
+
+public:
+	CEconomy();
 
 	/**
 	 * Removes an economy.
@@ -128,6 +169,30 @@
 
 	static const SaveLoad eco_desc[];
 
+	/**
+	 * Saves and Loads the prices from the savegame
+	 */
+	void SaveLoad_PRIC()
+	{
+		uint16 dummy[MAX_PRICE];
+		SlArray(m_prices, MAX_PRICE, SLE_INT32);
+		SlArray(dummy, MAX_PRICE, SLE_UINT16);
+	}
+
+	int32 GetPrice(Price operation, TileIndex tile = INVALID_TILE, bool release = false) const;
+
+	/**
+	 * Manually sets the price of an operation, used while loading games
+	 * @param operation The operation which to set the price for
+	 * @param value     The new price of the operation
+	 */
+	void SetPrice(int operation, int32 value)
+	{
+		assert(operation < MAX_PRICE);
+		DEBUG(eco, 4, "Setting price of operation %d to %f", (int)operation, (double) value);
+		m_prices[operation] = value;
+	}
+
 private:
 	/**
 	 * Computes the modification of economic growth by cyclic events
--- a/src/engine_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/engine_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -120,12 +120,20 @@
 	const RailVehicleInfo *rvi = RailVehInfo(engine);
 	uint multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 1 : 0;
 
-	SetDParam(0, (_price.build_railvehicle >> 3) * rvi->base_cost >> 5);
+	SetDParam(0, (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) * rvi->base_cost >> 5);
 	SetDParam(2, rvi->max_speed * 10 / 16);
 	SetDParam(3, rvi->power << multihead);
 	SetDParam(1, rvi->weight << multihead);
 
-	SetDParam(4, rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8 << multihead);
+	uint32 cost_class;
+	switch (rvi->running_cost_class)
+	{
+		default:
+		case 0: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+		case 1: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL1); break;
+		case 2: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL2); break;
+	}
+	SetDParam(4, rvi->running_cost_base * cost_class >> 8 << multihead);
 
 	if (rvi->capacity != 0) {
 		SetDParam(5, rvi->cargo_type);
@@ -139,11 +147,11 @@
 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
 {
 	const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
-	SetDParam(0, (_price.aircraft_base >> 3) * avi->base_cost >> 5);
+	SetDParam(0, (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) * avi->base_cost >> 5);
 	SetDParam(1, avi->max_speed * 10 / 16);
 	SetDParam(2, avi->passenger_capacity);
 	SetDParam(3, avi->mail_capacity);
-	SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);
+	SetDParam(4, avi->running_cost * _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) >> 8);
 
 	DrawStringMultiCenter(x, y, STR_A02E_COST_MAX_SPEED_CAPACITY, maxw);
 }
@@ -152,9 +160,9 @@
 {
 	const RoadVehicleInfo *rvi = RoadVehInfo(engine);
 
-	SetDParam(0, (_price.roadveh_base >> 3) * rvi->base_cost >> 5);
+	SetDParam(0, (_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) * rvi->base_cost >> 5);
 	SetDParam(1, rvi->max_speed * 10 / 32);
-	SetDParam(2, rvi->running_cost * _price.roadveh_running >> 8);
+	SetDParam(2, rvi->running_cost * _eco->GetPrice(CEconomy::ROADVEH_RUNNING) >> 8);
 	SetDParam(3, rvi->cargo_type);
 	SetDParam(4, rvi->capacity);
 
@@ -164,11 +172,11 @@
 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw)
 {
 	const ShipVehicleInfo *svi = ShipVehInfo(engine);
-	SetDParam(0, svi->base_cost * (_price.ship_base >> 3) >> 5);
+	SetDParam(0, svi->base_cost * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5);
 	SetDParam(1, svi->max_speed * 10 / 32);
 	SetDParam(2, svi->cargo_type);
 	SetDParam(3, svi->capacity);
-	SetDParam(4, svi->running_cost * _price.ship_running >> 8);
+	SetDParam(4, svi->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) >> 8);
 	DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
 }
 
--- a/src/industry_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/industry_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -1532,7 +1532,7 @@
 
 	if (CreateNewIndustryHelper(tile, p1, flags, indspec, it) == NULL) return CMD_ERROR;
 
-	return (_price.build_industry >> 5) * indspec->cost_multiplier;
+	return (_eco->GetPrice(CEconomy::BUILD_INDUSTRY) >> 5) * indspec->cost_multiplier;
 }
 
 
--- a/src/industry_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/industry_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -39,7 +39,7 @@
 		if (_thd.place_mode == 1 && _thd.window_class == WC_BUILD_INDUSTRY) {
 			int ind_type = _build_industry_types[_opt_ptr->landscape][WP(w,def_d).data_1];
 
-			SetDParam(0, (_price.build_industry >> 5) * GetIndustrySpec(ind_type)->cost_multiplier);
+			SetDParam(0, (_eco->GetPrice(CEconomy::BUILD_INDUSTRY) >> 5) * GetIndustrySpec(ind_type)->cost_multiplier);
 			DrawStringCentered(85, w->height - 21, STR_482F_COST, 0);
 		}
 		break;
--- a/src/newgrf.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/newgrf.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -1412,8 +1412,8 @@
 				byte factor = grf_load_byte(&buf);
 				uint price = gvid + i;
 
-				if (price < NUM_PRICES) {
-					SetPriceBaseMultiplier(price, factor);
+				if (price < CEconomy::MAX_PRICE) {
+					//SetPriceBaseMultiplier(price, factor);
 				} else {
 					grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
 				}
@@ -3962,7 +3962,7 @@
 	ResetEngineListOrder();
 
 	// Reset price base data
-	ResetPriceBaseMultipliers();
+	// ResetPriceBaseMultipliers();
 
 	/* Reset the curencies array */
 	ResetCurrencies();
--- a/src/oldloader.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/oldloader.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -19,6 +19,7 @@
 #include "network/network.h"
 #include "ai/ai.h"
 #include "date.h"
+#include "economy_new.h"
 
 enum {
 	HEADER_SIZE = 49,
@@ -528,8 +529,9 @@
 
 	/* We use a struct to store the prices, but they are ints in a row..
 	so just access the struct as an array of int32's */
-	((int32*)&_price)[num] = _old_price;
-	_price_frac[num] = _old_price_frac;
+	_eco->SetPrice(num, _old_price);
+	//((int32*)&_price)[num] = _old_price;
+	//_price_frac[num] = _old_price_frac;
 
 	return true;
 }
--- a/src/openttd.h	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/openttd.h	Sat Mar 31 12:34:36 2007 +0000
@@ -191,60 +191,6 @@
 	NUM_LANDSCAPE = 4,
 };
 
-enum {
-	NUM_PRICES = 49,
-};
-
-struct Prices {
-	int32 station_value;
-	int32 build_rail;
-	int32 build_road;
-	int32 build_signals;
-	int32 build_bridge;
-	int32 build_train_depot;
-	int32 build_road_depot;
-	int32 build_ship_depot;
-	int32 build_tunnel;
-	int32 train_station_track;
-	int32 train_station_length;
-	int32 build_airport;
-	int32 build_bus_station;
-	int32 build_truck_station;
-	int32 build_dock;
-	int32 build_railvehicle;
-	int32 build_railwagon;
-	int32 aircraft_base;
-	int32 roadveh_base;
-	int32 ship_base;
-	int32 build_trees;
-	int32 terraform;
-	int32 clear_1;
-	int32 purchase_land;
-	int32 clear_2;
-	int32 clear_3;
-	int32 remove_trees;
-	int32 remove_rail;
-	int32 remove_signals;
-	int32 clear_bridge;
-	int32 remove_train_depot;
-	int32 remove_road_depot;
-	int32 remove_ship_depot;
-	int32 clear_tunnel;
-	int32 clear_water;
-	int32 remove_rail_station;
-	int32 remove_airport;
-	int32 remove_bus_station;
-	int32 remove_truck_station;
-	int32 remove_dock;
-	int32 remove_house;
-	int32 remove_road;
-	int32 running_rail[3];
-	int32 aircraft_running;
-	int32 roadveh_running;
-	int32 ship_running;
-	int32 build_industry;
-};
-
 #define GAME_DIFFICULTY_NUM 19
 
 struct GameDifficulty {
--- a/src/rail_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/rail_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -191,7 +191,7 @@
 	if (IsSteepSlope(tileh)) {
 		if (existing == 0) {
 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
-			if (valid & rail_bits) return _price.terraform;
+			if (valid & rail_bits) return _eco->GetPrice(CEconomy::TERRAFORM);
 		}
 	} else {
 		rail_bits |= existing;
@@ -215,7 +215,7 @@
 			} else if (!_patches.build_on_slopes || _is_old_ai_player) {
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 			} else {
-				return _price.terraform;
+				return _eco->GetPrice(CEconomy::TERRAFORM);
 			}
 		}
 	}
@@ -276,6 +276,7 @@
 				SetRailGroundType(tile, RAIL_GROUND_BARREN);
 				SetTrackBits(tile, GetTrackBits(tile) | trackbit);
 			}
+			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD, tile);
 			break;
 
 		case MP_STREET:
@@ -314,6 +315,7 @@
 			if (CmdFailed(ret)) return ret;
 			cost += ret;
 
+			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD, tile);
 			if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype);
 			break;
 	}
@@ -324,7 +326,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return cost + _price.build_rail;
+	return cost;
 }
 
 /** Remove a single piece of track
@@ -336,7 +338,7 @@
 {
 	Track track = (Track)p2;
 	TrackBits trackbit;
-	int32 cost = _price.remove_rail;
+	int32 cost = 0;
 	bool crossing = false;
 
 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@@ -353,6 +355,7 @@
 				return CMD_ERROR;
 			}
 
+			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_REMOVE, tile, true);
 			if (flags & DC_EXEC) {
 				MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
 			}
@@ -376,8 +379,9 @@
 			if (HasSignalOnTrack(tile, track))
 				cost += DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS);
 
+			present ^= trackbit;
+			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_REMOVE, tile, (present == 0));
 			if (flags & DC_EXEC) {
-				present ^= trackbit;
 				if (present == 0) {
 					DoClearSquare(tile);
 				} else {
@@ -588,6 +592,8 @@
 	d = AllocateDepot();
 	if (d == NULL) return CMD_ERROR;
 
+	cost += _eco->GetPrice(CEconomy::BUILD_TRAIN_DEPOT, tile);
+
 	if (flags & DC_EXEC) {
 		MakeRailDepot(tile, _current_player, dir, (RailType)p1);
 		MarkTileDirtyByTile(tile);
@@ -599,7 +605,7 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return cost + _price.build_train_depot;
+	return cost;
 }
 
 /** Build signals, alternate between double/single, signal/semaphore,
@@ -647,11 +653,11 @@
 
 	if (!HasSignalOnTrack(tile, track)) {
 		// build new signals
-		cost = _price.build_signals;
+		cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
 	} else {
 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
 			// convert signals <-> semaphores
-			cost = _price.build_signals + _price.remove_signals;
+			cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS) + _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
 		} else {
 			// it is free to change orientation/pre-exit-combo signals
 			cost = 0;
@@ -834,7 +840,7 @@
 		MarkTileDirtyByTile(tile);
 	}
 
-	return _price.remove_signals;
+	return _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
 }
 
 /** Remove signals on a stretch of track.
@@ -886,7 +892,7 @@
 		}
 	}
 
-	return _price.build_rail / 2;
+	return _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2;
 }
 
 extern int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
@@ -970,7 +976,7 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return _price.remove_train_depot;
+	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT, tile, true);
 }
 
 static int32 ClearTile_Track(TileIndex tile, byte flags)
--- a/src/road_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/road_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -140,10 +140,10 @@
 			c &= present;
 			if (c == 0) return CMD_ERROR;
 
+			present ^= c;
 			if (flags & DC_EXEC) {
 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
-				present ^= c;
 				if (present == 0) {
 					DoClearSquare(tile);
 				} else {
@@ -151,7 +151,7 @@
 					MarkTileDirtyByTile(tile);
 				}
 			}
-			return CountRoadBits(c) * _price.remove_road;
+			return CountRoadBits(c) * _eco->GetPrice(CEconomy::REMOVE_ROAD, tile, (present == 0));
 		}
 
 		case ROAD_TILE_CROSSING: {
@@ -166,7 +166,7 @@
 				MarkTileDirtyByTile(tile);
 				YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
 			}
-			return _price.remove_road * 2;
+			return _eco->GetPrice(CEconomy::REMOVE_ROAD) * 2;
 		}
 
 		default:
@@ -218,7 +218,7 @@
 			// force full pieces.
 			*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 			*pieces |= (RoadBits)((*pieces & 0x3) << 2);
-			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _eco->GetPrice(CEconomy::TERRAFORM);
 		}
 		return CMD_ERROR;
 	}
@@ -233,7 +233,7 @@
 
 	// 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 existing != 0 ? 0 : _eco->GetPrice(CEconomy::TERRAFORM);
 	}
 
 	// partly leveled up tile, only if there's no road on that tile
@@ -241,7 +241,7 @@
 		// force full pieces.
 		*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 		*pieces |= (RoadBits)((*pieces & 0x3) << 2);
-		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _eco->GetPrice(CEconomy::TERRAFORM);
 	}
 	return CMD_ERROR;
 }
@@ -329,7 +329,8 @@
 				MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2);
 				MarkTileDirtyByTile(tile);
 			}
-			return _price.build_road * 2;
+			/** @todo should be more expensive */
+			return _eco->GetPrice(CEconomy::BUILD_ROAD) * 2;
 		}
 
 		default:
@@ -350,9 +351,12 @@
 	if (IsTileType(tile, MP_STREET)) {
 		// Don't put the pieces that already exist
 		pieces &= ComplementRoadBits(existing);
+		cost += CountRoadBits(pieces) * _eco->GetPrice(CEconomy::BUILD_ROAD);
+	} else {
+		cost += _eco->GetPrice(CEconomy::BUILD_ROAD, tile); /* the first road bit purchases us the tile */
+		cost += (CountRoadBits(pieces) - 1) * _eco->GetPrice(CEconomy::BUILD_ROAD);
 	}
 
-	cost += CountRoadBits(pieces) * _price.build_road;
 
 	if (flags & DC_EXEC) {
 		if (IsTileType(tile, MP_STREET)) {
@@ -385,7 +389,7 @@
 		YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile)));
 	}
 
-	return _price.build_rail >> 1;
+	return _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2;
 }
 
 
@@ -534,6 +538,8 @@
 	dep = AllocateDepot();
 	if (dep == NULL) return CMD_ERROR;
 
+	cost += _eco->GetPrice(CEconomy::BUILD_ROAD_DEPOT, tile);
+
 	if (flags & DC_EXEC) {
 		dep->xy = tile;
 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
@@ -541,7 +547,7 @@
 		MakeRoadDepot(tile, _current_player, dir);
 		MarkTileDirtyByTile(tile);
 	}
-	return cost + _price.build_road_depot;
+	return cost;
 }
 
 static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
@@ -553,7 +559,7 @@
 
 	if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
 
-	return _price.remove_road_depot;
+	return _eco->GetPrice(CEconomy::REMOVE_ROAD_DEPOT, tile, true);
 }
 
 static int32 ClearTile_Road(TileIndex tile, byte flags)
--- a/src/roadveh_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/roadveh_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -114,7 +114,7 @@
 
 static int32 EstimateRoadVehCost(EngineID engine_type)
 {
-	return ((_price.roadveh_base >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5;
+	return ((_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5;
 }
 
 /** Build a road vehicle.
@@ -1811,7 +1811,7 @@
 		}
 	}
 
-	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
+	cost = RoadVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::ROADVEH_RUNNING) / 364;
 
 	v->profit_this_year -= cost >> 8;
 
--- a/src/roadveh_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/roadveh_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -50,7 +50,7 @@
 
 			SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
 			SetDParam(2, v->max_age / 366);
-			SetDParam(3, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running >> 8);
+			SetDParam(3, RoadVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::ROADVEH_RUNNING) >> 8);
 			DrawString(2, 15, STR_900D_AGE_RUNNING_COST_YR, 0);
 		}
 
--- a/src/ship_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/ship_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -184,7 +184,7 @@
 
 	if (v->vehstatus & VS_STOPPED) return;
 
-	cost = ShipVehInfo(v->engine_type)->running_cost * _price.ship_running / 364;
+	cost = ShipVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) / 364;
 	v->profit_this_year -= cost >> 8;
 
 	SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
@@ -425,7 +425,7 @@
 
 static int32 EstimateShipCost(EngineID engine_type)
 {
-	return ShipVehInfo(engine_type)->base_cost * (_price.ship_base>>3)>>5;
+	return ShipVehInfo(engine_type)->base_cost * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5;
 }
 
 static void ShipArrivesAt(const Vehicle* v, Station* st)
--- a/src/ship_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/ship_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -48,7 +48,7 @@
 
 			SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
 			SetDParam(2, v->max_age / 366);
-			SetDParam(3, ShipVehInfo(v->engine_type)->running_cost * _price.ship_running >> 8);
+			SetDParam(3, ShipVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) >> 8);
 			DrawString(2, 15, STR_9812_AGE_RUNNING_COST_YR, 0);
 		}
 
--- a/src/station_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/station_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -651,7 +651,7 @@
 					(invalid_dirs&8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
 				return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 			}
-			cost += _price.terraform;
+			cost += _eco->GetPrice(CEconomy::TERRAFORM);
 			flat_z += TILE_HEIGHT;
 		}
 
@@ -834,7 +834,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;
-	int32 cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
+	int32 cost = ret + (numtracks * _eco->GetPrice(CEconomy::TRAIN_STATION_TRACK) + _eco->GetPrice(CEconomy::TRAIN_STATION_LENGTH)) * plat_len;
 
 	// Make sure there are no similar stations around us.
 	Station *st = GetStationAround(tile_org, w_org, h_org, est);
@@ -1058,7 +1058,7 @@
 			DeleteStationIfEmpty(st);
 		}
 	}
-	return _price.remove_rail_station;
+	return _eco->GetPrice(CEconomy::REMOVE_RAIL_STATION);
 }
 
 
@@ -1088,7 +1088,7 @@
 			if (st->TileBelongsToRailStation(tile)) {
 				if (!EnsureNoVehicle(tile))
 					return CMD_ERROR;
-				cost += _price.remove_rail_station;
+				cost += _eco->GetPrice(CEconomy::REMOVE_RAIL_STATION);
 				if (flags & DC_EXEC) {
 					Track track = GetRailStationTrack(tile);
 					DoClearSquare(tile);
@@ -1140,7 +1140,7 @@
 		YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile));
 	}
 
-	return _price.build_rail >> 1;
+	return _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2;
 }
 
 /**
@@ -1248,7 +1248,7 @@
 		st->sign.width_1 = 0;
 	}
 
-	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
+	cost += (type) ? _eco->GetPrice(CEconomy::BUILD_TRUCK_STATION) : _eco->GetPrice(CEconomy::BUILD_BUS_STATION);
 
 	if (flags & DC_EXEC) {
 		// Insert into linked list of RoadStops
@@ -1324,7 +1324,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
+	return (is_truck) ? _eco->GetPrice(CEconomy::REMOVE_TRUCK_STATION) : _eco->GetPrice(CEconomy::REMOVE_BUS_STATION);
 }
 
 /** Remove a bus or truck stop
@@ -1541,7 +1541,7 @@
 		}
 	}
 
-	cost += _price.build_airport * w * h;
+	cost += _eco->GetPrice(CEconomy::BUILD_AIRPORT) * w * h;
 
 	if (flags & DC_EXEC) {
 		st->airport_tile = tile;
@@ -1590,7 +1590,7 @@
 	int w = afc->size_x;
 	int h = afc->size_y;
 
-	int32 cost = w * h * _price.remove_airport;
+	int32 cost = w * h * _eco->GetPrice(CEconomy::REMOVE_AIRPORT);
 
 	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
 		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
@@ -1664,7 +1664,7 @@
 		st_auto_delete.Release();
 	}
 
-	return _price.build_dock;
+	return _eco->GetPrice(CEconomy::BUILD_DOCK);
 }
 
 /* Checks if any ship is servicing the buoy specified. Returns yes or no */
@@ -1716,7 +1716,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return _price.remove_truck_station;
+	return _eco->GetPrice(CEconomy::REMOVE_TRUCK_STATION);
 }
 
 static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
@@ -1825,7 +1825,7 @@
 		/* success, so don't delete the new station */
 		st_auto_delete.Release();
 	}
-	return _price.build_dock;
+	return _eco->GetPrice(CEconomy::BUILD_DOCK);
 }
 
 static int32 RemoveDock(Station *st, uint32 flags)
@@ -1854,7 +1854,7 @@
 		DeleteStationIfEmpty(st);
 	}
 
-	return _price.remove_dock;
+	return _eco->GetPrice(CEconomy::REMOVE_DOCK);
 }
 
 #include "table/station_land.h"
--- a/src/town.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/town.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -15,7 +15,7 @@
 	const Town *t = GetRadiusGroupForTile(tile, rad);
 	FixedT<int64, 16> price = t->GetActivity();
 	DEBUG(eco, 6, "Getting price for tile 0x%x at %f (authority at 0x%x)", tile, (double)price, t->xy);
-	price *=  _price.purchase_land * rad * rad * 10;
+	price *=  _eco->GetPrice(CEconomy::PURCHASE_LAND) * rad * rad * 10;
 
 	return price;
 }
--- a/src/town_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/town_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -376,7 +376,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 = _eco->GetPrice(CEconomy::REMOVE_HOUSE) * hs->removal_cost >> 8;
 
 	rating = hs->remove_rating_decrease;
 	_cleared_town_rating += rating;
@@ -1634,7 +1634,7 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
-	cost = (_price.build_industry >> 8) * _town_action_costs[p2];
+	cost = (_eco->GetPrice(CEconomy::BUILD_INDUSTRY) >> 8) * _town_action_costs[p2];
 
 	if (flags & DC_EXEC) {
 		_town_action_proc[p2](t);
--- a/src/town_gui.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/town_gui.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -58,8 +58,8 @@
 		}
 
 		// Things worth more than this are not shown
-		avail = GetPlayer(pid)->player_money + _price.station_value * 200;
-		ref = _price.build_industry >> 8;
+		avail = GetPlayer(pid)->player_money + _eco->GetPrice(CEconomy::STATION_VALUE) * 200;
+		ref = _eco->GetPrice(CEconomy::BUILD_INDUSTRY) >> 8;
 
 		for (i = 0; i != lengthof(_town_action_costs); i++, avail_buttons >>= 1) {
 			if (HASBIT(avail_buttons, 0) && avail >= _town_action_costs[i] * ref) {
@@ -173,7 +173,7 @@
 			int i = WP(w,def_d).data_1;
 
 			if (i != -1) {
-				SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
+				SetDParam(1, (_eco->GetPrice(CEconomy::BUILD_INDUSTRY) >> 8) * _town_action_costs[i]);
 				SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
 				DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
 			}
--- a/src/train_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/train_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -560,7 +560,7 @@
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
 	const RailVehicleInfo *rvi = RailVehInfo(engine);
-	int32 value = (rvi->base_cost * _price.build_railwagon) >> 8;
+	int32 value = (rvi->base_cost * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8;
 
 	uint num_vehicles = 1 + CountArticulatedParts(engine);
 
@@ -663,7 +663,7 @@
 
 static int32 EstimateTrainCost(const RailVehicleInfo* rvi)
 {
-	return rvi->base_cost * (_price.build_railvehicle >> 3) >> 5;
+	return rvi->base_cost * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5;
 }
 
 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
@@ -3461,8 +3461,16 @@
 
 	do {
 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
-		if (rvi->running_cost_base > 0)
-			cost += rvi->running_cost_base * _price.running_rail[rvi->running_cost_class];
+		if (rvi->running_cost_base > 0) {
+			int32 cost_class;
+			switch (rvi->running_cost_class) {
+				default:
+				case 0: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+				case 1: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+				case 2: cost_class = _eco->GetPrice(CEconomy::RUNNING_RAIL0); break;
+			}
+			cost += rvi->running_cost_base * cost_class;
+		}
 	} while ((v = GetNextVehicle(v)) != NULL);
 
 	return cost;
--- a/src/tree_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/tree_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -250,7 +250,7 @@
 						MarkTileDirtyByTile(tile);
 					}
 					// 2x as expensive to add more trees to an existing tile
-					cost += _price.build_trees * 2;
+					cost += _eco->GetPrice(CEconomy::BUILD_TREES) * 2;
 					break;
 
 				case MP_CLEAR:
@@ -261,8 +261,8 @@
 					}
 
 					switch (GetClearGround(tile)) {
-						case CLEAR_FIELDS: cost += _price.clear_3; break;
-						case CLEAR_ROCKS:  cost += _price.clear_2; break;
+						case CLEAR_FIELDS: cost += _eco->GetPrice(CEconomy::CLEAR_3); break;
+						case CLEAR_ROCKS:  cost += _eco->GetPrice(CEconomy::CLEAR_2); break;
 						default: break;
 					}
 
@@ -293,7 +293,7 @@
 						if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TREE_RAINFOREST, TREE_CACTUS))
 							SetTropicZone(tile, TROPICZONE_RAINFOREST);
 					}
-					cost += _price.build_trees;
+					cost += _eco->GetPrice(CEconomy::BUILD_TREES);
 					break;
 
 				default:
@@ -439,7 +439,7 @@
 
 	if (flags & DC_EXEC) DoClearSquare(tile);
 
-	return num * _price.remove_trees;
+	return num * _eco->GetPrice(CEconomy::REMOVE_TREES);
 }
 
 static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)
--- a/src/tunnelbridge_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -118,7 +118,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 _price.terraform;
+	if (HASBIT(valid, tileh)) return _eco->GetPrice(CEconomy::TERRAFORM);
 
 	return CMD_ERROR;
 }
@@ -133,7 +133,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 _price.terraform;
+	if (HASBIT(valid, tileh)) return _eco->GetPrice(CEconomy::TERRAFORM);
 
 	return CMD_ERROR;
 }
@@ -293,7 +293,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 = (bridge_len + 1) * _eco->GetPrice(CEconomy::CLEAR_BRIDGE); // The cost of clearing the current bridge.
 		replace_bridge = true;
 		replaced_bridge_type = GetBridgeType(tile_start);
 	} else {
@@ -429,7 +429,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 += (int64)bridge_len * _eco->GetPrice(CEconomy::BUILD_BRIDGE) * b->price >> 8;
 	}
 
 	return cost;
@@ -487,13 +487,13 @@
 			return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY);
 		}
 
-		cost += _price.build_tunnel;
+		cost += _eco->GetPrice(CEconomy::BUILD_TUNNEL);
 		cost += cost >> 3; // add a multiplier for longer tunnels
 		if (cost >= 400000000) cost = 400000000;
 	}
 
 	/* Add the cost of the entrance */
-	cost += _price.build_tunnel + ret;
+	cost += _eco->GetPrice(CEconomy::BUILD_TUNNEL) + ret;
 
 	// if the command fails from here on we want the end tile to be highlighted
 	_build_tunnel_endtile = end_tile;
@@ -506,7 +506,7 @@
 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 		if (CmdFailed(ret)) return ret;
 	}
-	cost += _price.build_tunnel + ret;
+	cost += _eco->GetPrice(CEconomy::BUILD_TUNNEL) + ret;
 
 	if (flags & DC_EXEC) {
 		if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
@@ -607,7 +607,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
-	return _price.clear_tunnel * (length + 1);
+	return _eco->GetPrice(CEconomy::CLEAR_TUNNEL) * (length + 1);
 }
 
 
@@ -679,7 +679,7 @@
 		YapfNotifyTrackLayoutChange(endtile, track);
 	}
 
-	return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge;
+	return (DistanceManhattan(tile, endtile) + 1) * _eco->GetPrice(CEconomy::CLEAR_BRIDGE);
 }
 
 static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
@@ -723,7 +723,7 @@
 			YapfNotifyTrackLayoutChange(tile, track);
 			YapfNotifyTrackLayoutChange(endtile, track);
 		}
-		return (length + 1) * (_price.build_rail >> 1);
+		return (length + 1) * (_eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2);
 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
@@ -757,7 +757,7 @@
 			}
 		}
 
-		return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail >> 1);
+		return (DistanceManhattan(tile, endtile) + 1) * (_eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2);
 	} else {
 		return CMD_ERROR;
 	}
--- a/src/unmovable_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/unmovable_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -221,6 +221,7 @@
 	}
 
 	if (IsOwnedLand(tile)) {
+		if (flags & DC_AUTO) return CMD_ERROR;
 		return DoCommand(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
 	}
 
--- a/src/variables.h	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/variables.h	Sat Mar 31 12:34:36 2007 +0000
@@ -12,10 +12,6 @@
 
 #include "gfx.h"
 
-// Prices and also the fractional part.
-VARDEF Prices _price;
-VARDEF uint16 _price_frac[NUM_PRICES];
-
 VARDEF uint32 _cargo_payment_rates[NUM_CARGO];
 VARDEF uint16 _cargo_payment_rates_frac[NUM_CARGO];
 
--- a/src/vehicle.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/vehicle.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -789,12 +789,12 @@
 	int32 base_cost = 0;
 
 	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 = _eco->GetPrice(CEconomy::SHIP_BASE); break;
+		case VEH_ROAD: base_cost = _eco->GetPrice(CEconomy::ROADVEH_BASE); break;
+		case VEH_AIRCRAFT: base_cost = _eco->GetPrice(CEconomy::AIRCRAFT_BASE); break;
 		case VEH_TRAIN:
 			base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
-							 _price.build_railwagon : _price.build_railvehicle);
+							 _eco->GetPrice(CEconomy::BUILD_RAILWAGON) : _eco->GetPrice(CEconomy::BUILD_RAILVEHICLE));
 			break;
 		default: NOT_REACHED(); break;
 	}
--- a/src/water_cmd.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/water_cmd.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -92,7 +92,7 @@
 		MarkTileDirtyByTile(tile2);
 	}
 
-	return cost + _price.build_ship_depot;
+	return cost + _eco->GetPrice(CEconomy::BUILD_SHIP_DEPOT);
 }
 
 static int32 RemoveShipDepot(TileIndex tile, uint32 flags)
@@ -117,7 +117,7 @@
 		MarkTileDirtyByTile(tile2);
 	}
 
-	return _price.remove_ship_depot;
+	return _eco->GetPrice(CEconomy::REMOVE_SHIP_DEPOT);
 }
 
 // build a shiplift
@@ -158,7 +158,7 @@
 		MarkTileDirtyByTile(tile + delta);
 	}
 
-	return _price.clear_water * 22 >> 3;
+	return _eco->GetPrice(CEconomy::CLEAR_WATER) * 22 >> 3;
 }
 
 static int32 RemoveShiplift(TileIndex tile, uint32 flags)
@@ -177,7 +177,7 @@
 		DoClearSquare(tile - delta);
 	}
 
-	return _price.clear_water * 2;
+	return _eco->GetPrice(CEconomy::CLEAR_WATER) * 2;
 }
 
 static void MarkTilesAroundDirty(TileIndex tile)
@@ -266,7 +266,7 @@
 			MarkTilesAroundDirty(tile);
 		}
 
-		cost += _price.clear_water;
+		cost += _eco->GetPrice(CEconomy::CLEAR_WATER);
 	} END_TILE_LOOP(tile, size_x, size_y, 0);
 
 	if (cost == 0) {
@@ -294,7 +294,7 @@
 			if (GetTileOwner(tile) != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
-			return _price.clear_water;
+			return _eco->GetPrice(CEconomy::CLEAR_WATER);
 
 		case WATER_TILE_COAST: {
 			Slope slope = GetTileSlope(tile, NULL);
@@ -310,9 +310,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 _eco->GetPrice(CEconomy::CLEAR_WATER);
 			} else {
-				return _price.purchase_land;
+				return _eco->GetPrice(CEconomy::PURCHASE_LAND);
 			}
 		}
 
--- a/src/waypoint.cpp	Fri Mar 23 12:03:41 2007 +0000
+++ b/src/waypoint.cpp	Sat Mar 31 12:34:36 2007 +0000
@@ -250,7 +250,7 @@
 		YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
 	}
 
-	return _price.build_train_depot;
+	return _eco->GetPrice(CEconomy::BUILD_TRAIN_DEPOT);
 }
 
 /* Daily loop for waypoints */
@@ -294,7 +294,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return _price.remove_train_depot;
+	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT);
 }
 
 /** Delete a waypoint