Skip to content

Commit

Permalink
Fix #10334: Store separate newgrf-safe version of date_of_last_service.
Browse files Browse the repository at this point in the history
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 Jul 14, 2023
1 parent e4be7f4 commit f329189
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 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
}

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 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
}
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 {

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 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 reliability; ///< Reliability.
uint16 reliability_spd_dec; ///< Reliability decrease speed.
byte breakdown_ctr; ///< Counter for managing breakdown events. @see Vehicle::HandleBreakdown
Expand Down

0 comments on commit f329189

Please sign in to comment.