1
0
Fork 0

Fix: Clear rail vehicle flipped flag if reverse probability callback returns false. (#14281)

This now distinguishes between not-flipped and callback not implemented.
pull/14288/head
Peter Nelson 2025-05-20 23:03:55 +01:00 committed by GitHub
parent acf594a7b7
commit a2addf0fe7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 24 additions and 10 deletions

View File

@ -432,7 +432,10 @@ void AddArticulatedParts(Vehicle *first)
if (flip_image) v->spritenum++;
if (v->type == VEH_TRAIN && TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) Train::From(v)->flags.Set(VehicleRailFlag::Flipped);
if (v->type == VEH_TRAIN) {
auto prob = TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed);
if (prob.has_value()) Train::From(v)->flags.Set(VehicleRailFlag::Flipped, prob.value());
}
v->UpdatePosition();
}
}

View File

@ -374,7 +374,11 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
if (new_veh->type == VEH_TRAIN && Train::From(old_veh)->flags.Test(VehicleRailFlag::Flipped)) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DoCommandFlag::Execute, new_veh->index, true);
/* Only copy the reverse state if neither old or new vehicle implements reverse-on-build probability callback. */
if (!TestVehicleBuildProbability(old_veh, old_veh->engine_type, BuildProbabilityType::Reversed).has_value() &&
!TestVehicleBuildProbability(new_veh, new_veh->engine_type, BuildProbabilityType::Reversed).has_value()) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DoCommandFlag::Execute, new_veh->index, true);
}
}
return cost;

View File

@ -1235,12 +1235,12 @@ int GetEngineProperty(EngineID engine, PropertyID property, int orig_value, cons
* 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.
* @returns True or false depending on the probability result, or std::nullopt if the callback failed.
*/
bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type)
std::optional<bool> TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type)
{
uint16_t p = GetVehicleCallback(CBID_VEHICLE_BUILD_PROBABILITY, to_underlying(type), 0, engine, v);
if (p == CALLBACK_FAILED) return false;
if (p == CALLBACK_FAILED) return std::nullopt;
const uint16_t PROBABILITY_RANGE = 100;
return p + RandomRange(PROBABILITY_RANGE) >= PROBABILITY_RANGE;

View File

@ -105,7 +105,7 @@ enum class BuildProbabilityType : uint8_t {
Reversed = 0,
};
bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type);
std::optional<bool> TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type);
void TriggerVehicleRandomisation(Vehicle *veh, VehicleRandomTrigger trigger);

View File

@ -662,7 +662,8 @@ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const
v->group_id = DEFAULT_GROUP;
if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) v->flags.Set(VehicleRailFlag::Flipped);
auto prob = TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed);
if (prob.has_value()) v->flags.Set(VehicleRailFlag::Flipped, prob.value());
AddArticulatedParts(v);
v->UpdatePosition();
@ -731,7 +732,8 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
v->SetMultiheaded();
u->SetMultiheaded();
v->SetNext(u);
if (TestVehicleBuildProbability(u, u->engine_type, BuildProbabilityType::Reversed)) u->flags.Set(VehicleRailFlag::Flipped);
auto prob = TestVehicleBuildProbability(u, u->engine_type, BuildProbabilityType::Reversed);
if (prob.has_value()) u->flags.Set(VehicleRailFlag::Flipped, prob.value());
u->UpdatePosition();
/* Now we need to link the front and rear engines together */
@ -804,7 +806,8 @@ CommandCost CmdBuildRailVehicle(DoCommandFlags flags, TileIndex tile, const Engi
v->SetFrontEngine();
v->SetEngine();
if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) v->flags.Set(VehicleRailFlag::Flipped);
auto prob = TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed);
if (prob.has_value()) v->flags.Set(VehicleRailFlag::Flipped, prob.value());
v->UpdatePosition();
if (rvi->railveh_type == RAILVEH_MULTIHEAD) {

View File

@ -906,7 +906,11 @@ std::tuple<CommandCost, VehicleID> CmdCloneVehicle(DoCommandFlags flags, TileInd
w = Vehicle::Get(new_veh_id);
if (v->type == VEH_TRAIN && Train::From(v)->flags.Test(VehicleRailFlag::Flipped)) {
Train::From(w)->flags.Set(VehicleRailFlag::Flipped);
/* Only copy the reverse state if neither old or new vehicle implements reverse-on-build probability callback. */
if (!TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed).has_value() &&
!TestVehicleBuildProbability(w, w->engine_type, BuildProbabilityType::Reversed).has_value()) {
Train::From(w)->flags.Set(VehicleRailFlag::Flipped);
}
}
if (v->type == VEH_TRAIN && !v->IsFrontEngine()) {