MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / StartupOneEngine

Function StartupOneEngine

src/engine.cpp:717–792  ·  view source on GitHub ↗

* Start/initialise one engine. * @param e The engine to initialise. * @param aging_date The date used for age calculations. * @param seed Random seed. */

Source from the content-addressed store, hash-verified

715 * @param seed Random seed.
716 */
717void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed)
718{
719 const EngineInfo *ei = &e->info;
720
721 e->age = 0;
722 e->flags = {};
723 e->company_avail = CompanyMask{};
724 e->company_hidden = CompanyMask{};
725
726 /* Vehicles with the same base_intro date shall be introduced at the same time.
727 * Make sure they use the same randomisation of the date. */
728 SavedRandomSeeds saved_seeds;
729 SaveRandomSeeds(&saved_seeds);
730 SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
731 ei->base_intro.base() ^
732 e->type ^
733 e->GetGRFID());
734 uint32_t r = Random();
735
736 /* Don't randomise the start-date in the first two years after gamestart to ensure availability
737 * of engines in early starting games.
738 * Note: TTDP uses fixed 1922 */
739 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;
740 if (e->intro_date <= TimerGameCalendar::date) {
741 TimerGameCalendar::YearMonthDay intro_ymd = TimerGameCalendar::ConvertDateToYMD(e->intro_date);
742 int aging_months = aging_ymd.year.base() * 12 + aging_ymd.month;
743 int intro_months = intro_ymd.year.base() * 12 + intro_ymd.month;
744 if (intro_ymd.day > 1) intro_months++; // Engines are introduced at the first month start at/after intro date.
745 e->age = aging_months - intro_months;
746 e->company_avail.Set();
747 e->flags.Set(EngineFlag::Available);
748 }
749
750 /* Get parent variant index for syncing reliability via random seed. */
751 const Engine *re = e;
752 while (re->info.variant_id != EngineID::Invalid() && re->info.extra_flags.Test(ExtraEngineFlag::SyncReliability)) {
753 re = Engine::Get(re->info.variant_id);
754 }
755
756 SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
757 (re->index.base() << 16) ^ (re->info.base_intro.base() << 12) ^ (re->info.decay_speed << 8) ^
758 (re->info.lifelength.base() << 4) ^ re->info.retire_early ^
759 e->type ^
760 e->GetGRFID());
761
762 /* Base reliability defined as a percentage of UINT16_MAX. */
763 const uint16_t RELIABILITY_START = UINT16_MAX * 48 / 100;
764 const uint16_t RELIABILITY_MAX = UINT16_MAX * 75 / 100;
765 const uint16_t RELIABILITY_FINAL = UINT16_MAX * 25 / 100;
766
767 static_assert(RELIABILITY_START == 0x7AE0);
768 static_assert(RELIABILITY_MAX == 0xBFFF);
769 static_assert(RELIABILITY_FINAL == 0x3FFF);
770
771 r = Random();
772 /* 14 bits gives a value between 0 and 16383, which is up to an additional 25%p reliability on top of the base reliability. */
773 e->reliability_start = GB(r, 16, 14) + RELIABILITY_START;
774 e->reliability_max = GB(r, 0, 14) + RELIABILITY_MAX;

Callers 2

StartupEnginesFunction · 0.85
FixTTOEnginesFunction · 0.85

Calls 10

SaveRandomSeedsFunction · 0.85
SetRandomSeedFunction · 0.85
GBFunction · 0.85
InvalidFunction · 0.85
RestoreRandomSeedsFunction · 0.85
TestMethod · 0.80
RandomFunction · 0.50
baseMethod · 0.45
GetGRFIDMethod · 0.45
SetMethod · 0.45

Tested by

no test coverage detected