From ed8e2bac048a6c4ba73e226b7a8332759bab0697 Mon Sep 17 00:00:00 2001 From: bjarni Date: Sat, 6 Aug 2005 16:07:22 +0000 Subject: (svn r2817) -Codechange: [autoreplace]: moved autoreplace and autorenew to serverside -This means that one company can only have one setting for renew and replacing more clients will not fight due to different settings anymore -This is a needed step in the line to fix autoreplacing dualheaded locomotives NOTE: savegame revision bump (peter1138 + me in coop) --- aircraft_cmd.c | 10 ++-- misc.c | 6 --- network_client.c | 3 ++ openttd.c | 21 +++++++++ player.h | 4 ++ players.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++- railtypes.h | 2 +- saveload.c | 2 +- settings_gui.c | 24 ++++++++-- tunnelbridge_cmd.c | 2 +- variables.h | 3 -- vehicle.c | 82 ++++++++++++++------------------- vehicle.h | 1 + vehicle_gui.c | 20 ++++---- 14 files changed, 235 insertions(+), 76 deletions(-) diff --git a/aircraft_cmd.c b/aircraft_cmd.c index aba653d36..ddb074f71 100644 --- a/aircraft_cmd.c +++ b/aircraft_cmd.c @@ -1523,14 +1523,15 @@ static void AircraftEventHandler_EndTakeOff(Vehicle *v, const AirportFTAClass *A static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *Airport) { + Player *p = GetPlayer(v->owner); v->sprite_width = v->sprite_height = 24; // ??? no idea what this is v->u.air.state = FLYING; // get the next position to go to, differs per airport AircraftNextAirportPos_and_Order(v); // check if the aircraft needs to be replaced or renewed and send it to a hangar if needed - if ((v->owner == _local_player && _autoreplace_array[v->engine_type] != v->engine_type) || - (v->owner == _local_player && _patches.autorenew && v->age - v->max_age > (_patches.autorenew_months * 30))) { + if ((v->owner == _local_player && p->engine_replacement[v->engine_type] != v->engine_type) || + (v->owner == _local_player && p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) { _current_player = _local_player; DoCommandP(v->tile, v->index, 1, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR); _current_player = OWNER_NONE; @@ -1586,13 +1587,14 @@ static void AircraftEventHandler_Flying(Vehicle *v, const AirportFTAClass *Airpo static void AircraftEventHandler_Landing(Vehicle *v, const AirportFTAClass *Airport) { + Player *p = GetPlayer(v->owner); AircraftLandAirplane(v); // maybe crash airplane v->u.air.state = ENDLANDING; // check if the aircraft needs to be replaced or renewed and send it to a hangar if needed if (v->current_order.type != OT_GOTO_DEPOT && v->owner == _local_player) { // only the vehicle owner needs to calculate the rest (locally) - if ((_autoreplace_array[v->engine_type] != v->engine_type) || - (_patches.autorenew && v->age - v->max_age > (_patches.autorenew_months * 30))) { + if ((p->engine_replacement[v->engine_type] != v->engine_type) || + (p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) { // send the aircraft to the hangar at next airport (bit 17 set) _current_player = _local_player; DoCommandP(v->tile, v->index, 1 << 16, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR); diff --git a/misc.c b/misc.c index 5e4b7ff46..9e32bd0d6 100644 --- a/misc.c +++ b/misc.c @@ -122,14 +122,8 @@ void ConvertGroundTilesIntoWaterTiles(void); void InitializeGame(uint size_x, uint size_y) { - uint i; - AllocateMap(size_x, size_y); - // Initialize the autoreplace array. Needs to be cleared between each game - for (i = 0; i < lengthof(_autoreplace_array); i++) - _autoreplace_array[i] = i; - AddTypeToEngines(); // make sure all engines have a type SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0); diff --git a/network_client.c b/network_client.c index 2f7af9087..b64e8358f 100644 --- a/network_client.c +++ b/network_client.c @@ -527,6 +527,9 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP) } else { // take control over an existing company _local_player = _network_playas - 1; + _patches.autorenew = GetPlayer(_local_player)->engine_renew; + _patches.autorenew_months = GetPlayer(_local_player)->engine_renew_months; + _patches.autorenew_money = GetPlayer(_local_player)->engine_renew_money; DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); } } diff --git a/openttd.c b/openttd.c index 4388866be..69849c7e6 100644 --- a/openttd.c +++ b/openttd.c @@ -579,6 +579,8 @@ static void MakeNewGame(void) DoStartupNewPlayer(false); _local_player = 0; + _current_player = _local_player; + DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_REPLACE_VEHICLE); } MarkWholeScreenDirty(); @@ -651,6 +653,8 @@ static void StartScenario(void) StartupDisasters(); _local_player = 0; + _current_player = _local_player; + DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_REPLACE_VEHICLE); MarkWholeScreenDirty(); } @@ -1242,6 +1246,23 @@ bool AfterLoadGame(uint version) } END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0); } + if (version < 0x1000) { + int i; + FOR_ALL_PLAYERS(p) { + for (i = 0; i < 256; i++) { + p->engine_replacement[i] = INVALID_ENGINE; + } + p->engine_renew = false; + p->engine_renew_months = -6; + p->engine_renew_money = 100000; + } + // Set the human controlled player to the patch settings + p = GetPlayer(_local_player); + p->engine_renew = _patches.autorenew; + p->engine_renew_months = _patches.autorenew_months; + p->engine_renew_money = _patches.autorenew_money; + } + FOR_ALL_PLAYERS(p) { p->avail_railtypes = GetPlayerRailtypes(p->index); } diff --git a/player.h b/player.h index 4b1939a6c..6517d0d2d 100644 --- a/player.h +++ b/player.h @@ -187,6 +187,10 @@ typedef struct Player { int64 yearly_expenses[3][13]; PlayerEconomyEntry cur_economy; PlayerEconomyEntry old_economy[24]; + EngineID engine_replacement[256]; + bool engine_renew; + int16 engine_renew_months; + uint32 engine_renew_money; } Player; void ChangeOwnershipOfPlayerItems(byte old_player, byte new_player); diff --git a/players.c b/players.c index 5727ce353..3502019bf 100644 --- a/players.c +++ b/players.c @@ -474,7 +474,7 @@ static Player *AllocatePlayer(void) Player *DoStartupNewPlayer(bool is_ai) { Player *p; - int index; + int index, i; p = AllocatePlayer(); if (p == NULL) return NULL; @@ -497,6 +497,14 @@ Player *DoStartupNewPlayer(bool is_ai) p->inaugurated_year = _cur_year; p->face = Random(); + /* Engine renewal settings */ + for (i = 0; i < 256; i++) + p->engine_replacement[i] = INVALID_ENGINE; + + p->engine_renew = false; + p->engine_renew_months = -6; + p->engine_renew_money = 100000; + GeneratePresidentName(p); InvalidateWindow(WC_GRAPH_LEGEND, 0); @@ -661,6 +669,119 @@ static void DeletePlayerStuff(int pi) p->president_name_1 = 0; } +/** Change engine renewal parameters + * @param x,y unused + * @param p1 bits 0-3 command + * - p1 = 0 - change auto renew bool + * - p1 = 1 - change auto renew months + * - p1 = 2 - change auto renew money + * - p1 = 3 - change auto renew array + * - p1 = 4 - change bool, months & money all together + * @param p2 value to set + * if p1 = 0, then: + * - p2 = enable engine renewal + * if p1 = 1, then: + * - p2 = months left before engine expires to replace it + * if p1 = 2, then + * - p2 = minimum amount of money available + * if p1 = 3, then: + * - p2 bits 0-15 = old engine type + * - p2 bits 16-31 = new engine type + * if p1 = 4, then: + * - p1 bit 15 = enable engine renewal + * - p1 bits 16-31 = months left before engine expires to replace it + * - p2 bits 0-31 = minimum amount of money available + */ +int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) +{ + Player *p; + if (!(_current_player < MAX_PLAYERS)) + return CMD_ERROR; + + p = GetPlayer(_current_player); + switch (GB(p1, 0, 3)) { + case 0: + if (p->engine_renew == (bool)GB(p2, 0, 1)) + return CMD_ERROR; + + if (flags & DC_EXEC) { + p->engine_renew = (bool)GB(p2, 0, 1); + if (_current_player == _local_player) { + _patches.autorenew = p->engine_renew; + InvalidateWindow(WC_GAME_OPTIONS, 0); + } + } + break; + case 1: + if (p->engine_renew_months == (int16)p2) + return CMD_ERROR; + + if (flags & DC_EXEC) { + p->engine_renew_months = (int16)p2; + if (_current_player == _local_player) { + _patches.autorenew_months = p->engine_renew_months; + InvalidateWindow(WC_GAME_OPTIONS, 0); + } + } + break; + case 2: + if (p->engine_renew_money == (uint32)p2) + return CMD_ERROR; + + if (flags & DC_EXEC) { + p->engine_renew_money = (uint32)p2; + if (_current_player == _local_player) { + _patches.autorenew_money = p->engine_renew_money; + InvalidateWindow(WC_GAME_OPTIONS, 0); + } + } + break; + case 3: { + EngineID old_engine_type = GB(p2, 0, 16); + EngineID new_engine_type = GB(p2, 16, 16); + + if (new_engine_type != INVALID_ENGINE) { + /* First we make sure that it's a valid type the user requested + * check that it's an engine that is in the engine array */ + if(!IsEngineIndex(new_engine_type)) + return CMD_ERROR; + + // check that the new vehicle type is the same as the original one + if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type) + return CMD_ERROR; + + // make sure that we do not replace a plane with a helicopter or vise versa + if (GetEngine(new_engine_type)->type == VEH_Aircraft && HASBIT(AircraftVehInfo(old_engine_type)->subtype, 0) != HASBIT(AircraftVehInfo(new_engine_type)->subtype, 0)) + return CMD_ERROR; + + // make sure that the player can actually buy the new engine + if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player)) + return CMD_ERROR; + } + + if (flags & DC_EXEC) { + p->engine_replacement[old_engine_type] = new_engine_type; + } + } break; + case 4: + if (flags & DC_EXEC) { + p->engine_renew = (bool)GB(p1, 15, 1); + p->engine_renew_months = (int16)GB(p1, 16, 16); + p->engine_renew_money = (uint32)p2; + + if (_current_player == _local_player) { + _patches.autorenew = p->engine_renew; + _patches.autorenew_months = p->engine_renew_months; + _patches.autorenew_money = p->engine_renew_money; + InvalidateWindow(WC_GAME_OPTIONS, 0); + } + } + break; + } + + return 0; +} + /** Control the players: add, delete, etc. * @param x,y unused * @param p1 various functionality @@ -706,6 +827,8 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2) _local_player = p->index; MarkWholeScreenDirty(); } + } else if (p->index == _local_player) { + DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_REPLACE_VEHICLE); } #ifdef ENABLE_NETWORK if (_network_server) { @@ -1022,6 +1145,12 @@ static const SaveLoad _player_desc[] = { SLE_CONDVAR(Player,is_ai, SLE_UINT8, 2, 255), SLE_CONDVAR(Player,is_active, SLE_UINT8, 4, 255), + // Engine renewal settings + SLE_CONDARR(Player,engine_replacement, SLE_UINT16, 256, 16, 255), + SLE_CONDVAR(Player,engine_renew, SLE_UINT8, 16, 255), + SLE_CONDVAR(Player,engine_renew_months, SLE_INT16, 16, 255), + SLE_CONDVAR(Player,engine_renew_money, SLE_UINT32, 16, 255), + // reserve extra space in savegame here. (currently 64 bytes) SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 8, 2, 255), diff --git a/railtypes.h b/railtypes.h index 9375d2a14..74cd0768f 100644 --- a/railtypes.h +++ b/railtypes.h @@ -24,7 +24,7 @@ const RailtypeInfo _railtypes[RAILTYPE_END] = { /* Compatible railtypes */ (1 << RAILTYPE_RAIL), - + /* main offset */ 0, }, diff --git a/saveload.c b/saveload.c index 73928c0c6..54f73b3e8 100644 --- a/saveload.c +++ b/saveload.c @@ -28,7 +28,7 @@ #include "variables.h" enum { - SAVEGAME_MAJOR_VERSION = 15, + SAVEGAME_MAJOR_VERSION = 16, SAVEGAME_MINOR_VERSION = 0, SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION diff --git a/settings_gui.c b/settings_gui.c index 6d50c7259..8fce9348e 100644 --- a/settings_gui.c +++ b/settings_gui.c @@ -618,6 +618,24 @@ static int32 CheckInterval(int32 p1) return InValidateDetailsWindow(0); } +static int32 EngineRenewUpdate(int32 p1) +{ + DoCommandP(0, 0, _patches.autorenew, NULL, CMD_REPLACE_VEHICLE); + return 0; +} + +static int32 EngineRenewMonthsUpdate(int32 p1) +{ + DoCommandP(0, 1, _patches.autorenew_months, NULL, CMD_REPLACE_VEHICLE); + return 0; +} + +static int32 EngineRenewMoneyUpdate(int32 p1) +{ + DoCommandP(0, 2, _patches.autorenew_money, NULL, CMD_REPLACE_VEHICLE); + return 0; +} + typedef int32 PatchButtonClick(int32); typedef struct PatchEntry { @@ -688,9 +706,9 @@ static const PatchEntry _patches_vehicles[] = { {PE_BOOL, 0, STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES, "never_expire_vehicles", &_patches.never_expire_vehicles,0,0,0, NULL}, {PE_UINT16, PF_0ISDIS | PF_PLAYERBASED, STR_CONFIG_PATCHES_LOST_TRAIN_DAYS, "lost_train_days", &_patches.lost_train_days, 180,720, 60, NULL}, - {PE_BOOL, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,"autorenew", &_patches.autorenew, 0, 0, 0, NULL}, - {PE_INT16, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, "autorenew_months", &_patches.autorenew_months, -12, 12, 1, NULL}, - {PE_CURRENCY, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONEY,"autorenew_money", &_patches.autorenew_money, 0, 2000000, 100000, NULL}, + {PE_BOOL, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE, "autorenew", &_patches.autorenew, 0, 0, 0, &EngineRenewUpdate}, + {PE_INT16, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, "autorenew_months", &_patches.autorenew_months, -12, 12, 1, &EngineRenewMonthsUpdate}, + {PE_CURRENCY, PF_PLAYERBASED, STR_CONFIG_PATCHES_AUTORENEW_MONEY, "autorenew_money", &_patches.autorenew_money, 0, 2000000, 100000, &EngineRenewMoneyUpdate}, {PE_UINT16, 0, STR_CONFIG_PATCHES_MAX_TRAINS, "max_trains", &_patches.max_trains, 0,5000, 50, NULL}, {PE_UINT16, 0, STR_CONFIG_PATCHES_MAX_ROADVEH, "max_roadveh", &_patches.max_roadveh, 0,5000, 50, NULL}, diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c index 7fd1942e7..7472e7c61 100644 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -33,7 +33,7 @@ extern void DrawCanalWater(TileIndex tile); const Bridge _bridge[] = { /* - year of availablity + year of availablity | minimum length | | maximum length | | | price diff --git a/variables.h b/variables.h index 530bfd47c..2872225e3 100644 --- a/variables.h +++ b/variables.h @@ -434,9 +434,6 @@ VARDEF byte _vehicle_design_names; * to include npf.h */ #define NPF_TILE_LENGTH 100 -/* Autoreplace vehicle stuff*/ -VARDEF byte _autoreplace_array[256]; - /* Forking stuff */ VARDEF bool _dedicated_forks; diff --git a/vehicle.c b/vehicle.c index 4a0b75122..fa32a79ea 100644 --- a/vehicle.c +++ b/vehicle.c @@ -1322,7 +1322,7 @@ static void ShowVehicleGettingOld(Vehicle *v, StringID msg) return; // Do not show getting-old message if autorenew is active - if (_patches.autorenew) + if (GetPlayer(v->owner)->engine_renew) return; SetDParam(0, _vehicle_type_names[v->type - 0x10]); @@ -1360,32 +1360,25 @@ extern int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p extern int32 CmdRefitShip(int x, int y, uint32 flags, uint32 p1, uint32 p2); extern int32 CmdRefitAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2); + + /** Replaces a vehicle (used to be called autorenew). - * @param x,y unused - * @param p1 index of vehicle being replaced - * @param p2 various bitstuffed elements - * - p2 = (bit 0-15) - new engine type for the vehicle (p2 & 0xFFFF) - * - p2 = (bit 16-31) - money the player wants to have left after replacement counted in 100.000 (100K) (p2 >> 16) + * Must be called with _current_player set to the owner of the vehicle + * @param v Vehicle to replace */ -int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) -{ - /* makesvariables to inform about how much money the player wants to have left after replacing - and which engine to replace with out of p2. - the first 16 bit is the money. The last 5 digits (all 0) were removed when sent, so we add them again. - This way the max is 6553 millions and it is more than the 32 bit that is stored in _patches - This is a nice way to send 32 bit and only use 16 bit - the last 8 bit is the engine. The 8 bits in front of the engine is free so it have room for 16 bit engine entries */ - EngineID new_engine_type = (p2 & 0xFFFF); - uint32 autorefit_money = (p2 >> 16) * 100000; - Vehicle *v, *u, *first; +int32 ReplaceVehicle(Vehicle *v) +{ + Player *p = GetPlayer(v->owner); + EngineID old_engine_type = v->engine_type; + EngineID new_engine_type = p->engine_replacement[old_engine_type]; + Vehicle *u, *first; int cost, build_cost, rear_engine_cost = 0; - EngineID old_engine_type; - - if (!IsVehicleIndex(p1)) return CMD_ERROR; - v = u = GetVehicle(p1); + // If replacing due to age only, use the same type :-) + if (new_engine_type == INVALID_ENGINE) + new_engine_type = old_engine_type; - old_engine_type = v->engine_type; + u = v; /* First we make sure that it's a valid type the user requested * check that it's an engine that is in the engine array */ @@ -1449,7 +1442,7 @@ int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) /* Check if there is money for the upgrade.. if not, give a nice news-item (that is needed, because this CMD is called automaticly) */ - if ( GetPlayer(v->owner)->money64 < (int32)(autorefit_money + build_cost + rear_engine_cost - v->value)) { + if ( p->money64 < (p->engine_renew_money + build_cost + rear_engine_cost - v->value)) { if (( _local_player == v->owner ) && ( v->unitnumber != 0 )) { //v->unitnumber = 0 for train cars int message; SetDParam(0, v->unitnumber); @@ -1469,8 +1462,7 @@ int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) } cost = build_cost - v->value + rear_engine_cost; - - if (flags & DC_EXEC) { + if (old_engine_type != new_engine_type) { /* We do not really buy a new vehicle, we upgrade the old one */ const Engine* e = GetEngine(new_engine_type); @@ -1615,22 +1607,27 @@ int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) v->cargo_count = v->cargo_cap; } } - InvalidateWindow(WC_REPLACE_VEHICLE, v->type); - ResortVehicleLists(); - InvalidateWindow(WC_VEHICLE_DETAILS, v->index); } + + // A replaced vehicle should be classed as new + v->age = 0; + + InvalidateWindow(WC_REPLACE_VEHICLE, v->type); + ResortVehicleLists(); + InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + //needs to be down here because refitting will change SET_EXPENSES_TYPE if called SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); + SubtractMoneyFromPlayer(cost); + if (_current_player == _local_player) + ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); return cost; } void MaybeReplaceVehicle(Vehicle *v) { - uint32 new_engine_and_autoreplace_money; - - if (v->owner != _local_player) - return; + Player *p = GetPlayer(v->owner); // uncomment next line if you want to see what engine type just entered a depot //printf("engine type: %d\n", v->engine_type); @@ -1639,31 +1636,20 @@ void MaybeReplaceVehicle(Vehicle *v) // Standard is -6, meaning 6 months before his max age // It can be any value between -12 and 12. // Here it also checks if the vehicles is listed for replacement - if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30)) { //replace if engine is too old - if (_autoreplace_array[v->engine_type] == v->engine_type && v->type != VEH_Train) //updates to a new model + if (!p->engine_renew || v->age - v->max_age < (p->engine_renew_months * 30)) { //replace if engine is too old + if (p->engine_replacement[v->engine_type] == INVALID_ENGINE && v->type != VEH_Train) // updates to a new model return; } /* Now replace the vehicle */ _current_player = v->owner; - /* makes the variable to inform about how much money the player wants to have left after replacing - and which engine to replace with - the first 16 bit is the money. Since we know the last 5 digits is 0, they are thrown away. - This way the max is 6553 millions and it is more than the 32 bit that is stored in _patches - This is a nice way to send 32 bit and only use 16 bit - the last 8 bit is the engine. The 8 bits in front of the engine is free so it have room for 16 bit engine entries */ - new_engine_and_autoreplace_money = ((_patches.autorenew_money / 100000) << 16) + _autoreplace_array[v->engine_type]; - - assert(v->type == GetEngine(_autoreplace_array[v->engine_type])->type); - if ( v->type != VEH_Train ) { - DoCommandP(v->tile, v->index, new_engine_and_autoreplace_money, NULL, CMD_REPLACE_VEHICLE | CMD_SHOW_NO_ERROR); + ReplaceVehicle(v); } else { // checks if any of the engines in the train are either old or listed for replacement do { - if ( v->engine_type != _autoreplace_array[v->engine_type] || (_patches.autorenew && (v->age - v->max_age) > (_patches.autorenew_months * 30))) { - new_engine_and_autoreplace_money = (new_engine_and_autoreplace_money & 0xFFFF0000) + _autoreplace_array[v->engine_type]; // sets the new engine replacement type - DoCommandP(v->tile, v->index, new_engine_and_autoreplace_money, NULL, CMD_REPLACE_VEHICLE | CMD_SHOW_NO_ERROR); + if (p->engine_replacement[v->engine_type] != INVALID_ENGINE || (p->engine_renew && (v->age - v->max_age) > (p->engine_renew_months * 30))) { + ReplaceVehicle(v); } } while ((v=v->next) != NULL); } diff --git a/vehicle.h b/vehicle.h index 1dd05e2c2..796315552 100644 --- a/vehicle.h +++ b/vehicle.h @@ -453,6 +453,7 @@ VARDEF byte _cmd_build_rail_veh_var1; //VARDEF Vehicle *_vehicle_arr[8][4]; #define INVALID_VEHICLE 0xFFFF +#define INVALID_ENGINE 0xFFFF /* A lot of code calls for the invalidation of the status bar, which is widget 5. * Best is to have a virtual value for it when it needs to change again */ diff --git a/vehicle_gui.c b/vehicle_gui.c index 375c32db5..9434d99c5 100644 --- a/vehicle_gui.c +++ b/vehicle_gui.c @@ -744,6 +744,7 @@ static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) uint16 click_scroll_pos = w->vscroll2.pos; uint16 click_scroll_cap = w->vscroll2.cap; byte click_side = 1; + Player *p = GetPlayer(_local_player); switch(e->event) { case WE_PAINT: @@ -813,13 +814,13 @@ static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) } } - if ( selected_id[0] == selected_id[1] || _autoreplace_array[selected_id[0]] == selected_id[1] + if ( selected_id[0] == selected_id[1] || p->engine_replacement[selected_id[0]] == selected_id[1] || selected_id[0] == -1 || selected_id[1] == -1 ) SETBIT(w->disabled_state, 4); else CLRBIT(w->disabled_state, 4); - if ( _autoreplace_array[selected_id[0]] == selected_id[0] || selected_id[0] == -1 ) + if (p->engine_replacement[selected_id[0]] == INVALID_ENGINE || selected_id[0] == -1) SETBIT(w->disabled_state, 6); else CLRBIT(w->disabled_state, 6); @@ -831,10 +832,10 @@ static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) // sets up the string for the vehicle that is being replaced to if ( selected_id[0] != -1 ) { - if ( selected_id[0] == _autoreplace_array[selected_id[0]] ) + if (p->engine_replacement[selected_id[0]] == INVALID_ENGINE) SetDParam(0, STR_NOT_REPLACING); else - SetDParam(0, GetCustomEngineName(_autoreplace_array[selected_id[0]])); + SetDParam(0, GetCustomEngineName(p->engine_replacement[selected_id[0]])); } else { SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED); } @@ -908,14 +909,17 @@ static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) ShowDropDownMenu(w, _rail_types_list, _railtype_selected_in_replace_gui, 15, ~GetPlayer(_local_player)->avail_railtypes, 1); break; } - case 4: { - _autoreplace_array[WP(w,replaceveh_d).sel_engine[0]] = WP(w,replaceveh_d).sel_engine[1]; + case 4: { /* Start replacing */ + EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; + EngineID veh_to = WP(w, replaceveh_d).sel_engine[1]; + DoCommandP(0, 3, veh_from + (veh_to << 16), NULL, CMD_REPLACE_VEHICLE); SetWindowDirty(w); break; } - case 6: { - _autoreplace_array[WP(w,replaceveh_d).sel_engine[0]] = WP(w,replaceveh_d).sel_engine[0]; + case 6: { /* Stop replacing */ + EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; + DoCommandP(0, 3, veh_from + (INVALID_ENGINE << 16), NULL, CMD_REPLACE_VEHICLE); SetWindowDirty(w); break; } -- cgit v1.2.3-70-g09d2