diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index 482031cec0..056461c006 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -282,6 +282,9 @@ enum CallbackID { /** Called to determine the engine name to show. */ CBID_VEHICLE_NAME = 0x161, // 15 bit callback + + /** Called to determine probability during build. */ + CBID_VEHICLE_BUILD_PROBABILITY = 0x162, // 15 bit callback }; /** diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index df3be19561..bea6c1d2e8 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1192,6 +1192,20 @@ int GetEngineProperty(EngineID engine, PropertyID property, int orig_value, cons return orig_value; } +/** + * Test for vehicle build probablity type. + * @param v Vehicle whose build probability to test. + * @param type Build probability type to test for. + * @returns True iff the probability result says so. + */ +bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type) +{ + uint16_t p = GetVehicleCallback(CBID_VEHICLE_BUILD_PROBABILITY, std::underlying_type::type(type), 0, engine, v); + if (p == CALLBACK_FAILED) return false; + + const uint16_t PROBABILITY_RANGE = 100; + return p + RandomRange(PROBABILITY_RANGE) >= PROBABILITY_RANGE; +} static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, uint16_t base_random_bits, bool first) { diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index 4452ad9caf..da37602b81 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.h @@ -103,6 +103,12 @@ bool UsesWagonOverride(const Vehicle *v); int GetVehicleProperty(const Vehicle *v, PropertyID property, int orig_value, bool is_signed = false); int GetEngineProperty(EngineID engine, PropertyID property, int orig_value, const Vehicle *v = nullptr, bool is_signed = false); +enum class BuildProbabilityType { + Reversed = 0, +}; + +bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type); + enum VehicleTrigger { VEHICLE_TRIGGER_NEW_CARGO = 0x01, /* Externally triggered only for the first vehicle in chain */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 67e233f9d7..848a1bad4e 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -661,6 +661,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const v->group_id = DEFAULT_GROUP; + if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) SetBit(v->flags, VRF_REVERSE_DIRECTION); AddArticulatedParts(v); v->UpdatePosition(); @@ -728,6 +729,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v) v->SetMultiheaded(); u->SetMultiheaded(); v->SetNext(u); + if (TestVehicleBuildProbability(u, u->engine_type, BuildProbabilityType::Reversed)) SetBit(u->flags, VRF_REVERSE_DIRECTION); u->UpdatePosition(); /* Now we need to link the front and rear engines together */ @@ -799,6 +801,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin v->SetFrontEngine(); v->SetEngine(); + if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) SetBit(v->flags, VRF_REVERSE_DIRECTION); v->UpdatePosition(); if (rvi->railveh_type == RAILVEH_MULTIHEAD) {