src/players.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 10184 fcf5fb2548eb
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     3 /** @file players.cpp
     3 /** @file players.cpp
     4  */
     4  */
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "engine.h"
     7 #include "engine.h"
     8 #include "functions.h"
     8 #include "player_func.h"
     9 #include "string.h"
     9 #include "player_gui.h"
    10 #include "strings.h"
       
    11 #include "table/strings.h"
       
    12 #include "table/sprites.h"
       
    13 #include "map.h"
       
    14 #include "player.h"
       
    15 #include "town.h"
    10 #include "town.h"
    16 #include "vehicle.h"
       
    17 #include "station.h"
    11 #include "station.h"
    18 #include "gfx.h"
       
    19 #include "news.h"
    12 #include "news.h"
    20 #include "saveload.h"
    13 #include "saveload.h"
    21 #include "command.h"
    14 #include "command_func.h"
    22 #include "sound.h"
       
    23 #include "network/network.h"
    15 #include "network/network.h"
       
    16 #include "network/network_internal.h"
    24 #include "variables.h"
    17 #include "variables.h"
    25 #include "engine.h"
    18 #include "engine.h"
    26 #include "ai/ai.h"
    19 #include "ai/ai.h"
    27 #include "date.h"
       
    28 #include "window.h"
       
    29 #include "player_face.h"
    20 #include "player_face.h"
    30 #include "group.h"
    21 #include "group.h"
    31 #include "settings.h"
    22 #include "window_func.h"
       
    23 #include "tile_map.h"
       
    24 #include "strings_func.h"
       
    25 #include "gfx_func.h"
       
    26 #include "functions.h"
       
    27 #include "date_func.h"
       
    28 #include "vehicle_func.h"
       
    29 #include "sound_func.h"
       
    30 #include "autoreplace_func.h"
       
    31 #include "autoreplace_gui.h"
       
    32 #include "string_func.h"
       
    33 #include "ai/default/default.h"
       
    34 #include "ai/trolly/trolly.h"
       
    35 #include "road_func.h"
       
    36 #include "rail.h"
       
    37 
       
    38 #include "table/strings.h"
       
    39 #include "table/sprites.h"
       
    40 
       
    41 Player _players[MAX_PLAYERS];
       
    42 PlayerByte _local_player;
       
    43 PlayerByte _current_player;
       
    44 /* NOSAVE: can be determined from player structs */
       
    45 byte _player_colors[MAX_PLAYERS];
       
    46 PlayerFace _player_face; ///< for player face storage in openttd.cfg
       
    47 HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
    32 
    48 
    33 /**
    49 /**
    34  * Sets the local player and updates the patch settings that are set on a
    50  * Sets the local player and updates the patch settings that are set on a
    35  * per-company (player) basis to reflect the core's state in the GUI.
    51  * per-company (player) basis to reflect the core's state in the GUI.
    36  * @param new_player the new player
    52  * @param new_player the new player
    49 		_patches.autorenew        = p->engine_renew;
    65 		_patches.autorenew        = p->engine_renew;
    50 		_patches.autorenew_months = p->engine_renew_months;
    66 		_patches.autorenew_months = p->engine_renew_months;
    51 		_patches.autorenew_money  = p->engine_renew_money;
    67 		_patches.autorenew_money  = p->engine_renew_money;
    52 		InvalidateWindow(WC_GAME_OPTIONS, 0);
    68 		InvalidateWindow(WC_GAME_OPTIONS, 0);
    53 	}
    69 	}
       
    70 }
       
    71 
       
    72 bool IsHumanPlayer(PlayerID pi)
       
    73 {
       
    74 	return !GetPlayer(pi)->is_ai;
    54 }
    75 }
    55 
    76 
    56 
    77 
    57 uint16 GetDrawStringPlayerColor(PlayerID player)
    78 uint16 GetDrawStringPlayerColor(PlayerID player)
    58 {
    79 {
   187 	return true;
   208 	return true;
   188 }
   209 }
   189 
   210 
   190 static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost)
   211 static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost)
   191 {
   212 {
   192 	CommandCost tmp(p->player_money);
   213 	if (cost.GetCost() == 0) return;
   193 	tmp.AddCost(-cost.GetCost());
   214 	assert(cost.GetExpensesType() != INVALID_EXPENSES);
   194 	p->player_money = tmp.GetCost();
   215 
   195 
   216 	p->player_money -= cost.GetCost();
   196 	tmp = CommandCost(p->yearly_expenses[0][_yearly_expenses_type]);
   217 	p->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();
   197 	tmp.AddCost(cost);
       
   198 	p->yearly_expenses[0][_yearly_expenses_type] = tmp.GetCost();
       
   199 
   218 
   200 	if (HasBit(1 << EXPENSES_TRAIN_INC    |
   219 	if (HasBit(1 << EXPENSES_TRAIN_INC    |
   201 	           1 << EXPENSES_ROADVEH_INC  |
   220 	           1 << EXPENSES_ROADVEH_INC  |
   202 	           1 << EXPENSES_AIRCRAFT_INC |
   221 	           1 << EXPENSES_AIRCRAFT_INC |
   203 	           1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
   222 	           1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
   204 		tmp = CommandCost(p->cur_economy.income);
   223 		p->cur_economy.income -= cost.GetCost();
   205 		tmp.AddCost(-cost.GetCost());
       
   206 		p->cur_economy.income = tmp.GetCost();
       
   207 	} else if (HasBit(1 << EXPENSES_TRAIN_RUN    |
   224 	} else if (HasBit(1 << EXPENSES_TRAIN_RUN    |
   208 	                  1 << EXPENSES_ROADVEH_RUN  |
   225 	                  1 << EXPENSES_ROADVEH_RUN  |
   209 	                  1 << EXPENSES_AIRCRAFT_RUN |
   226 	                  1 << EXPENSES_AIRCRAFT_RUN |
   210 	                  1 << EXPENSES_SHIP_RUN     |
   227 	                  1 << EXPENSES_SHIP_RUN     |
   211 	                  1 << EXPENSES_PROPERTY     |
   228 	                  1 << EXPENSES_PROPERTY     |
   212 	                  1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) {
   229 	                  1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
   213 		tmp = CommandCost(p->cur_economy.expenses);
   230 		p->cur_economy.expenses -= cost.GetCost();
   214 		tmp.AddCost(-cost.GetCost());
       
   215 		p->cur_economy.expenses = tmp.GetCost();
       
   216 	}
   231 	}
   217 
   232 
   218 	InvalidatePlayerWindows(p);
   233 	InvalidatePlayerWindows(p);
   219 }
   234 }
   220 
   235 
   232 	Money cost = cst.GetCost();
   247 	Money cost = cst.GetCost();
   233 
   248 
   234 	p->player_money_fraction = m - (byte)cost;
   249 	p->player_money_fraction = m - (byte)cost;
   235 	cost >>= 8;
   250 	cost >>= 8;
   236 	if (p->player_money_fraction > m) cost++;
   251 	if (p->player_money_fraction > m) cost++;
   237 	if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cost));
   252 	if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cst.GetExpensesType(), cost));
   238 }
   253 }
   239 
   254 
   240 void GetNameOfOwner(Owner owner, TileIndex tile)
   255 void GetNameOfOwner(Owner owner, TileIndex tile)
   241 {
   256 {
   242 	SetDParam(2, owner);
   257 	SetDParam(2, owner);
   438 	/* Find a free slot */
   453 	/* Find a free slot */
   439 	FOR_ALL_PLAYERS(p) {
   454 	FOR_ALL_PLAYERS(p) {
   440 		if (!p->is_active) {
   455 		if (!p->is_active) {
   441 			PlayerID i = p->index;
   456 			PlayerID i = p->index;
   442 			memset(p, 0, sizeof(Player));
   457 			memset(p, 0, sizeof(Player));
       
   458 			memset(&_players_ai[i], 0, sizeof(PlayerAI));
       
   459 			memset(&_players_ainew[i], 0, sizeof(PlayerAiNew));
   443 			p->index = i;
   460 			p->index = i;
   444 			return p;
   461 			return p;
   445 		}
   462 		}
   446 	}
   463 	}
   447 	return NULL;
   464 	return NULL;
   477 	p->is_active = true;
   494 	p->is_active = true;
   478 
   495 
   479 	p->player_money = p->current_loan = 100000;
   496 	p->player_money = p->current_loan = 100000;
   480 
   497 
   481 	p->is_ai = is_ai;
   498 	p->is_ai = is_ai;
   482 	p->ai.state = 5; // AIS_WANT_NEW_ROUTE
   499 	_players_ai[p->index].state = 5; // AIS_WANT_NEW_ROUTE
   483 	p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
   500 	p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
   484 
   501 
   485 	p->avail_railtypes = GetPlayerRailtypes(p->index);
   502 	p->avail_railtypes = GetPlayerRailtypes(p->index);
   486 	p->avail_roadtypes = GetPlayerRoadtypes(p->index);
   503 	p->avail_roadtypes = GetPlayerRoadtypes(p->index);
   487 	p->inaugurated_year = _cur_year;
   504 	p->inaugurated_year = _cur_year;
   542 }
   559 }
   543 
   560 
   544 void InitializePlayers()
   561 void InitializePlayers()
   545 {
   562 {
   546 	memset(_players, 0, sizeof(_players));
   563 	memset(_players, 0, sizeof(_players));
   547 	for (PlayerID i = PLAYER_FIRST; i != MAX_PLAYERS; i++) _players[i].index = i;
   564 	for (PlayerID i = PLAYER_FIRST; i != MAX_PLAYERS; i++) {
       
   565 		_players[i].index = i;
       
   566 		for (uint j = 0; j < 4; j++) _players[i].share_owners[j] = PLAYER_SPECTATOR;
       
   567 	}
   548 	_cur_player_tick_index = 0;
   568 	_cur_player_tick_index = 0;
   549 }
   569 }
   550 
   570 
   551 void OnTick_Players()
   571 void OnTick_Players()
   552 {
   572 {
   586 			SndPlayFx(SND_00_GOOD_YEAR);
   606 			SndPlayFx(SND_00_GOOD_YEAR);
   587 		}
   607 		}
   588 	}
   608 	}
   589 }
   609 }
   590 
   610 
   591 byte GetPlayerRailtypes(PlayerID p)
       
   592 {
       
   593 	byte rt = 0;
       
   594 	EngineID i;
       
   595 
       
   596 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
       
   597 		const Engine* e = GetEngine(i);
       
   598 		const EngineInfo *ei = EngInfo(i);
       
   599 
       
   600 		if (e->type == VEH_TRAIN && HasBit(ei->climates, _opt.landscape) &&
       
   601 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
       
   602 			const RailVehicleInfo *rvi = RailVehInfo(i);
       
   603 
       
   604 			if (rvi->railveh_type != RAILVEH_WAGON) {
       
   605 				assert(rvi->railtype < RAILTYPE_END);
       
   606 				SetBit(rt, rvi->railtype);
       
   607 			}
       
   608 		}
       
   609 	}
       
   610 
       
   611 	return rt;
       
   612 }
       
   613 
       
   614 byte GetPlayerRoadtypes(PlayerID p)
       
   615 {
       
   616 	byte rt = 0;
       
   617 	EngineID i;
       
   618 
       
   619 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
       
   620 		const Engine* e = GetEngine(i);
       
   621 		const EngineInfo *ei = EngInfo(i);
       
   622 
       
   623 		if (e->type == VEH_ROAD && HasBit(ei->climates, _opt.landscape) &&
       
   624 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
       
   625 			SetBit(rt, HasBit(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
       
   626 		}
       
   627 	}
       
   628 
       
   629 	return rt;
       
   630 }
       
   631 
       
   632 static void DeletePlayerStuff(PlayerID pi)
   611 static void DeletePlayerStuff(PlayerID pi)
   633 {
   612 {
   634 	Player *p;
   613 	Player *p;
   635 
   614 
   636 	DeletePlayerWindows(pi);
   615 	DeletePlayerWindows(pi);
   637 	p = GetPlayer(pi);
   616 	p = GetPlayer(pi);
   638 	DeleteName(p->name_1);
   617 	p->name_1 = STR_NULL;
   639 	DeleteName(p->president_name_1);
   618 	p->president_name_1 = STR_NULL;
   640 	p->name_1 = 0;
   619 	free(p->name);
   641 	p->president_name_1 = 0;
   620 	free(p->president_name);
       
   621 	p->name = NULL;
       
   622 	p->president_name = NULL;
   642 }
   623 }
   643 
   624 
   644 /** Change engine renewal parameters
   625 /** Change engine renewal parameters
   645  * @param tile unused
   626  * @param tile unused
   646  * @param flags operation to perform
   627  * @param flags operation to perform
   846 
   827 
   847 		/* This is the joining client who wants a new company */
   828 		/* This is the joining client who wants a new company */
   848 		if (_local_player != _network_playas && _network_playas == p->index) {
   829 		if (_local_player != _network_playas && _network_playas == p->index) {
   849 			assert(_local_player == PLAYER_SPECTATOR);
   830 			assert(_local_player == PLAYER_SPECTATOR);
   850 			SetLocalPlayer(p->index);
   831 			SetLocalPlayer(p->index);
       
   832 #ifdef ENABLE_NETWORK
   851 			if (!StrEmpty(_network_default_company_pass)) {
   833 			if (!StrEmpty(_network_default_company_pass)) {
   852 				char *password = _network_default_company_pass;
   834 				char *password = _network_default_company_pass;
   853 				NetworkChangeCompanyPassword(1, &password);
   835 				NetworkChangeCompanyPassword(1, &password);
   854 			}
   836 			}
       
   837 #endif /* ENABLE_NETWORK */
   855 			MarkWholeScreenDirty();
   838 			MarkWholeScreenDirty();
   856 		}
   839 		}
   857 
   840 
   858 		/* Now that we have a new player, broadcast its autorenew settings to
   841 		/* Now that we have a new player, broadcast its autorenew settings to
   859 		 * all clients so everything is in sync */
   842 		 * all clients so everything is in sync */
   924 			/* Remove the company */
   907 			/* Remove the company */
   925 			ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
   908 			ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
   926 			p->is_active = false;
   909 			p->is_active = false;
   927 		}
   910 		}
   928 		RemoveAllEngineReplacementForPlayer(p);
   911 		RemoveAllEngineReplacementForPlayer(p);
   929 		RemoveAllGroupsForPlayer(p);
   912 		RemoveAllGroupsForPlayer(p->index);
   930 
   913 
   931 	} break;
   914 	} break;
   932 
   915 
   933 	case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
   916 	case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
   934 		PlayerID pid_old = (PlayerID)GB(p2,  0, 16);
   917 		PlayerID pid_old = (PlayerID)GB(p2,  0, 16);
  1115 
  1098 
  1116 /* Save/load of players */
  1099 /* Save/load of players */
  1117 static const SaveLoad _player_desc[] = {
  1100 static const SaveLoad _player_desc[] = {
  1118 	    SLE_VAR(Player, name_2,          SLE_UINT32),
  1101 	    SLE_VAR(Player, name_2,          SLE_UINT32),
  1119 	    SLE_VAR(Player, name_1,          SLE_STRINGID),
  1102 	    SLE_VAR(Player, name_1,          SLE_STRINGID),
       
  1103 	SLE_CONDSTR(Player, name,            SLE_STR, 0,                       84, SL_MAX_VERSION),
  1120 
  1104 
  1121 	    SLE_VAR(Player, president_name_1,SLE_UINT16),
  1105 	    SLE_VAR(Player, president_name_1,SLE_UINT16),
  1122 	    SLE_VAR(Player, president_name_2,SLE_UINT32),
  1106 	    SLE_VAR(Player, president_name_2,SLE_UINT32),
       
  1107 	SLE_CONDSTR(Player, president_name,  SLE_STR, 0,                       84, SL_MAX_VERSION),
  1123 
  1108 
  1124 	    SLE_VAR(Player, face,            SLE_UINT32),
  1109 	    SLE_VAR(Player, face,            SLE_UINT32),
  1125 
  1110 
  1126 	/* money was changed to a 64 bit field in savegame version 1. */
  1111 	/* money was changed to a 64 bit field in savegame version 1. */
  1127 	SLE_CONDVAR(Player, player_money,          SLE_VAR_I64 | SLE_FILE_I32,  0, 0),
  1112 	SLE_CONDVAR(Player, player_money,          SLE_VAR_I64 | SLE_FILE_I32,  0, 0),
  1187 	    SLE_VAR(PlayerEconomyEntry, performance_history, SLE_INT32),
  1172 	    SLE_VAR(PlayerEconomyEntry, performance_history, SLE_INT32),
  1188 
  1173 
  1189 	SLE_END()
  1174 	SLE_END()
  1190 };
  1175 };
  1191 
  1176 
  1192 static const SaveLoad _player_ai_desc[] = {
       
  1193 	    SLE_VAR(PlayerAI, state,             SLE_UINT8),
       
  1194 	    SLE_VAR(PlayerAI, tick,              SLE_UINT8),
       
  1195 	SLE_CONDVAR(PlayerAI, state_counter,     SLE_FILE_U16 | SLE_VAR_U32,  0, 12),
       
  1196 	SLE_CONDVAR(PlayerAI, state_counter,     SLE_UINT32,                 13, SL_MAX_VERSION),
       
  1197 	    SLE_VAR(PlayerAI, timeout_counter,   SLE_UINT16),
       
  1198 
       
  1199 	    SLE_VAR(PlayerAI, state_mode,        SLE_UINT8),
       
  1200 	    SLE_VAR(PlayerAI, banned_tile_count, SLE_UINT8),
       
  1201 	    SLE_VAR(PlayerAI, railtype_to_use,   SLE_UINT8),
       
  1202 
       
  1203 	    SLE_VAR(PlayerAI, cargo_type,        SLE_UINT8),
       
  1204 	    SLE_VAR(PlayerAI, num_wagons,        SLE_UINT8),
       
  1205 	    SLE_VAR(PlayerAI, build_kind,        SLE_UINT8),
       
  1206 	    SLE_VAR(PlayerAI, num_build_rec,     SLE_UINT8),
       
  1207 	    SLE_VAR(PlayerAI, num_loco_to_build, SLE_UINT8),
       
  1208 	    SLE_VAR(PlayerAI, num_want_fullload, SLE_UINT8),
       
  1209 
       
  1210 	    SLE_VAR(PlayerAI, route_type_mask,   SLE_UINT8),
       
  1211 
       
  1212 	SLE_CONDVAR(PlayerAI, start_tile_a,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
       
  1213 	SLE_CONDVAR(PlayerAI, start_tile_a,      SLE_UINT32,                  6, SL_MAX_VERSION),
       
  1214 	SLE_CONDVAR(PlayerAI, cur_tile_a,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
       
  1215 	SLE_CONDVAR(PlayerAI, cur_tile_a,        SLE_UINT32,                  6, SL_MAX_VERSION),
       
  1216 	    SLE_VAR(PlayerAI, start_dir_a,       SLE_UINT8),
       
  1217 	    SLE_VAR(PlayerAI, cur_dir_a,         SLE_UINT8),
       
  1218 
       
  1219 	SLE_CONDVAR(PlayerAI, start_tile_b,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
       
  1220 	SLE_CONDVAR(PlayerAI, start_tile_b,      SLE_UINT32,                  6, SL_MAX_VERSION),
       
  1221 	SLE_CONDVAR(PlayerAI, cur_tile_b,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
       
  1222 	SLE_CONDVAR(PlayerAI, cur_tile_b,        SLE_UINT32,                  6, SL_MAX_VERSION),
       
  1223 	    SLE_VAR(PlayerAI, start_dir_b,       SLE_UINT8),
       
  1224 	    SLE_VAR(PlayerAI, cur_dir_b,         SLE_UINT8),
       
  1225 
       
  1226 	    SLE_REF(PlayerAI, cur_veh,           REF_VEHICLE),
       
  1227 
       
  1228 	    SLE_ARR(PlayerAI, wagon_list,        SLE_UINT16, 9),
       
  1229 	    SLE_ARR(PlayerAI, order_list_blocks, SLE_UINT8, 20),
       
  1230 	    SLE_ARR(PlayerAI, banned_tiles,      SLE_UINT16, 16),
       
  1231 
       
  1232 	SLE_CONDNULL(64, 2, SL_MAX_VERSION),
       
  1233 	SLE_END()
       
  1234 };
       
  1235 
       
  1236 static const SaveLoad _player_ai_build_rec_desc[] = {
       
  1237 	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
       
  1238 	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_UINT32,                 6, SL_MAX_VERSION),
       
  1239 	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
       
  1240 	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
       
  1241 	    SLE_VAR(AiBuildRec, rand_rng,          SLE_UINT8),
       
  1242 	    SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
       
  1243 	    SLE_VAR(AiBuildRec, unk6,              SLE_UINT8),
       
  1244 	    SLE_VAR(AiBuildRec, unk7,              SLE_UINT8),
       
  1245 	    SLE_VAR(AiBuildRec, buildcmd_a,        SLE_UINT8),
       
  1246 	    SLE_VAR(AiBuildRec, buildcmd_b,        SLE_UINT8),
       
  1247 	    SLE_VAR(AiBuildRec, direction,         SLE_UINT8),
       
  1248 	    SLE_VAR(AiBuildRec, cargo,             SLE_UINT8),
       
  1249 	SLE_END()
       
  1250 };
       
  1251 
       
  1252 static const SaveLoad _player_livery_desc[] = {
  1177 static const SaveLoad _player_livery_desc[] = {
  1253 	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
  1178 	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
  1254 	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
  1179 	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
  1255 	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
  1180 	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
  1256 	SLE_END()
  1181 	SLE_END()
  1262 
  1187 
  1263 	SlObject(p, _player_desc);
  1188 	SlObject(p, _player_desc);
  1264 
  1189 
  1265 	/* Write AI? */
  1190 	/* Write AI? */
  1266 	if (!IsHumanPlayer(p->index)) {
  1191 	if (!IsHumanPlayer(p->index)) {
  1267 		SlObject(&p->ai, _player_ai_desc);
  1192 		SaveLoad_AI(p->index);
  1268 		for (i = 0; i != p->ai.num_build_rec; i++) {
       
  1269 			SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
       
  1270 		}
       
  1271 	}
  1193 	}
  1272 
  1194 
  1273 	/* Write economy */
  1195 	/* Write economy */
  1274 	SlObject(&p->cur_economy, _player_economy_desc);
  1196 	SlObject(&p->cur_economy, _player_economy_desc);
  1275 
  1197 
  1277 	for (i = 0; i < p->num_valid_stat_ent; i++) {
  1199 	for (i = 0; i < p->num_valid_stat_ent; i++) {
  1278 		SlObject(&p->old_economy[i], _player_economy_desc);
  1200 		SlObject(&p->old_economy[i], _player_economy_desc);
  1279 	}
  1201 	}
  1280 
  1202 
  1281 	/* Write each livery entry. */
  1203 	/* Write each livery entry. */
  1282 	int num_liveries = CheckSavegameVersion(63) ? LS_END - 2 : LS_END;
  1204 	int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
  1283 	for (i = 0; i < num_liveries; i++) {
  1205 	for (i = 0; i < num_liveries; i++) {
  1284 		SlObject(&p->livery[i], _player_livery_desc);
  1206 		SlObject(&p->livery[i], _player_livery_desc);
  1285 	}
  1207 	}
  1286 
  1208 
  1287 	if (num_liveries == LS_END - 2) {
  1209 	if (num_liveries < LS_END) {
       
  1210 		/* We want to insert some liveries somewhere in between. This means some have to be moved. */
       
  1211 		memmove(&p->livery[LS_FREIGHT_WAGON], &p->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(p->livery[0]));
       
  1212 		p->livery[LS_PASSENGER_WAGON_MONORAIL] = p->livery[LS_MONORAIL];
       
  1213 		p->livery[LS_PASSENGER_WAGON_MAGLEV]   = p->livery[LS_MAGLEV];
       
  1214 	}
       
  1215 
       
  1216 	if (num_liveries == LS_END - 4) {
  1288 		/* Copy bus/truck liveries over to trams */
  1217 		/* Copy bus/truck liveries over to trams */
  1289 		p->livery[LS_PASSENGER_TRAM] = p->livery[LS_BUS];
  1218 		p->livery[LS_PASSENGER_TRAM] = p->livery[LS_BUS];
  1290 		p->livery[LS_FREIGHT_TRAM]   = p->livery[LS_TRUCK];
  1219 		p->livery[LS_FREIGHT_TRAM]   = p->livery[LS_TRUCK];
  1291 	}
  1220 	}
  1292 }
  1221 }