src/economy.cpp
branchnoai
changeset 9723 eee46cb39750
parent 9722 ebf0ece7d8f6
child 9724 b39bc69bb2f2
equal deleted inserted replaced
9722:ebf0ece7d8f6 9723:eee46cb39750
     3 /** @file economy.cpp */
     3 /** @file economy.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "currency.h"
     7 #include "currency.h"
     8 #include "functions.h"
       
     9 #include "landscape.h"
     8 #include "landscape.h"
    10 #include "strings.h" // XXX InjectDParam()
       
    11 #include "table/strings.h"
     9 #include "table/strings.h"
    12 #include "table/sprites.h"
    10 #include "table/sprites.h"
    13 #include "map.h"
       
    14 #include "news.h"
    11 #include "news.h"
    15 #include "player.h"
    12 #include "player.h"
    16 #include "station.h"
    13 #include "station.h"
    17 #include "vehicle.h"
    14 #include "command_func.h"
    18 #include "window.h"
       
    19 #include "gfx.h"
       
    20 #include "command.h"
       
    21 #include "saveload.h"
    15 #include "saveload.h"
    22 #include "economy.h"
       
    23 #include "industry.h"
    16 #include "industry.h"
    24 #include "town.h"
    17 #include "town.h"
    25 #include "network/network.h"
    18 #include "network/network.h"
    26 #include "sound.h"
       
    27 #include "engine.h"
    19 #include "engine.h"
    28 #include "network/network_data.h"
    20 #include "network/network_data.h"
    29 #include "variables.h"
    21 #include "variables.h"
    30 #include "vehicle_gui.h"
    22 #include "vehicle_gui.h"
    31 #include "ai/ai.h"
    23 #include "ai/ai.h"
    36 #include "newgrf_sound.h"
    28 #include "newgrf_sound.h"
    37 #include "newgrf_callbacks.h"
    29 #include "newgrf_callbacks.h"
    38 #include "newgrf_industries.h"
    30 #include "newgrf_industries.h"
    39 #include "newgrf_industrytiles.h"
    31 #include "newgrf_industrytiles.h"
    40 #include "unmovable.h"
    32 #include "unmovable.h"
    41 #include "date.h"
       
    42 #include "cargotype.h"
    33 #include "cargotype.h"
    43 #include "player_face.h"
    34 #include "player_face.h"
    44 #include "group.h"
    35 #include "group.h"
       
    36 #include "strings_func.h"
       
    37 #include "tile_cmd.h"
       
    38 #include "functions.h"
       
    39 #include "window_func.h"
       
    40 #include "date_func.h"
       
    41 #include "vehicle_func.h"
       
    42 #include "sound_func.h"
       
    43 #include "track_type.h"
       
    44 #include "track_func.h"
       
    45 #include "rail_map.h"
       
    46 #include "gfx_func.h"
    45 
    47 
    46 /**
    48 /**
    47  * Multiply two integer values and shift the results to right.
    49  * Multiply two integer values and shift the results to right.
    48  *
    50  *
    49  * This function multiplies two integer values. The result is
    51  * This function multiplies two integer values. The result is
    88 	{ SCORE_LOAN,         250000,  50 },
    90 	{ SCORE_LOAN,         250000,  50 },
    89 	{ SCORE_TOTAL,             0,   0 }
    91 	{ SCORE_TOTAL,             0,   0 }
    90 };
    92 };
    91 
    93 
    92 int _score_part[MAX_PLAYERS][SCORE_END];
    94 int _score_part[MAX_PLAYERS][SCORE_END];
       
    95 Economy _economy;
       
    96 Subsidy _subsidies[MAX_PLAYERS];
       
    97 Prices _price;
       
    98 uint16 _price_frac[NUM_PRICES];
       
    99 Money  _cargo_payment_rates[NUM_CARGO];
       
   100 uint16 _cargo_payment_rates_frac[NUM_CARGO];
       
   101 Money _additional_cash_required;
    93 
   102 
    94 Money CalculateCompanyValue(const Player* p)
   103 Money CalculateCompanyValue(const Player* p)
    95 {
   104 {
    96 	PlayerID owner = p->index;
   105 	PlayerID owner = p->index;
    97 	/* Do a little nasty by using CommandCost, so we can use the "overflow" protection of CommandCost */
       
    98 	Money value = 0;
   106 	Money value = 0;
    99 
   107 
   100 	Station *st;
   108 	Station *st;
   101 	uint num = 0;
   109 	uint num = 0;
   102 
   110 
   278 		uint i;
   286 		uint i;
   279 
   287 
   280 		/* See if the old_player had shares in other companies */
   288 		/* See if the old_player had shares in other companies */
   281 		_current_player = old_player;
   289 		_current_player = old_player;
   282 		FOR_ALL_PLAYERS(p) {
   290 		FOR_ALL_PLAYERS(p) {
       
   291 			if (!p->is_active) continue;
   283 			for (i = 0; i < 4; i++) {
   292 			for (i = 0; i < 4; i++) {
   284 				if (p->share_owners[i] == old_player) {
   293 				if (p->share_owners[i] == old_player) {
   285 					/* Sell his shares */
   294 					/* Sell his shares */
   286 					CommandCost res = DoCommand(0, p->index, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY);
   295 					CommandCost res = DoCommand(0, p->index, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY);
   287 					/* Because we are in a DoCommand, we can't just execute an other one and
   296 					/* Because we are in a DoCommand, we can't just execute an other one and
   363 				}
   372 				}
   364 			}
   373 			}
   365 		}
   374 		}
   366 
   375 
   367 		FOR_ALL_VEHICLES(v) {
   376 		FOR_ALL_VEHICLES(v) {
   368 			if (v->owner == old_player && IS_BYTE_INSIDE(v->type, VEH_TRAIN, VEH_AIRCRAFT + 1)) {
   377 			if (v->owner == old_player && IsInsideMM(v->type, VEH_TRAIN, VEH_AIRCRAFT + 1)) {
   369 				if (new_player == PLAYER_SPECTATOR) {
   378 				if (new_player == PLAYER_SPECTATOR) {
   370 					DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   379 					DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   371 					DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
   380 					DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
   372 					DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
   381 					DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
   373 
   382 
   394 								break;
   403 								break;
   395 						}
   404 						}
   396 					}
   405 					}
   397 				} else {
   406 				} else {
   398 					v->owner = new_player;
   407 					v->owner = new_player;
       
   408 					v->colormap = PAL_NONE;
   399 					v->group_id = DEFAULT_GROUP;
   409 					v->group_id = DEFAULT_GROUP;
   400 					if (IsEngineCountable(v)) GetPlayer(new_player)->num_engines[v->engine_type]++;
   410 					if (IsEngineCountable(v)) GetPlayer(new_player)->num_engines[v->engine_type]++;
   401 					switch (v->type) {
   411 					switch (v->type) {
   402 						case VEH_TRAIN:    if (IsFrontEngine(v)) v->unitnumber = ++num_train; break;
   412 						case VEH_TRAIN:    if (IsFrontEngine(v)) v->unitnumber = ++num_train; break;
   403 						case VEH_ROAD:     if (IsRoadVehFront(v)) v->unitnumber = ++num_road; break;
   413 						case VEH_ROAD:     if (IsRoadVehFront(v)) v->unitnumber = ++num_road; break;
   414 	{
   424 	{
   415 		TileIndex tile = 0;
   425 		TileIndex tile = 0;
   416 		do {
   426 		do {
   417 			ChangeTileOwner(tile, old_player, new_player);
   427 			ChangeTileOwner(tile, old_player, new_player);
   418 		} while (++tile != MapSize());
   428 		} while (++tile != MapSize());
       
   429 
       
   430 		if (new_player != PLAYER_SPECTATOR) {
       
   431 			/* Update all signals because there can be new segment that was owned by two players
       
   432 			 * and signals were not propagated */
       
   433 			tile = 0;
       
   434 
       
   435 			do {
       
   436 				if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, new_player) && HasSignals(tile)) {
       
   437 					TrackBits tracks = GetTrackBits(tile);
       
   438 					do { // there may be two tracks with signals for TRACK_BIT_HORZ and TRACK_BIT_VERT
       
   439 						Track track = RemoveFirstTrack(&tracks);
       
   440 						if (HasSignalOnTrack(tile, track)) SetSignalsOnBothDir(tile, track);
       
   441 					} while (tracks != TRACK_BIT_NONE);
       
   442 				}
       
   443 			} while (++tile != MapSize());
       
   444 		}
   419 	}
   445 	}
   420 
   446 
   421 	/* Change color of existing windows */
   447 	/* Change color of existing windows */
   422 	if (new_player != PLAYER_SPECTATOR) ChangeWindowOwner(old_player, new_player);
   448 	if (new_player != PLAYER_SPECTATOR) ChangeWindowOwner(old_player, new_player);
   423 
   449 
   632 	Station *st;
   658 	Station *st;
   633 	Player *p;
   659 	Player *p;
   634 
   660 
   635 	FOR_ALL_STATIONS(st) {
   661 	FOR_ALL_STATIONS(st) {
   636 		_current_player = st->owner;
   662 		_current_player = st->owner;
   637 		SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
   663 		CommandCost cost(EXPENSES_PROPERTY, _price.station_value >> 1);
   638 		SubtractMoneyFromPlayer(_price.station_value >> 1);
   664 		SubtractMoneyFromPlayer(cost);
   639 	}
   665 	}
   640 
   666 
   641 	if (!HasBit(1<<0|1<<3|1<<6|1<<9, _cur_month))
   667 	if (!HasBit(1<<0|1<<3|1<<6|1<<9, _cur_month))
   642 		return;
   668 		return;
   643 
   669 
   733 
   759 
   734 	FOR_ALL_PLAYERS(p) {
   760 	FOR_ALL_PLAYERS(p) {
   735 		if (!p->is_active) continue;
   761 		if (!p->is_active) continue;
   736 
   762 
   737 		_current_player = p->index;
   763 		_current_player = p->index;
   738 		SET_EXPENSES_TYPE(EXPENSES_LOAN_INT);
   764 
   739 
   765 		SubtractMoneyFromPlayer(CommandCost(EXPENSES_LOAN_INT, (Money)BigMulSU(p->current_loan, interest, 16)));
   740 		SubtractMoneyFromPlayer(CommandCost((Money)BigMulSU(p->current_loan, interest, 16)));
   766 
   741 
   767 		SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, _price.station_value >> 2));
   742 		SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
   743 		SubtractMoneyFromPlayer(_price.station_value >> 2);
       
   744 	}
   768 	}
   745 }
   769 }
   746 
   770 
   747 static void HandleEconomyFluctuations()
   771 static void HandleEconomyFluctuations()
   748 {
   772 {
   788 	 700000, ///< aircraft_base
   812 	 700000, ///< aircraft_base
   789 	  14000, ///< roadveh_base
   813 	  14000, ///< roadveh_base
   790 	  65000, ///< ship_base
   814 	  65000, ///< ship_base
   791 	     20, ///< build_trees
   815 	     20, ///< build_trees
   792 	    250, ///< terraform
   816 	    250, ///< terraform
   793 	     20, ///< clear_1
   817 	     20, ///< clear_grass
   794 	     40, ///< purchase_land
   818 	     40, ///< clear_roughland
   795 	    200, ///< clear_2
   819 	    200, ///< clear_rocks
   796 	    500, ///< clear_3
   820 	    500, ///< clear_fields
   797 	     20, ///< remove_trees
   821 	     20, ///< remove_trees
   798 	    -70, ///< remove_rail
   822 	    -70, ///< remove_rail
   799 	     10, ///< remove_signals
   823 	     10, ///< remove_signals
   800 	     50, ///< clear_bridge
   824 	     50, ///< clear_bridge
   801 	     80, ///< remove_train_depot
   825 	     80, ///< remove_train_depot
  1099 			s->age++;
  1123 			s->age++;
  1100 		}
  1124 		}
  1101 	}
  1125 	}
  1102 
  1126 
  1103 	/* 25% chance to go on */
  1127 	/* 25% chance to go on */
  1104 	if (CHANCE16(1,4)) {
  1128 	if (Chance16(1,4)) {
  1105 		/*  Find a free slot*/
  1129 		/*  Find a free slot*/
  1106 		s = _subsidies;
  1130 		s = _subsidies;
  1107 		while (s->cargo_type != CT_INVALID) {
  1131 		while (s->cargo_type != CT_INVALID) {
  1108 			if (++s == endof(_subsidies))
  1132 			if (++s == endof(_subsidies))
  1109 				goto no_add;
  1133 				goto no_add;
  1486 		ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit);
  1510 		ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit);
  1487 	}
  1511 	}
  1488 
  1512 
  1489 	if (route_profit != 0) {
  1513 	if (route_profit != 0) {
  1490 		front_v->profit_this_year += vehicle_profit;
  1514 		front_v->profit_this_year += vehicle_profit;
  1491 		SubtractMoneyFromPlayer(-route_profit);
  1515 		SubtractMoneyFromPlayer(CommandCost(front_v->GetExpenseType(true), -route_profit));
  1492 
  1516 
  1493 		if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
  1517 		if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
  1494 			SndPlayVehicleFx(SND_14_CASHTILL, front_v);
  1518 			SndPlayVehicleFx(SND_14_CASHTILL, front_v);
  1495 		}
  1519 		}
  1496 
  1520 
  1521 			}
  1545 			}
  1522 		}
  1546 		}
  1523 		return;
  1547 		return;
  1524 	}
  1548 	}
  1525 
  1549 
  1526 	if (v->type == VEH_TRAIN && !IsTileType(v->tile, MP_STATION)) {
  1550 	StationID last_visited = v->last_station_visited;
       
  1551 	Station *st = GetStation(last_visited);
       
  1552 
       
  1553 	if (v->type == VEH_TRAIN && (!IsTileType(v->tile, MP_STATION) || GetStationIndex(v->tile) != st->index)) {
  1527 		/* The train reversed in the station. Take the "easy" way
  1554 		/* The train reversed in the station. Take the "easy" way
  1528 		 * out and let the train just leave as it always did. */
  1555 		 * out and let the train just leave as it always did. */
  1529 		SetBit(v->vehicle_flags, VF_LOADING_FINISHED);
  1556 		SetBit(v->vehicle_flags, VF_LOADING_FINISHED);
  1530 		return;
  1557 		return;
  1531 	}
  1558 	}
  1540 	bool anything_loaded   = false;
  1567 	bool anything_loaded   = false;
  1541 	uint32 cargo_not_full  = 0;
  1568 	uint32 cargo_not_full  = 0;
  1542 	uint32 cargo_full      = 0;
  1569 	uint32 cargo_full      = 0;
  1543 
  1570 
  1544 	v->cur_speed = 0;
  1571 	v->cur_speed = 0;
  1545 
       
  1546 	StationID last_visited = v->last_station_visited;
       
  1547 	Station *st = GetStation(last_visited);
       
  1548 
  1572 
  1549 	for (; v != NULL; v = v->Next()) {
  1573 	for (; v != NULL; v = v->Next()) {
  1550 		if (v->cargo_cap == 0) continue;
  1574 		if (v->cargo_cap == 0) continue;
  1551 
  1575 
  1552 		byte load_amount = EngInfo(v->engine_type)->load_amount;
  1576 		byte load_amount = EngInfo(v->engine_type)->load_amount;
  1795 
  1819 
  1796 	value = CalculateCompanyValue(p) >> 2;
  1820 	value = CalculateCompanyValue(p) >> 2;
  1797 	PlayerID old_player = _current_player;
  1821 	PlayerID old_player = _current_player;
  1798 	for (i = 0; i != 4; i++) {
  1822 	for (i = 0; i != 4; i++) {
  1799 		if (p->share_owners[i] != PLAYER_SPECTATOR) {
  1823 		if (p->share_owners[i] != PLAYER_SPECTATOR) {
  1800 			SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
  1801 			_current_player = p->share_owners[i];
  1824 			_current_player = p->share_owners[i];
  1802 			SubtractMoneyFromPlayer(CommandCost(-value));
  1825 			SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, -value));
  1803 		}
  1826 		}
  1804 	}
  1827 	}
  1805 	_current_player = old_player;
  1828 	_current_player = old_player;
  1806 
  1829 
  1807 	p->is_active = false;
  1830 	p->is_active = false;
  1819  * @param p2 unused
  1842  * @param p2 unused
  1820  */
  1843  */
  1821 CommandCost CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1844 CommandCost CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1822 {
  1845 {
  1823 	Player *p;
  1846 	Player *p;
  1824 	CommandCost cost;
  1847 	CommandCost cost(EXPENSES_OTHER);
  1825 
  1848 
  1826 	/* Check if buying shares is allowed (protection against modified clients) */
  1849 	/* Check if buying shares is allowed (protection against modified clients) */
  1827 	/* Cannot buy own shares */
  1850 	/* Cannot buy own shares */
  1828 	if (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
  1851 	if (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
  1829 
  1852 
  1830 	p = GetPlayer((PlayerID)p1);
  1853 	p = GetPlayer((PlayerID)p1);
  1831 
  1854 
  1832 	/* Cannot buy shares of non-existent nor bankrupted company */
  1855 	/* Cannot buy shares of non-existent nor bankrupted company */
  1833 	if (!p->is_active) return CMD_ERROR;
  1856 	if (!p->is_active) return CMD_ERROR;
  1834 
       
  1835 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
  1836 
  1857 
  1837 	/* Protect new companies from hostile takeovers */
  1858 	/* Protect new companies from hostile takeovers */
  1838 	if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
  1859 	if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
  1839 
  1860 
  1840 	/* Those lines are here for network-protection (clients can be slow) */
  1861 	/* Those lines are here for network-protection (clients can be slow) */
  1881 	p = GetPlayer((PlayerID)p1);
  1902 	p = GetPlayer((PlayerID)p1);
  1882 
  1903 
  1883 	/* Cannot sell shares of non-existent nor bankrupted company */
  1904 	/* Cannot sell shares of non-existent nor bankrupted company */
  1884 	if (!p->is_active) return CMD_ERROR;
  1905 	if (!p->is_active) return CMD_ERROR;
  1885 
  1906 
  1886 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
  1887 
       
  1888 	/* Those lines are here for network-protection (clients can be slow) */
  1907 	/* Those lines are here for network-protection (clients can be slow) */
  1889 	if (GetAmountOwnedBy(p, _current_player) == 0) return CommandCost();
  1908 	if (GetAmountOwnedBy(p, _current_player) == 0) return CommandCost();
  1890 
  1909 
  1891 	/* adjust it a little to make it less profitable to sell and buy */
  1910 	/* adjust it a little to make it less profitable to sell and buy */
  1892 	cost = CalculateCompanyValue(p) >> 2;
  1911 	cost = CalculateCompanyValue(p) >> 2;
  1896 		PlayerByte* b = p->share_owners;
  1915 		PlayerByte* b = p->share_owners;
  1897 		while (*b != _current_player) b++; // share owners is guaranteed to contain player
  1916 		while (*b != _current_player) b++; // share owners is guaranteed to contain player
  1898 		*b = PLAYER_SPECTATOR;
  1917 		*b = PLAYER_SPECTATOR;
  1899 		InvalidateWindow(WC_COMPANY, p1);
  1918 		InvalidateWindow(WC_COMPANY, p1);
  1900 	}
  1919 	}
  1901 	return CommandCost(cost);
  1920 	return CommandCost(EXPENSES_OTHER, cost);
  1902 }
  1921 }
  1903 
  1922 
  1904 /** Buy up another company.
  1923 /** Buy up another company.
  1905  * When a competing company is gone bankrupt you get the chance to purchase
  1924  * When a competing company is gone bankrupt you get the chance to purchase
  1906  * that company.
  1925  * that company.
  1919 	if (!IsValidPlayer(pid) || _networking) return CMD_ERROR;
  1938 	if (!IsValidPlayer(pid) || _networking) return CMD_ERROR;
  1920 
  1939 
  1921 	/* Do not allow players to take over themselves */
  1940 	/* Do not allow players to take over themselves */
  1922 	if (pid == _current_player) return CMD_ERROR;
  1941 	if (pid == _current_player) return CMD_ERROR;
  1923 
  1942 
  1924 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
  1925 	p = GetPlayer(pid);
  1943 	p = GetPlayer(pid);
  1926 
  1944 
  1927 	if (!p->is_ai) return CMD_ERROR;
  1945 	if (!p->is_ai) return CMD_ERROR;
  1928 
  1946 
  1929 	if (flags & DC_EXEC) {
  1947 	if (flags & DC_EXEC) {
  1930 		DoAcquireCompany(p);
  1948 		DoAcquireCompany(p);
  1931 	}
  1949 	}
  1932 	return CommandCost(p->bankrupt_value);
  1950 	return CommandCost(EXPENSES_OTHER, p->bankrupt_value);
  1933 }
  1951 }
  1934 
  1952 
  1935 /** Prices */
  1953 /** Prices */
  1936 static void SaveLoad_PRIC()
  1954 static void SaveLoad_PRIC()
  1937 {
  1955 {