Changeset - r28370:d448a5422ad5
[Not reviewed]
master
0 3 0
Peter Nelson - 11 months ago 2023-12-31 15:47:32
peter1138@openttd.org
Fix: Calculation of initial engine age was inaccurate. (#11660)

Engine age in months was calculated as the difference in days / 32, instead of the actually difference in months. This would result in engines being artificially younger if a game was started at a later date.
3 files changed with 11 insertions and 5 deletions:
0 comments (0 inline, 0 general)
src/engine.cpp
Show inline comments
 
@@ -672,13 +672,13 @@ void SetYearEngineAgingStops()
 
/**
 
 * Start/initialise one engine.
 
 * @param e The engine to initialise.
 
 * @param aging_date The date used for age calculations.
 
 * @param seed Random seed.
 
 */
 
void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed)
 
void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed)
 
{
 
	const EngineInfo *ei = &e->info;
 

	
 
	e->age = 0;
 
	e->flags = 0;
 
	e->company_avail = 0;
 
@@ -696,13 +696,17 @@ void StartupOneEngine(Engine *e, TimerGa
 

	
 
	/* Don't randomise the start-date in the first two years after gamestart to ensure availability
 
	 * of engines in early starting games.
 
	 * Note: TTDP uses fixed 1922 */
 
	e->intro_date = ei->base_intro <= TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro;
 
	if (e->intro_date <= TimerGameCalendar::date) {
 
		e->age = (aging_date - e->intro_date).base() >> 5;
 
		TimerGameCalendar::YearMonthDay intro_ymd = TimerGameCalendar::ConvertDateToYMD(e->intro_date);
 
		int aging_months = aging_ymd.year.base() * 12 + aging_ymd.month;
 
		int intro_months = intro_ymd.year.base() * 12 + intro_ymd.month;
 
		if (intro_ymd.day > 1) intro_months++; // Engines are introduced at the first month start at/after intro date.
 
		e->age = aging_months - intro_months;
 
		e->company_avail = MAX_UVALUE(CompanyMask);
 
		e->flags |= ENGINE_AVAILABLE;
 
	}
 

	
 
	/* Get parent variant index for syncing reliability via random seed. */
 
	const Engine *re = e;
 
@@ -753,16 +757,17 @@ void StartupOneEngine(Engine *e, TimerGa
 
 * to the NewGRF config.
 
 */
 
void StartupEngines()
 
{
 
	/* Aging of vehicles stops, so account for that when starting late */
 
	const TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date, TimerGameCalendar::ConvertYMDToDate(_year_engine_aging_stops, 0, 1));
 
	TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date);
 
	uint32_t seed = Random();
 

	
 
	for (Engine *e : Engine::Iterate()) {
 
		StartupOneEngine(e, aging_date, seed);
 
		StartupOneEngine(e, aging_ymd, seed);
 
	}
 
	for (Engine *e : Engine::Iterate()) {
 
		CalcEngineReliability(e, false);
 
	}
 

	
 
	/* Update the bitmasks for the vehicle lists */
src/engine_func.h
Show inline comments
 
@@ -24,11 +24,11 @@ extern const uint8_t _engine_counts[4];
 
extern const uint8_t _engine_offsets[4];
 

	
 
bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company);
 
bool IsEngineRefittable(EngineID engine);
 
void SetYearEngineAgingStops();
 
void CalcEngineReliability(Engine *e, bool new_month);
 
void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed);
 
void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed);
 

	
 
uint GetTotalCapacityOfArticulatedParts(EngineID engine);
 

	
 
#endif /* ENGINE_FUNC_H */
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -396,21 +396,22 @@ static bool FixTTOEngines()
 
		for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i);
 
		for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i);
 
		for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i);
 
	}
 

	
 
	TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1));
 
	TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date);
 

	
 
	for (EngineID i = 0; i < 256; i++) {
 
		int oi = ttd_to_tto[i];
 
		Engine *e = GetTempDataEngine(i);
 

	
 
		if (oi == 255) {
 
			/* Default engine is used */
 
			TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
 
			StartupOneEngine(e, aging_date, 0);
 
			StartupOneEngine(e, aging_ymd, 0);
 
			CalcEngineReliability(e, false);
 
			e->intro_date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
 
			TimerGameCalendar::date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
 

	
 
			/* Make sure for example monorail and maglev are available when they should be */
 
			if (TimerGameCalendar::date >= e->intro_date && HasBit(e->info.climates, 0)) {
0 comments (0 inline, 0 general)