(svn r3138) -Fix: [clone vehicles] fixed assert when it was possible to allocate some vehicles to clone a train, but not for all cars
authorbjarni
Sat, 05 Nov 2005 14:01:00 +0000
changeset 2601 7c94a0e394a6
parent 2600 2e6079e37708
child 2602 f0e2dcce3695
(svn r3138) -Fix: [clone vehicles] fixed assert when it was possible to allocate some vehicles to clone a train, but not for all cars
Now it gives "too many vehicles" error message instead
To make this work, AllocateVehicles() needed to be moved to vehicle.c (from aircraft_cmd.c) and made non-static
aircraft_cmd.c
vehicle.c
vehicle.h
--- a/aircraft_cmd.c	Fri Nov 04 22:10:49 2005 +0000
+++ b/aircraft_cmd.c	Sat Nov 05 14:01:00 2005 +0000
@@ -121,29 +121,6 @@
 	}
 }
 
-/* Allocate many vehicles */
-static bool AllocateVehicles(Vehicle **vl, int num)
-{
-	int i;
-	Vehicle *v;
-	bool success = true;
-
-	for(i=0; i!=num; i++) {
-		vl[i] = v = AllocateVehicle();
-		if (v == NULL) {
-			success = false;
-			break;
-		}
-		v->type = 1;
-	}
-
-	while (--i >= 0) {
-		vl[i]->type = 0;
-	}
-
-	return success;
-}
-
 int32 EstimateAircraftCost(EngineID engine_type)
 {
 	return AircraftVehInfo(engine_type)->base_cost * (_price.aircraft_base>>3)>>5;
--- a/vehicle.c	Fri Nov 04 22:10:49 2005 +0000
+++ b/vehicle.c	Sat Nov 05 14:01:00 2005 +0000
@@ -315,6 +315,34 @@
 	return NULL;
 }
 
+/** Allocates a lot of vehicles and frees them again
+* @param vl pointer to an array of vehicles that can store all the vehicles in the test
+* @param num number of vehicles to test for
+*	returns true if there is room to allocate all the vehicles
+*/
+bool AllocateVehicles(Vehicle **vl, int num)
+{
+	int i;
+	Vehicle *v;
+	bool success = true;
+
+	for(i = 0; i != num; i++) {
+		vl[i] = v = AllocateVehicle();
+		if (v == NULL) {
+			success = false;
+			break;
+		}
+		v->type = 1;
+	}
+
+	while (--i >= 0) {
+		vl[i]->type = 0;
+	}
+
+	return success;
+}
+
+
 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
 {
 	int x,y,x2,y2;
@@ -1482,7 +1510,6 @@
 	Vehicle *v_front, *v;
 	Vehicle *w_front, *w, *w_rear;
 	int cost, total_cost = 0;
-//	VehicleID *new_id;
 
 	if (!IsVehicleIndex(p1))
 		return CMD_ERROR;
@@ -1506,6 +1533,25 @@
 
 	if (v->type == VEH_Train && v->subtype != TS_Front_Engine) return CMD_ERROR;
 
+	// check that we can allocate enough vehicles
+	if (!(flags & DC_EXEC)) {
+		int veh_counter = 0;
+		do {
+			veh_counter++;
+		} while ((v = v->next) != NULL);
+
+		{
+			Vehicle **vl = malloc(sizeof(Vehicle*) * veh_counter);	// some platforms do not support Vehicle *vl[veh_counter]
+			bool can_allocate_vehicles = AllocateVehicles(vl, veh_counter);
+			free(vl);
+			if (!can_allocate_vehicles) {
+				return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+			}
+		}
+	}
+
+	v = v_front;
+
 	do {
 		cost = DoCommand(x, y, v->engine_type, 3, flags, CMD_BUILD_VEH(v->type));
 
--- a/vehicle.h	Fri Nov 04 22:10:49 2005 +0000
+++ b/vehicle.h	Sat Nov 05 14:01:00 2005 +0000
@@ -274,6 +274,7 @@
 
 void VehicleServiceInDepot(Vehicle *v);
 Vehicle *AllocateVehicle(void);
+bool AllocateVehicles(Vehicle **vl, int num);
 Vehicle *ForceAllocateVehicle(void);
 Vehicle *ForceAllocateSpecialVehicle(void);
 void UpdateVehiclePosHash(Vehicle *v, int x, int y);