diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -15,16 +15,24 @@ #include "newgrf_engine.h" -uint CountArticulatedParts(EngineID engine_type) +uint CountArticulatedParts(EngineID engine_type, bool purchase_window) { if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0; + Vehicle *v = NULL;; + if (!purchase_window) { + v = new InvalidVehicle(); + v->engine_type = engine_type; + } + uint i; for (i = 1; i < MAX_UVALUE(EngineID); i++) { - uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine_type, NULL); + uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine_type, v); if (callback == CALLBACK_FAILED || callback == 0xFF) break; } + delete v; + return i - 1; } @@ -42,7 +50,6 @@ void AddArticulatedParts(Vehicle **vl, V /* Attempt to use pre-allocated vehicles until they run out. This can happen * if the callback returns different values depending on the cargo type. */ u->SetNext(vl[i]); - if (u->Next() == NULL) u->SetNext(new InvalidVehicle()); if (u->Next() == NULL) return; Vehicle *previous = u; diff --git a/src/articulated_vehicles.h b/src/articulated_vehicles.h --- a/src/articulated_vehicles.h +++ b/src/articulated_vehicles.h @@ -5,7 +5,7 @@ #ifndef ARTICULATED_VEHICLES_H #define ARTICULATED_VEHICLES_H -uint CountArticulatedParts(EngineID engine_type); +uint CountArticulatedParts(EngineID engine_type, bool purchase_window); void AddArticulatedParts(Vehicle **vl, VehicleType type); #endif /* ARTICULATED_VEHICLES_H */ diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -621,7 +621,7 @@ int DrawVehiclePurchaseInfo(int x, int y int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); SetDParam(0, rvi->cargo_type); - SetDParam(1, (capacity * (CountArticulatedParts(engine_number) + 1)) << multihead); + SetDParam(1, (capacity * (CountArticulatedParts(engine_number, true) + 1)) << multihead); SetDParam(2, refitable ? STR_9842_REFITTABLE : STR_EMPTY); } DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -179,11 +179,11 @@ CommandCost CmdBuildRoadVeh(TileIndex ti if (HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) != HASBIT(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE); - uint num_vehicles = 1 + CountArticulatedParts(p1); + uint num_vehicles = 1 + CountArticulatedParts(p1, false); - /* Allow for the front and the articulated parts. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * num_vehicles); - memset(vl, 0, sizeof(*vl) * num_vehicles); + /* Allow for the front and the articulated parts, plus one to "terminate" the list. */ + Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) { return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -514,12 +514,12 @@ static CommandCost CmdBuildRailWagon(Eng const RailVehicleInfo *rvi = RailVehInfo(engine); CommandCost value((GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8); - uint num_vehicles = 1 + CountArticulatedParts(engine); + uint num_vehicles = 1 + CountArticulatedParts(engine, false); if (!(flags & DC_QUERY_COST)) { - /* Allow for the wagon and the articulated parts. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * num_vehicles); - memset(vl, 0, sizeof(*vl) * num_vehicles); + /* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */ + Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); @@ -682,12 +682,12 @@ CommandCost CmdBuildRailVehicle(TileInde uint num_vehicles = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + - CountArticulatedParts(p1); + CountArticulatedParts(p1, false); if (!(flags & DC_QUERY_COST)) { - /* Allow for the dual-heads and the articulated parts. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * num_vehicles); - memset(vl, 0, sizeof(*vl) * num_vehicles); + /* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */ + Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);