diff --git a/src/economy.cpp b/src/economy.cpp index 4006fc0597..a1a63ee1e1 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1213,7 +1213,7 @@ static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type) return false; } -static int32 DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, StationID dest, byte days_in_transit) +static int32 DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, StationID dest, TileIndex source_tile, byte days_in_transit) { bool subsidised; Station *s_from, *s_to; @@ -1243,7 +1243,7 @@ static int32 DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, DeliverGoodsToIndustry(s_to->xy, cargo_type, num_pieces); // Determine profit - profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(s_from->xy, s_to->xy), days_in_transit, cargo_type); + profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(source_tile, s_to->xy), days_in_transit, cargo_type); // Modify profit if a subsidy is in effect if (subsidised) { @@ -1376,7 +1376,7 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived) unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */ if (just_arrived && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) { - profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days); + profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_source_xy, v->cargo_days); SETBIT(v->load_status, LS_CARGO_PAID_FOR); } result |= 1; @@ -1388,7 +1388,7 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived) if (just_arrived && (u->current_order.flags & OF_TRANSFER) && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) { v_profit = GetTransportedGoodsIncome( v->cargo_count, - DistanceManhattan(GetStation(v->cargo_source)->xy, GetStation(last_visited)->xy), + DistanceManhattan(v->cargo_source_xy, GetStation(last_visited)->xy), v->cargo_days, v->cargo_type) * 3 / 2; @@ -1402,12 +1402,15 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived) // No goods waiting at station ge->enroute_time = v->cargo_days; ge->enroute_from = v->cargo_source; + ge->enroute_from_xy = v->cargo_source_xy; } else { // Goods already waiting at station. Set counters to the worst value. - if (v->cargo_days >= ge->enroute_time) - ge->enroute_time = v->cargo_days; - if (last_visited != ge->enroute_from) + if (v->cargo_days >= ge->enroute_time) ge->enroute_time = v->cargo_days; + + if (last_visited != ge->enroute_from) { ge->enroute_from = v->cargo_source; + ge->enroute_from_xy = v->cargo_source_xy; + } } // Update amount of waiting cargo SB(ge->waiting_acceptance, 0, 12, min(amount_unloaded + t, 0xFFF)); @@ -1451,8 +1454,7 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived) int cargoshare; int feeder_profit_share; - if (v->cargo_count == 0) - TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); + if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); /* Skip loading this vehicle if another train/vehicle is already handling * the same cargo type at this station */ @@ -1482,6 +1484,7 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived) // And record the source of the cargo, and the days in travel. v->cargo_source = ge->enroute_from; + v->cargo_source_xy = ge->enroute_from_xy; v->cargo_days = ge->enroute_time; result |= 2; st->last_vehicle_type = v->type; diff --git a/src/openttd.cpp b/src/openttd.cpp index e0d0d1f275..cb030b4fa0 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1689,6 +1689,19 @@ bool AfterLoadGame(void) } END_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0) } + if (CheckSavegameVersion(44)) { + Vehicle *v; + /* If we remove a station while cargo from it is still enroute, payment calculation will assume + * 0, 0 to be the origin of the cargo, resulting in very high payments usually. v->cargo_source_xy + * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded + * where this situation exists, the cargo-source information is lost. in this case, we set the origin + * to the current tile of the vehicle to prevent excessive profits + */ + FOR_ALL_VEHICLES(v) { + v->cargo_source_xy = IsValidStationID(v->cargo_source) ? GetStation(v->cargo_source)->xy : v->tile; + } + } + return true; } diff --git a/src/saveload.cpp b/src/saveload.cpp index ef8911b065..65e6e454d8 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -30,7 +30,7 @@ #include "variables.h" #include -extern const uint16 SAVEGAME_VERSION = 43; +extern const uint16 SAVEGAME_VERSION = 44; uint16 _sl_version; /// the major savegame version identifier byte _sl_minor_version; /// the minor savegame version, DO NOT USE! diff --git a/src/station.h b/src/station.h index e2ec2e8a7c..b6cffe1d26 100644 --- a/src/station.h +++ b/src/station.h @@ -18,6 +18,7 @@ typedef struct GoodsEntry { days_since_pickup(0), rating(175), enroute_from(INVALID_STATION), + enroute_from_xy(INVALID_TILE), last_speed(0), last_age(255), feeder_profit(0) @@ -27,6 +28,7 @@ typedef struct GoodsEntry { byte days_since_pickup; byte rating; StationID enroute_from; + TileIndex enroute_from_xy; byte enroute_time; byte last_speed; byte last_age; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 351c55aff0..417dbf775a 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2533,6 +2533,7 @@ static void UpdateStationWaiting(Station *st, int type, uint amount) st->goods[type].enroute_time = 0; st->goods[type].enroute_from = st->index; + st->goods[type].enroute_from_xy = st->xy; InvalidateWindow(WC_STATION_VIEW, st->index); st->MarkTilesDirty(); } @@ -2748,6 +2749,7 @@ void BuildOilRig(TileIndex tile) st->goods[j].waiting_acceptance = 0; st->goods[j].days_since_pickup = 0; st->goods[j].enroute_from = INVALID_STATION; + st->goods[j].enroute_from_xy = INVALID_TILE; st->goods[j].rating = 175; st->goods[j].last_speed = 0; st->goods[j].last_age = 255; @@ -2958,6 +2960,7 @@ static const SaveLoad _goods_desc[] = { SLE_VAR(GoodsEntry, rating, SLE_UINT8), SLE_CONDVAR(GoodsEntry, enroute_from, SLE_FILE_U8 | SLE_VAR_U16, 0, 6), SLE_CONDVAR(GoodsEntry, enroute_from, SLE_UINT16, 7, SL_MAX_VERSION), + SLE_CONDVAR(GoodsEntry, enroute_from_xy, SLE_UINT32, 44, SL_MAX_VERSION), SLE_VAR(GoodsEntry, enroute_time, SLE_UINT8), SLE_VAR(GoodsEntry, last_speed, SLE_UINT8), SLE_VAR(GoodsEntry, last_age, SLE_UINT8), diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 96cc9a2ece..69fabc10f0 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2957,6 +2957,7 @@ extern const SaveLoad _common_veh_desc[] = { SLE_VAR(Vehicle, cargo_days, SLE_UINT8), SLE_CONDVAR(Vehicle, cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6), SLE_CONDVAR(Vehicle, cargo_source, SLE_UINT16, 7, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, cargo_source_xy, SLE_UINT32, 44, SL_MAX_VERSION), SLE_VAR(Vehicle, cargo_cap, SLE_UINT16), SLE_VAR(Vehicle, cargo_count, SLE_UINT16), diff --git a/src/vehicle.h b/src/vehicle.h index 71ff5aab09..85b74135d8 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -195,6 +195,7 @@ struct Vehicle { CargoID cargo_type; // type of cargo this vehicle is carrying byte cargo_days; // how many days have the pieces been in transit StationID cargo_source; // source of cargo + TileIndex cargo_source_xy; //< stores the Tile where the source station is located, in case it is removed uint16 cargo_cap; // total capacity uint16 cargo_count; // how many pieces are used byte cargo_subtype; ///< Used for livery refits (NewGRF variations)