Changeset - r7595:4f881cfee2f3
[Not reviewed]
master
0 5 0
rubidium - 17 years ago 2007-09-17 04:23:03
rubidium@openttd.org
(svn r11122) -Fix [FS#1234]: crash when building a NewGRF vehicle when the articulated build vehicle callback returneed a different value for the purchase window than the normal build. Thanks for Dalestan and _minime_ for pointers to possible causes.
5 files changed with 24 insertions and 17 deletions:
0 comments (0 inline, 0 general)
src/articulated_vehicles.cpp
Show inline comments
 
@@ -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;
src/articulated_vehicles.h
Show inline comments
 
@@ -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 */
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -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);
src/roadveh_cmd.cpp
Show inline comments
 
@@ -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);
src/train_cmd.cpp
Show inline comments
 
@@ -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);
0 comments (0 inline, 0 general)