Skip to content

Commit

Permalink
Fix #10334: Store separate newgrf-safe version of date_of_last_servic…
Browse files Browse the repository at this point in the history
…e. (#11124)

This value is not changed when the date cheat is used, which caused issues with changing properties based on service date.

Co-authored-by: Peter Nelson <peter1138@openttd.org>
  • Loading branch information
2TallTyler and PeterN committed Aug 6, 2023
1 parent 77c00df commit 9a602ff
Show file tree
Hide file tree
Showing 11 changed files with 24 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/aircraft_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_aircraft);

v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = u->build_year = TimerGameCalendar::year;

v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
Expand Down Expand Up @@ -1557,6 +1558,7 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass *
if (v->subtype == AIR_HELICOPTER && apc->num_helipads > 0) {
/* an excerpt of ServiceAircraft, without the invisibility stuff */
v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->breakdowns_since_last_service = 0;
v->reliability = v->GetEngine()->reliability;
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
Expand Down
1 change: 1 addition & 0 deletions src/articulated_vehicles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ void AddArticulatedParts(Vehicle *first)
v->y_pos = first->y_pos;
v->z_pos = first->z_pos;
v->date_of_last_service = first->date_of_last_service;
v->date_of_last_service_newgrf = first->date_of_last_service_newgrf;
v->build_year = first->build_year;
v->vehstatus = first->vehstatus & ~VS_STOPPED;

Expand Down
6 changes: 3 additions & 3 deletions src/newgrf_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
}

case 0x4B: // Long date of last service
return v->date_of_last_service;
return v->date_of_last_service_newgrf;

case 0x4C: // Current maximum speed in NewGRF units
if (!v->IsPrimaryVehicle()) return 0;
Expand Down Expand Up @@ -767,8 +767,8 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
}
return (variable - 0x80) == 0x10 ? ticks : GB(ticks, 8, 8);
}
case 0x12: return ClampTo<uint16_t>(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR);
case 0x13: return GB(ClampTo<uint16_t>(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0x12: return ClampTo<uint16_t>(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR);
case 0x13: return GB(ClampTo<uint16_t>(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0x14: return v->GetServiceInterval();
case 0x15: return GB(v->GetServiceInterval(), 8, 8);
case 0x16: return v->last_station_visited;
Expand Down
1 change: 1 addition & 0 deletions src/roadveh_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->SetServiceInterval(Company::Get(v->owner)->settings.vehicle.servint_roadveh);

v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;

v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
Expand Down
7 changes: 7 additions & 0 deletions src/saveload/afterload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3234,6 +3234,13 @@ bool AfterLoadGame()
_new_competitor_timeout.fired = _new_competitor_timeout.period == 0;
}

if (IsSavegameVersionBefore(SLV_NEWGRF_LAST_SERVICE)) {
/* Set service date provided to NewGRF. */
for (Vehicle *v : Vehicle::Iterate()) {
v->date_of_last_service_newgrf = v->date_of_last_service;
}
}

AfterLoadLabelMaps();
AfterLoadCompanyStats();
AfterLoadStoryBook();
Expand Down
1 change: 1 addition & 0 deletions src/saveload/saveload.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ enum SaveLoadVersion : uint16_t {

SLV_INDUSTRY_CARGO_REORGANISE, ///< 315 PR#10853 Industry accepts/produced data reorganised.
SLV_PERIODS_IN_TRANSIT_RENAME, ///< 316 PR#11112 Rename days in transit to (cargo) periods in transit.
SLV_NEWGRF_LAST_SERVICE, ///< 317 PR#11124 Added stable date_of_last_service to avoid NewGRF trouble.

SL_MAX_VERSION, ///< Highest possible saveload version
};
Expand Down
1 change: 1 addition & 0 deletions src/saveload/vehicle_sl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ class SlVehicleCommon : public DefaultSaveLoadHandler<SlVehicleCommon, Vehicle>
SLE_CONDVAR(Vehicle, max_age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, date_of_last_service_newgrf, SLE_INT32, SLV_NEWGRF_LAST_SERVICE, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SLV_31, SLV_180),
SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SLV_180, SL_MAX_VERSION),
Expand Down
1 change: 1 addition & 0 deletions src/ship_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V

v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = Random();
Expand Down
3 changes: 3 additions & 0 deletions src/train_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const
v->railtype = rvi->railtype;

v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = Random();
Expand Down Expand Up @@ -719,6 +720,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
u->railtype = v->railtype;
u->engine_type = v->engine_type;
u->date_of_last_service = v->date_of_last_service;
u->date_of_last_service_newgrf = v->date_of_last_service_newgrf;
u->build_year = v->build_year;
u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
u->random_bits = Random();
Expand Down Expand Up @@ -783,6 +785,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin

v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = Random();
Expand Down
3 changes: 3 additions & 0 deletions src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ void VehicleServiceInDepot(Vehicle *v)

do {
v->date_of_last_service = TimerGameCalendar::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->breakdowns_since_last_service = 0;
v->reliability = v->GetEngine()->reliability;
/* Prevent vehicles from breaking down directly after exiting the depot. */
Expand Down Expand Up @@ -761,6 +762,8 @@ uint32_t Vehicle::GetGRFID() const
void Vehicle::ShiftDates(int interval)
{
this->date_of_last_service = std::max(this->date_of_last_service + interval, 0);
/* date_of_last_service_newgrf is not updated here as it must stay stable
* for vehicles outside of a depot. */
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/vehicle_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist
TimerGameCalendar::Date age; ///< Age in days
TimerGameCalendar::Date max_age; ///< Maximum age
TimerGameCalendar::Date date_of_last_service; ///< Last date the vehicle had a service at a depot.
TimerGameCalendar::Date date_of_last_service_newgrf; ///< Last date the vehicle had a service at a depot, unchanged by the date cheat to protect against unsafe NewGRF behavior.
uint16_t reliability; ///< Reliability.
uint16_t reliability_spd_dec; ///< Reliability decrease speed.
byte breakdown_ctr; ///< Counter for managing breakdown events. @see Vehicle::HandleBreakdown
Expand Down

0 comments on commit 9a602ff

Please sign in to comment.