From 5481dcd191a1b763330345d11264de6eac91a106 Mon Sep 17 00:00:00 2001 From: bjarni Date: Mon, 7 Nov 2005 23:20:47 +0000 Subject: (svn r3155) -Feature: [autoreplace] autoreplace can now remove cars from too long trains -Trains will now remember the length of stations it visits and sell cars when being autoreplaced if they became too long -If it needs to remove cars, then it starts from the front and sells all it can find until the train is short enough -This only works for trains, that knows the station length of the route so a full uninterrupted run is needed -a train needs 1-2 runs to detect if the shortest station is expanded -This feature can be turned on and off in the train replace window and each company can have it's own setting -NOTE: minor savegame version bump --- vehicle.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'vehicle.c') diff --git a/vehicle.c b/vehicle.c index ff327d25c..ece0547b4 100644 --- a/vehicle.c +++ b/vehicle.c @@ -1693,6 +1693,8 @@ static int32 ReplaceVehicle(Vehicle **w, byte flags) if (old_v->type == VEH_Train){ // move the entire train to the new engine, including the old engine. It will be sold in a moment anyway DoCommand(0, 0, (new_v->index << 16) | old_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); + new_v->u.rail.shortest_platform[0] = old_v->u.rail.shortest_platform[0]; + new_v->u.rail.shortest_platform[1] = old_v->u.rail.shortest_platform[1]; } } } @@ -1720,6 +1722,7 @@ static void MaybeReplaceVehicle(Vehicle *v) byte flags = 0; int32 cost, temp_cost = 0; bool stopped = false; + bool train_fits_in_station = false; _current_player = v->owner; @@ -1733,6 +1736,11 @@ static void MaybeReplaceVehicle(Vehicle *v) stopped = true; } + if (v->type == VEH_Train && v->u.rail.shortest_platform[0]*16 <= v->u.rail.cached_total_length && GetPlayer(v->owner)->renew_keep_length) { + // the train is not too long for the stations it visits. We should try to keep it that way if we change anything + train_fits_in_station = true; + } + while (true) { cost = 0; w = v; @@ -1794,6 +1802,27 @@ static void MaybeReplaceVehicle(Vehicle *v) flags |= DC_EXEC; } + if (train_fits_in_station) { + // the train fitted in the stations it got in it's orders, so we should make sure that it still do + Vehicle *temp; + w = v; + while (v->u.rail.shortest_platform[0]*16 < v->u.rail.cached_total_length) { + // the train is too long. We will remove cars one by one from the start of the train until it's short enough + while (w != NULL && !(RailVehInfo(w->engine_type)->flags&RVI_WAGON) ) { + w = GetNextVehicle(w); + } + if (w == NULL) { + // we failed to make the train short enough + SetDParam(0, v->unitnumber); + AddNewsItem(STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); + break; + } + temp = w; + w = GetNextVehicle(w); + cost += DoCommand(0, 0, temp->index, 0, flags, CMD_SELL_VEH(temp->type)); + } + } + if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); if (stopped) @@ -2085,8 +2114,10 @@ static const SaveLoad _train_desc[] = { SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_status), SLE_UINT8, 2, 255), SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_tile), SLE_UINT32, 2, 255), SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_trackdir), SLE_UINT8, 2, 255), - // reserve extra space in savegame here. (currently 7 bytes) - SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 7, 2, 255), + SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,shortest_platform[0]), SLE_UINT8, 2, 255), // added with 16.1, but was blank since 2 + SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,shortest_platform[1]), SLE_UINT8, 2, 255), // added with 16.1, but was blank since 2 + // reserve extra space in savegame here. (currently 5 bytes) + SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 5, 2, 255), SLE_END() }; -- cgit v1.2.3-54-g00ecf