(svn r8144) -Fix: [FS#163] When a station is removed, vehicles do not get excessive payment any longer, as the origin TILE is now stored as long as the origin STATION for the transported cargos. Basically this is only a temporary fix until cargopackets are implemented, but it fixes one of the oldest known bugs (Special Thanks to Darkvater for lots of testing)

This commit is contained in:
celestar 2007-01-15 14:42:24 +00:00
parent 3b22cfe70d
commit 05b783e551
7 changed files with 33 additions and 10 deletions

View File

@ -1213,7 +1213,7 @@ static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type)
return false; 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; bool subsidised;
Station *s_from, *s_to; 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); DeliverGoodsToIndustry(s_to->xy, cargo_type, num_pieces);
// Determine profit // 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 // Modify profit if a subsidy is in effect
if (subsidised) { if (subsidised) {
@ -1376,7 +1376,7 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */ unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */
if (just_arrived && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) { 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); SETBIT(v->load_status, LS_CARGO_PAID_FOR);
} }
result |= 1; 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)) { if (just_arrived && (u->current_order.flags & OF_TRANSFER) && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
v_profit = GetTransportedGoodsIncome( v_profit = GetTransportedGoodsIncome(
v->cargo_count, 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_days,
v->cargo_type) * 3 / 2; v->cargo_type) * 3 / 2;
@ -1402,12 +1402,15 @@ int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
// No goods waiting at station // No goods waiting at station
ge->enroute_time = v->cargo_days; ge->enroute_time = v->cargo_days;
ge->enroute_from = v->cargo_source; ge->enroute_from = v->cargo_source;
ge->enroute_from_xy = v->cargo_source_xy;
} else { } else {
// Goods already waiting at station. Set counters to the worst value. // Goods already waiting at station. Set counters to the worst value.
if (v->cargo_days >= ge->enroute_time) if (v->cargo_days >= ge->enroute_time) ge->enroute_time = v->cargo_days;
ge->enroute_time = v->cargo_days;
if (last_visited != ge->enroute_from) if (last_visited != ge->enroute_from) {
ge->enroute_from = v->cargo_source; ge->enroute_from = v->cargo_source;
ge->enroute_from_xy = v->cargo_source_xy;
}
} }
// Update amount of waiting cargo // Update amount of waiting cargo
SB(ge->waiting_acceptance, 0, 12, min(amount_unloaded + t, 0xFFF)); 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 cargoshare;
int feeder_profit_share; int feeder_profit_share;
if (v->cargo_count == 0) if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
/* Skip loading this vehicle if another train/vehicle is already handling /* Skip loading this vehicle if another train/vehicle is already handling
* the same cargo type at this station */ * 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. // And record the source of the cargo, and the days in travel.
v->cargo_source = ge->enroute_from; v->cargo_source = ge->enroute_from;
v->cargo_source_xy = ge->enroute_from_xy;
v->cargo_days = ge->enroute_time; v->cargo_days = ge->enroute_time;
result |= 2; result |= 2;
st->last_vehicle_type = v->type; st->last_vehicle_type = v->type;

View File

@ -1689,6 +1689,19 @@ bool AfterLoadGame(void)
} END_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0) } 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; return true;
} }

View File

@ -30,7 +30,7 @@
#include "variables.h" #include "variables.h"
#include <setjmp.h> #include <setjmp.h>
extern const uint16 SAVEGAME_VERSION = 43; extern const uint16 SAVEGAME_VERSION = 44;
uint16 _sl_version; /// the major savegame version identifier uint16 _sl_version; /// the major savegame version identifier
byte _sl_minor_version; /// the minor savegame version, DO NOT USE! byte _sl_minor_version; /// the minor savegame version, DO NOT USE!

View File

@ -18,6 +18,7 @@ typedef struct GoodsEntry {
days_since_pickup(0), days_since_pickup(0),
rating(175), rating(175),
enroute_from(INVALID_STATION), enroute_from(INVALID_STATION),
enroute_from_xy(INVALID_TILE),
last_speed(0), last_speed(0),
last_age(255), last_age(255),
feeder_profit(0) feeder_profit(0)
@ -27,6 +28,7 @@ typedef struct GoodsEntry {
byte days_since_pickup; byte days_since_pickup;
byte rating; byte rating;
StationID enroute_from; StationID enroute_from;
TileIndex enroute_from_xy;
byte enroute_time; byte enroute_time;
byte last_speed; byte last_speed;
byte last_age; byte last_age;

View File

@ -2533,6 +2533,7 @@ static void UpdateStationWaiting(Station *st, int type, uint amount)
st->goods[type].enroute_time = 0; st->goods[type].enroute_time = 0;
st->goods[type].enroute_from = st->index; st->goods[type].enroute_from = st->index;
st->goods[type].enroute_from_xy = st->xy;
InvalidateWindow(WC_STATION_VIEW, st->index); InvalidateWindow(WC_STATION_VIEW, st->index);
st->MarkTilesDirty(); st->MarkTilesDirty();
} }
@ -2748,6 +2749,7 @@ void BuildOilRig(TileIndex tile)
st->goods[j].waiting_acceptance = 0; st->goods[j].waiting_acceptance = 0;
st->goods[j].days_since_pickup = 0; st->goods[j].days_since_pickup = 0;
st->goods[j].enroute_from = INVALID_STATION; st->goods[j].enroute_from = INVALID_STATION;
st->goods[j].enroute_from_xy = INVALID_TILE;
st->goods[j].rating = 175; st->goods[j].rating = 175;
st->goods[j].last_speed = 0; st->goods[j].last_speed = 0;
st->goods[j].last_age = 255; st->goods[j].last_age = 255;
@ -2958,6 +2960,7 @@ static const SaveLoad _goods_desc[] = {
SLE_VAR(GoodsEntry, rating, SLE_UINT8), 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_FILE_U8 | SLE_VAR_U16, 0, 6),
SLE_CONDVAR(GoodsEntry, enroute_from, SLE_UINT16, 7, SL_MAX_VERSION), 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, enroute_time, SLE_UINT8),
SLE_VAR(GoodsEntry, last_speed, SLE_UINT8), SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
SLE_VAR(GoodsEntry, last_age, SLE_UINT8), SLE_VAR(GoodsEntry, last_age, SLE_UINT8),

View File

@ -2957,6 +2957,7 @@ extern const SaveLoad _common_veh_desc[] = {
SLE_VAR(Vehicle, cargo_days, SLE_UINT8), 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_FILE_U8 | SLE_VAR_U16, 0, 6),
SLE_CONDVAR(Vehicle, cargo_source, SLE_UINT16, 7, SL_MAX_VERSION), 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_cap, SLE_UINT16),
SLE_VAR(Vehicle, cargo_count, SLE_UINT16), SLE_VAR(Vehicle, cargo_count, SLE_UINT16),

View File

@ -195,6 +195,7 @@ struct Vehicle {
CargoID cargo_type; // type of cargo this vehicle is carrying CargoID cargo_type; // type of cargo this vehicle is carrying
byte cargo_days; // how many days have the pieces been in transit byte cargo_days; // how many days have the pieces been in transit
StationID cargo_source; // source of cargo 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_cap; // total capacity
uint16 cargo_count; // how many pieces are used uint16 cargo_count; // how many pieces are used
byte cargo_subtype; ///< Used for livery refits (NewGRF variations) byte cargo_subtype; ///< Used for livery refits (NewGRF variations)