Fix 3ac1a2f1e4: Game crash due to invalid vehicle type information. (#14628)
Use std::variant instead of union for vehicle info. RailVehicleInfo is now non-POD so using in a union causes undefined behaviour.
This commit is contained in:
+4
-4
@@ -122,10 +122,10 @@ std::tuple<CommandCost, VehicleID, uint, uint16_t, CargoArray> CmdBuildVehicle(D
|
||||
/* Check whether the number of vehicles we need to build can be built according to pool space. */
|
||||
uint num_vehicles;
|
||||
switch (type) {
|
||||
case VEH_TRAIN: num_vehicles = (e->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false); break;
|
||||
case VEH_TRAIN: num_vehicles = (e->VehInfo<RailVehicleInfo>().railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false); break;
|
||||
case VEH_ROAD: num_vehicles = 1 + CountArticulatedParts(eid, false); break;
|
||||
case VEH_SHIP: num_vehicles = 1; break;
|
||||
case VEH_AIRCRAFT: num_vehicles = e->u.air.subtype & AIR_CTOL ? 2 : 3; break;
|
||||
case VEH_AIRCRAFT: num_vehicles = e->VehInfo<AircraftVehicleInfo>().subtype & AIR_CTOL ? 2 : 3; break;
|
||||
default: NOT_REACHED(); // Safe due to IsDepotTile()
|
||||
}
|
||||
if (!Vehicle::CanAllocateItem(num_vehicles)) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), VehicleID::Invalid(), 0, 0, {} };
|
||||
@@ -133,7 +133,7 @@ std::tuple<CommandCost, VehicleID, uint, uint16_t, CargoArray> CmdBuildVehicle(D
|
||||
/* Check whether we can allocate a unit number. Autoreplace does not allocate
|
||||
* an unit number as it will (always) reuse the one of the replaced vehicle
|
||||
* and (train) wagons don't have an unit number in any scenario. */
|
||||
UnitID unit_num = (flags.Test(DoCommandFlag::QueryCost) || flags.Test(DoCommandFlag::AutoReplace) || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type);
|
||||
UnitID unit_num = (flags.Test(DoCommandFlag::QueryCost) || flags.Test(DoCommandFlag::AutoReplace) || (type == VEH_TRAIN && e->VehInfo<RailVehicleInfo>().railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type);
|
||||
if (unit_num == UINT16_MAX) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), VehicleID::Invalid(), 0, 0, {} };
|
||||
|
||||
/* If we are refitting we need to temporarily purchase the vehicle to be able to
|
||||
@@ -325,7 +325,7 @@ static CommandCost GetRefitCost(const Vehicle *v, EngineID engine_type, CargoTyp
|
||||
break;
|
||||
|
||||
case VEH_TRAIN:
|
||||
base_price = (e->u.rail.railveh_type == RAILVEH_WAGON) ? PR_BUILD_VEHICLE_WAGON : PR_BUILD_VEHICLE_TRAIN;
|
||||
base_price = (e->VehInfo<RailVehicleInfo>().railveh_type == RAILVEH_WAGON) ? PR_BUILD_VEHICLE_WAGON : PR_BUILD_VEHICLE_TRAIN;
|
||||
cost_factor <<= 1;
|
||||
expense_type = EXPENSES_TRAIN_RUN;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user