src/train_cmd.cpp
changeset 6476 5bd4843b681b
parent 6467 6228b576422d
child 6477 c0add302a009
equal deleted inserted replaced
6475:f80c51a83069 6476:5bd4843b681b
    58  * Recalculates the cached total power of a train. Should be called when the consist is changed
    58  * Recalculates the cached total power of a train. Should be called when the consist is changed
    59  * @param v First vehicle of the consist.
    59  * @param v First vehicle of the consist.
    60  */
    60  */
    61 void TrainPowerChanged(Vehicle* v)
    61 void TrainPowerChanged(Vehicle* v)
    62 {
    62 {
    63 	Vehicle* u;
       
    64 	uint32 power = 0;
    63 	uint32 power = 0;
    65 	uint32 max_te = 0;
    64 	uint32 max_te = 0;
    66 
    65 
    67 	for (u = v; u != NULL; u = u->next) {
    66 	for (const Vehicle *u = v; u != NULL; u = u->next) {
    68 		/* Power is not added for articulated parts */
    67 		/* Power is not added for articulated parts */
    69 		if (IsArticulatedPart(u)) continue;
    68 		if (IsArticulatedPart(u)) continue;
    70 
    69 
    71 		RailType railtype = (IsLevelCrossingTile(u->tile) ? GetRailTypeCrossing(u->tile) : GetRailType(u->tile));
    70 		RailType railtype = (IsLevelCrossingTile(u->tile) ? GetRailTypeCrossing(u->tile) : GetRailType(u->tile));
    72 		bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype);
    71 		bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype);
    99  * the consist changes.
    98  * the consist changes.
   100  * @param v First vehicle of the consist.
    99  * @param v First vehicle of the consist.
   101  */
   100  */
   102 static void TrainCargoChanged(Vehicle* v)
   101 static void TrainCargoChanged(Vehicle* v)
   103 {
   102 {
   104 	Vehicle *u;
       
   105 	uint32 weight = 0;
   103 	uint32 weight = 0;
   106 
   104 
   107 	for (u = v; u != NULL; u = u->next) {
   105 	for (Vehicle *u = v; u != NULL; u = u->next) {
   108 		const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
   106 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo_count * FreightWagonMult(u->cargo_type) / 16;
   109 		uint32 vweight = (GetCargo(u->cargo_type)->weight * u->cargo_count * FreightWagonMult(u->cargo_type)) / 16;
       
   110 
   107 
   111 		// Vehicle weight is not added for articulated parts.
   108 		// Vehicle weight is not added for articulated parts.
   112 		if (!IsArticulatedPart(u)) {
   109 		if (!IsArticulatedPart(u)) {
   113 			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
   110 			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
   114 			vweight += rvi->weight;
   111 			vweight += RailVehInfo(u->engine_type)->weight;
   115 
   112 
   116 			// powered wagons have extra weight added
   113 			// powered wagons have extra weight added
   117 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
   114 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
   118 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   115 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   119 		}
   116 		}
   121 		// consist weight is the sum of the weight of all vehicles in the consist
   118 		// consist weight is the sum of the weight of all vehicles in the consist
   122 		weight += vweight;
   119 		weight += vweight;
   123 
   120 
   124 		// store vehicle weight in cache
   121 		// store vehicle weight in cache
   125 		u->u.rail.cached_veh_weight = vweight;
   122 		u->u.rail.cached_veh_weight = vweight;
   126 	};
   123 	}
   127 
   124 
   128 	// store consist weight in cache
   125 	// store consist weight in cache
   129 	v->u.rail.cached_weight = weight;
   126 	v->u.rail.cached_weight = weight;
   130 
   127 
   131 	/* Now update train power (tractive effort is dependent on weight) */
   128 	/* Now update train power (tractive effort is dependent on weight) */
   139  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
   136  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
   140  * @param v First vehicle of the chain.
   137  * @param v First vehicle of the chain.
   141  */
   138  */
   142 void TrainConsistChanged(Vehicle* v)
   139 void TrainConsistChanged(Vehicle* v)
   143 {
   140 {
   144 	const RailVehicleInfo *rvi_v;
       
   145 	Vehicle *u;
       
   146 	uint16 max_speed = 0xFFFF;
   141 	uint16 max_speed = 0xFFFF;
   147 	EngineID first_engine;
       
   148 
   142 
   149 	assert(v->type == VEH_Train);
   143 	assert(v->type == VEH_Train);
   150 
       
   151 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   144 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   152 
   145 
   153 	rvi_v = RailVehInfo(v->engine_type);
   146 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   154 	first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   147 	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   155 	v->u.rail.cached_total_length = 0;
   148 	v->u.rail.cached_total_length = 0;
   156 	v->u.rail.compatible_railtypes = 0;
   149 	v->u.rail.compatible_railtypes = 0;
   157 
   150 
   158 	for (u = v; u != NULL; u = u->next) {
   151 	for (Vehicle *u = v; u != NULL; u = u->next) {
   159 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   152 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   160 		uint16 veh_len;
       
   161 
   153 
   162 		// Update the v->first cache. This is faster than having to brute force it later.
   154 		// Update the v->first cache. This is faster than having to brute force it later.
   163 		if (u->first == NULL) u->first = v;
   155 		if (u->first == NULL) u->first = v;
   164 
   156 
   165 		// update the 'first engine'
   157 		// update the 'first engine'
   166 		u->u.rail.first_engine = (v == u) ? (EngineID)INVALID_ENGINE : first_engine;
   158 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
   167 		u->u.rail.railtype = rvi_u->railtype;
   159 		u->u.rail.railtype = rvi_u->railtype;
   168 
   160 
   169 		if (IsTrainEngine(u)) first_engine = u->engine_type;
   161 		if (IsTrainEngine(u)) first_engine = u->engine_type;
   170 
   162 
   171 		if (rvi_u->visual_effect != 0) {
   163 		if (rvi_u->visual_effect != 0) {
   182 				u->u.rail.cached_vis_effect = 8;
   174 				u->u.rail.cached_vis_effect = 8;
   183 			}
   175 			}
   184 		}
   176 		}
   185 
   177 
   186 		if (!IsArticulatedPart(u)) {
   178 		if (!IsArticulatedPart(u)) {
   187 			// check if its a powered wagon
       
   188 			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
       
   189 
       
   190 			/* Check powered wagon / visual effect callback */
   179 			/* Check powered wagon / visual effect callback */
   191 			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
   180 			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
   192 				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
   181 				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
   193 
   182 
   194 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   183 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   196 
   185 
   197 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   186 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   198 				UsesWagonOverride(u) && (u->u.rail.cached_vis_effect < 0x40)) {
   187 				UsesWagonOverride(u) && (u->u.rail.cached_vis_effect < 0x40)) {
   199 				/* wagon is powered */
   188 				/* wagon is powered */
   200 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
   189 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
       
   190 			} else {
       
   191 				CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   201 			}
   192 			}
   202 
   193 
   203 			/* Do not count powered wagons for the compatible railtypes, as wagons always
   194 			/* Do not count powered wagons for the compatible railtypes, as wagons always
   204 			   have railtype normal */
   195 			   have railtype normal */
   205 			if (rvi_u->power > 0) {
   196 			if (rvi_u->power > 0) {
   218 				rvi_u->max_speed != 0 && !UsesWagonOverride(u))
   209 				rvi_u->max_speed != 0 && !UsesWagonOverride(u))
   219 				max_speed = min(rvi_u->max_speed, max_speed);
   210 				max_speed = min(rvi_u->max_speed, max_speed);
   220 		}
   211 		}
   221 
   212 
   222 		// check the vehicle length (callback)
   213 		// check the vehicle length (callback)
   223 		veh_len = CALLBACK_FAILED;
   214 		uint16 veh_len = CALLBACK_FAILED;
   224 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   215 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   225 			veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   216 			veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   226 		}
   217 		}
   227 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   218 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   228 		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
   219 		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
   229 		u->u.rail.cached_veh_length = 8 - veh_len;
   220 		u->u.rail.cached_veh_length = 8 - veh_len;
   230 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   221 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   231 
   222 	}
   232 	};
       
   233 
   223 
   234 	// store consist weight/max speed in cache
   224 	// store consist weight/max speed in cache
   235 	v->u.rail.cached_max_speed = max_speed;
   225 	v->u.rail.cached_max_speed = max_speed;
   236 
   226 
   237 	// recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
   227 	// recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
   289 }
   279 }
   290 
   280 
   291 //new acceleration
   281 //new acceleration
   292 static int GetTrainAcceleration(Vehicle *v, bool mode)
   282 static int GetTrainAcceleration(Vehicle *v, bool mode)
   293 {
   283 {
   294 	const Vehicle *u;
       
   295 	int num = 0; //number of vehicles, change this into the number of axles later
       
   296 	int power = 0;
       
   297 	int mass = 0;
       
   298 	int max_speed = 2000;
   284 	int max_speed = 2000;
   299 	int area = 120;
   285 	int speed = v->cur_speed * 10 / 16; //[mph]
   300 	int friction = 35; //[1e-3]
   286 	int curvecount[2] = {0, 0};
   301 	int drag_coeff = 20; //[1e-4]
   287 
   302 	int incl = 0;
   288 	//first find the curve speed limit
   303 	int resistance;
   289 	int numcurve = 0;
   304 	int speed = v->cur_speed; //[mph]
   290 	int sum = 0;
   305 	int force = 0x3FFFFFFF;
       
   306 	int pos = 0;
   291 	int pos = 0;
   307 	int lastpos = -1;
   292 	int lastpos = -1;
   308 	int curvecount[2] = {0, 0};
   293 	for (const Vehicle *u = v; u->next != NULL; u = u->next, pos++) {
   309 	int sum = 0;
       
   310 	int numcurve = 0;
       
   311 	int max_te = v->u.rail.cached_max_te; // [N]
       
   312 
       
   313 	speed *= 10;
       
   314 	speed /= 16;
       
   315 
       
   316 	//first find the curve speed limit
       
   317 	for (u = v; u->next != NULL; u = u->next, pos++) {
       
   318 		Direction dir = u->direction;
   294 		Direction dir = u->direction;
   319 		Direction ndir = u->next->direction;
   295 		Direction ndir = u->next->direction;
   320 		int i;
   296 		int i;
   321 
   297 
   322 		for (i = 0; i < 2; i++) {
   298 		for (i = 0; i < 2; i++) {
   367 
   343 
   368 			max_speed = max(max_speed, 25 * station_length);
   344 			max_speed = max(max_speed, 25 * station_length);
   369 		}
   345 		}
   370 	}
   346 	}
   371 
   347 
   372 	mass = v->u.rail.cached_weight;
   348 	int mass = v->u.rail.cached_weight;
   373 	power = v->u.rail.cached_power * 746;
   349 	int power = v->u.rail.cached_power * 746;
   374 	max_speed = min(max_speed, v->u.rail.cached_max_speed);
   350 	max_speed = min(max_speed, v->u.rail.cached_max_speed);
   375 
   351 
   376 	for (u = v; u != NULL; u = u->next) {
   352 	int num = 0; //number of vehicles, change this into the number of axles later
       
   353 	int incl = 0;
       
   354 	int drag_coeff = 20; //[1e-4]
       
   355 	for (const Vehicle *u = v; u != NULL; u = u->next) {
   377 		num++;
   356 		num++;
   378 		drag_coeff += 3;
   357 		drag_coeff += 3;
   379 
   358 
   380 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   359 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   381 
   360 
   386 		}
   365 		}
   387 	}
   366 	}
   388 
   367 
   389 	v->max_speed = max_speed;
   368 	v->max_speed = max_speed;
   390 
   369 
       
   370 	const int area = 120;
       
   371 	const int friction = 35; //[1e-3]
       
   372 	int resistance;
   391 	if (v->u.rail.railtype != RAILTYPE_MAGLEV) {
   373 	if (v->u.rail.railtype != RAILTYPE_MAGLEV) {
   392 		resistance = 13 * mass / 10;
   374 		resistance = 13 * mass / 10;
   393 		resistance += 60 * num;
   375 		resistance += 60 * num;
   394 		resistance += friction * mass * speed / 1000;
   376 		resistance += friction * mass * speed / 1000;
   395 		resistance += (area * drag_coeff * speed * speed) / 10000;
   377 		resistance += (area * drag_coeff * speed * speed) / 10000;
   399 	resistance += incl;
   381 	resistance += incl;
   400 	resistance *= 4; //[N]
   382 	resistance *= 4; //[N]
   401 
   383 
   402 	/* Due to the mph to m/s conversion below, at speeds below 3 mph the force is
   384 	/* Due to the mph to m/s conversion below, at speeds below 3 mph the force is
   403 	 * actually double the train's power */
   385 	 * actually double the train's power */
       
   386 	const int max_te = v->u.rail.cached_max_te; // [N]
       
   387 	int force;
   404 	if (speed > 2) {
   388 	if (speed > 2) {
   405 		switch (v->u.rail.railtype) {
   389 		switch (v->u.rail.railtype) {
   406 			case RAILTYPE_RAIL:
   390 			case RAILTYPE_RAIL:
   407 			case RAILTYPE_ELECTRIC:
   391 			case RAILTYPE_ELECTRIC:
   408 			case RAILTYPE_MONO:
   392 			case RAILTYPE_MONO:
   410 				force *= 22;
   394 				force *= 22;
   411 				force /= 10;
   395 				force /= 10;
   412 				if (mode == AM_ACCEL && force > max_te) force = max_te;
   396 				if (mode == AM_ACCEL && force > max_te) force = max_te;
   413 				break;
   397 				break;
   414 
   398 
       
   399 			default: NOT_REACHED();
   415 			case RAILTYPE_MAGLEV:
   400 			case RAILTYPE_MAGLEV:
   416 				force = power / 25;
   401 				force = power / 25;
   417 				break;
   402 				break;
   418 
       
   419 			default: NOT_REACHED();
       
   420 		}
   403 		}
   421 	} else {
   404 	} else {
   422 		//"kickoff" acceleration
   405 		//"kickoff" acceleration
   423 		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
   406 		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
   424 		force = max(force, (mass * 8) + resistance);
   407 		force = max(force, (mass * 8) + resistance);
   435 	}
   418 	}
   436 }
   419 }
   437 
   420 
   438 static void UpdateTrainAcceleration(Vehicle* v)
   421 static void UpdateTrainAcceleration(Vehicle* v)
   439 {
   422 {
   440 	uint power = 0;
       
   441 	uint weight = 0;
       
   442 
       
   443 	assert(IsFrontEngine(v));
   423 	assert(IsFrontEngine(v));
   444 
   424 
   445 	weight = v->u.rail.cached_weight;
       
   446 	power = v->u.rail.cached_power;
       
   447 	v->max_speed = v->u.rail.cached_max_speed;
   425 	v->max_speed = v->u.rail.cached_max_speed;
   448 
   426 
       
   427 	uint power = v->u.rail.cached_power;
       
   428 	uint weight = v->u.rail.cached_weight;
   449 	assert(weight != 0);
   429 	assert(weight != 0);
   450 
       
   451 	v->acceleration = clamp(power / weight * 4, 1, 255);
   430 	v->acceleration = clamp(power / weight * 4, 1, 255);
   452 }
   431 }
   453 
   432 
   454 int GetTrainImage(const Vehicle* v, Direction direction)
   433 int GetTrainImage(const Vehicle* v, Direction direction)
   455 {
   434 {
   506 	DrawSprite(image, pal, x, y);
   485 	DrawSprite(image, pal, x, y);
   507 }
   486 }
   508 
   487 
   509 uint CountArticulatedParts(EngineID engine_type)
   488 uint CountArticulatedParts(EngineID engine_type)
   510 {
   489 {
   511 	uint16 callback;
   490 	if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
       
   491 
   512 	uint i;
   492 	uint i;
   513 
       
   514 	if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
       
   515 
       
   516 	for (i = 1; i < 10; i++) {
   493 	for (i = 1; i < 10; i++) {
   517 		callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL);
   494 		uint16 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL);
   518 		if (callback == CALLBACK_FAILED || callback == 0xFF) break;
   495 		if (callback == CALLBACK_FAILED || callback == 0xFF) break;
   519 	}
   496 	}
   520 
   497 
   521 	return i - 1;
   498 	return i - 1;
   522 }
   499 }
   523 
   500 
   524 static void AddArticulatedParts(Vehicle **vl)
   501 static void AddArticulatedParts(Vehicle **vl)
   525 {
   502 {
   526 	const RailVehicleInfo *rvi_artic;
   503 	const Vehicle *v = vl[0];
   527 	EngineID engine_type;
   504 	Vehicle *u = vl[0];
   528 	Vehicle *v = vl[0];
       
   529 	Vehicle *u = v;
       
   530 	uint16 callback;
       
   531 	bool flip_image;
       
   532 	uint i;
       
   533 
   505 
   534 	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
   506 	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
   535 
   507 
   536 	for (i = 1; i < 10; i++) {
   508 	for (uint i = 1; i < 10; i++) {
   537 		callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, v);
   509 		uint16 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, v);
   538 		if (callback == CALLBACK_FAILED || callback == 0xFF) return;
   510 		if (callback == CALLBACK_FAILED || callback == 0xFF) return;
   539 
   511 
   540 		/* Attempt to use pre-allocated vehicles until they run out. This can happen
   512 		/* Attempt to use pre-allocated vehicles until they run out. This can happen
   541 		 * if the callback returns different values depending on the cargo type. */
   513 		 * if the callback returns different values depending on the cargo type. */
   542 		u->next = vl[i];
   514 		u->next = vl[i];
   543 		if (u->next == NULL) u->next = AllocateVehicle();
   515 		if (u->next == NULL) u->next = AllocateVehicle();
   544 		if (u->next == NULL) return;
   516 		if (u->next == NULL) return;
   545 
   517 
   546 		u = u->next;
   518 		u = u->next;
   547 
   519 
   548 		engine_type = GB(callback, 0, 7);
   520 		EngineID engine_type = GB(callback, 0, 7);
   549 		flip_image = HASBIT(callback, 7);
   521 		bool flip_image = HASBIT(callback, 7);
   550 		rvi_artic = RailVehInfo(engine_type);
   522 		const RailVehicleInfo *rvi_artic = RailVehInfo(engine_type);
   551 
   523 
   552 		// get common values from first engine
   524 		// get common values from first engine
   553 		u->direction = v->direction;
   525 		u->direction = v->direction;
   554 		u->owner = v->owner;
   526 		u->owner = v->owner;
   555 		u->tile = v->tile;
   527 		u->tile = v->tile;
   583 	}
   555 	}
   584 }
   556 }
   585 
   557 
   586 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   558 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   587 {
   559 {
   588 	int32 value;
       
   589 	const RailVehicleInfo *rvi;
       
   590 	uint num_vehicles;
       
   591 
       
   592 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   560 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   593 
   561 
   594 	rvi = RailVehInfo(engine);
   562 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   595 	value = (rvi->base_cost * _price.build_railwagon) >> 8;
   563 	int32 value = (rvi->base_cost * _price.build_railwagon) >> 8;
   596 
   564 
   597 	num_vehicles = 1 + CountArticulatedParts(engine);
   565 	uint num_vehicles = 1 + CountArticulatedParts(engine);
   598 
   566 
   599 	if (!(flags & DC_QUERY_COST)) {
   567 	if (!(flags & DC_QUERY_COST)) {
   600 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   568 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   601 		Vehicle* v;
       
   602 		int x;
       
   603 		int y;
       
   604 
   569 
   605 		memset(&vl, 0, sizeof(vl));
   570 		memset(&vl, 0, sizeof(vl));
   606 
   571 
   607 		if (!AllocateVehicles(vl, num_vehicles))
   572 		if (!AllocateVehicles(vl, num_vehicles))
   608 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   573 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   609 
   574 
   610 		if (flags & DC_EXEC) {
   575 		if (flags & DC_EXEC) {
   611 			Vehicle *u, *w;
   576 			Vehicle *v = vl[0];
   612 			DiagDirection dir;
       
   613 
       
   614 			v = vl[0];
       
   615 			v->spritenum = rvi->image_index;
   577 			v->spritenum = rvi->image_index;
   616 
   578 
   617 			u = NULL;
   579 			Vehicle *u = NULL;
   618 
   580 
       
   581 			Vehicle *w;
   619 			FOR_ALL_VEHICLES(w) {
   582 			FOR_ALL_VEHICLES(w) {
   620 				if (w->type == VEH_Train && w->tile == tile &&
   583 				if (w->type == VEH_Train && w->tile == tile &&
   621 				    IsFreeWagon(w) && w->engine_type == engine) {
   584 				    IsFreeWagon(w) && w->engine_type == engine) {
   622 					u = GetLastVehicleInChain(w);
   585 					u = GetLastVehicleInChain(w);
   623 					break;
   586 					break;
   624 				}
   587 				}
   625 			}
   588 			}
   626 
   589 
   627 			v->engine_type = engine;
   590 			v->engine_type = engine;
   628 
   591 
   629 			dir = GetRailDepotDirection(tile);
   592 			DiagDirection dir = GetRailDepotDirection(tile);
   630 
   593 
   631 			v->direction = DiagDirToDir(dir);
   594 			v->direction = DiagDirToDir(dir);
   632 			v->tile = tile;
   595 			v->tile = tile;
   633 
   596 
   634 			x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
   597 			int x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
   635 			y = TileY(tile) * TILE_SIZE | _vehicle_initial_y_fract[dir];
   598 			int y = TileY(tile) * TILE_SIZE | _vehicle_initial_y_fract[dir];
   636 
   599 
   637 			v->x_pos = x;
   600 			v->x_pos = x;
   638 			v->y_pos = y;
   601 			v->y_pos = y;
   639 			v->z_pos = GetSlopeZ(x,y);
   602 			v->z_pos = GetSlopeZ(x, y);
   640 			v->owner = _current_player;
   603 			v->owner = _current_player;
   641 			v->z_height = 6;
   604 			v->z_height = 6;
   642 			v->u.rail.track = TRACK_BIT_DEPOT;
   605 			v->u.rail.track = TRACK_BIT_DEPOT;
   643 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   606 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   644 
   607 
   738  * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
   701  * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
   739  *           bit 1 prevents any free cars from being added to the train
   702  *           bit 1 prevents any free cars from being added to the train
   740  */
   703  */
   741 int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   704 int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   742 {
   705 {
   743 	const RailVehicleInfo *rvi;
       
   744 	int value;
       
   745 	Vehicle *v;
       
   746 	UnitID unit_num;
       
   747 	uint num_vehicles;
       
   748 
       
   749 	/* Check if the engine-type is valid (for the player) */
   706 	/* Check if the engine-type is valid (for the player) */
   750 	if (!IsEngineBuildable(p1, VEH_Train, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
   707 	if (!IsEngineBuildable(p1, VEH_Train, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
   751 
   708 
   752 	/* Check if the train is actually being built in a depot belonging
   709 	/* Check if the train is actually being built in a depot belonging
   753 	 * to the player. Doesn't matter if only the cost is queried */
   710 	 * to the player. Doesn't matter if only the cost is queried */
   756 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   713 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   757 	}
   714 	}
   758 
   715 
   759 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   716 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   760 
   717 
   761 	rvi = RailVehInfo(p1);
   718 	const RailVehicleInfo *rvi = RailVehInfo(p1);
   762 
   719 
   763 	/* Check if depot and new engine uses the same kind of tracks */
   720 	/* Check if depot and new engine uses the same kind of tracks */
   764 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   721 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   765 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   722 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   766 
   723 
   767 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   724 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   768 
   725 
   769 	value = EstimateTrainCost(rvi);
   726 	int32 value = EstimateTrainCost(rvi);
   770 
   727 
   771 	num_vehicles = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 2 : 1;
   728 	uint num_vehicles =
   772 	num_vehicles += CountArticulatedParts(p1);
   729 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
       
   730 		CountArticulatedParts(p1);
   773 
   731 
   774 	if (!(flags & DC_QUERY_COST)) {
   732 	if (!(flags & DC_QUERY_COST)) {
   775 		Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads
   733 		Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads
   776 
   734 
   777 		memset(&vl, 0, sizeof(vl));
   735 		memset(&vl, 0, sizeof(vl));
   778 
   736 
   779 		if (!AllocateVehicles(vl, num_vehicles))
   737 		if (!AllocateVehicles(vl, num_vehicles))
   780 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   738 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   781 
   739 
   782 		v = vl[0];
   740 		Vehicle *v = vl[0];
   783 
   741 
   784 		unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Train);
   742 		UnitID unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Train);
   785 		if (unit_num > _patches.max_trains)
   743 		if (unit_num > _patches.max_trains)
   786 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   744 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   787 
   745 
   788 		if (flags & DC_EXEC) {
   746 		if (flags & DC_EXEC) {
   789 			DiagDirection dir = GetRailDepotDirection(tile);
   747 			DiagDirection dir = GetRailDepotDirection(tile);
   794 			v->direction = DiagDirToDir(dir);
   752 			v->direction = DiagDirToDir(dir);
   795 			v->tile = tile;
   753 			v->tile = tile;
   796 			v->owner = _current_player;
   754 			v->owner = _current_player;
   797 			v->x_pos = x;
   755 			v->x_pos = x;
   798 			v->y_pos = y;
   756 			v->y_pos = y;
   799 			v->z_pos = GetSlopeZ(x,y);
   757 			v->z_pos = GetSlopeZ(x, y);
   800 			v->z_height = 6;
   758 			v->z_height = 6;
   801 			v->u.rail.track = TRACK_BIT_DEPOT;
   759 			v->u.rail.track = TRACK_BIT_DEPOT;
   802 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   760 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   803 			v->spritenum = rvi->image_index;
   761 			v->spritenum = rvi->image_index;
   804 			v->cargo_type = rvi->cargo_type;
   762 			v->cargo_type = rvi->cargo_type;
   869 
   827 
   870 /* Check if all the wagons of the given train are in a depot, returns the
   828 /* Check if all the wagons of the given train are in a depot, returns the
   871  * number of cars (including loco) then. If not it returns -1 */
   829  * number of cars (including loco) then. If not it returns -1 */
   872 int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped)
   830 int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped)
   873 {
   831 {
   874 	int count;
       
   875 	TileIndex tile = v->tile;
   832 	TileIndex tile = v->tile;
   876 
   833 
   877 	/* check if stopped in a depot */
   834 	/* check if stopped in a depot */
   878 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
   835 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
   879 
   836 
   880 	count = 0;
   837 	int count = 0;
   881 	for (; v != NULL; v = v->next) {
   838 	for (; v != NULL; v = v->next) {
   882 		/* This count is used by the depot code to determine the number of engines
   839 		/* This count is used by the depot code to determine the number of engines
   883 		 * in the consist. Exclude articulated parts so that autoreplacing to
   840 		 * in the consist. Exclude articulated parts so that autoreplacing to
   884 		 * engines with more articulated parts than before works correctly.
   841 		 * engines with more articulated parts than before works correctly.
   885 		 *
   842 		 *
   901 }
   858 }
   902 
   859 
   903 /* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
   860 /* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
   904 inline bool CheckTrainIsInsideDepot(const Vehicle *v)
   861 inline bool CheckTrainIsInsideDepot(const Vehicle *v)
   905 {
   862 {
   906 	return (CheckTrainInDepot(v, false) > 0);
   863 	return CheckTrainInDepot(v, false) > 0;
   907 }
   864 }
   908 
   865 
   909 /**
   866 /**
   910  * Unlink a rail wagon from the consist.
   867  * Unlink a rail wagon from the consist.
   911  * @param v Vehicle to remove.
   868  * @param v Vehicle to remove.
   912  * @param first The first vehicle of the consist.
   869  * @param first The first vehicle of the consist.
   913  * @return The first vehicle of the consist.
   870  * @return The first vehicle of the consist.
   914  */
   871  */
   915 static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
   872 static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
   916 {
   873 {
   917 	Vehicle *u;
       
   918 
       
   919 	// unlinking the first vehicle of the chain?
   874 	// unlinking the first vehicle of the chain?
   920 	if (v == first) {
   875 	if (v == first) {
   921 		v = GetNextVehicle(v);
   876 		v = GetNextVehicle(v);
   922 		if (v == NULL) return NULL;
   877 		if (v == NULL) return NULL;
   923 
   878 
   924 		if (IsTrainWagon(v)) SetFreeWagon(v);
   879 		if (IsTrainWagon(v)) SetFreeWagon(v);
   925 
   880 
   926 		return v;
   881 		return v;
   927 	}
   882 	}
   928 
   883 
       
   884 	Vehicle *u;
   929 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   885 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   930 	GetLastEnginePart(u)->next = GetNextVehicle(v);
   886 	GetLastEnginePart(u)->next = GetNextVehicle(v);
   931 	return first;
   887 	return first;
   932 }
   888 }
   933 
   889 
   971  * move around on the train so rear engines are placed correctly according to the other engines
   927  * move around on the train so rear engines are placed correctly according to the other engines
   972  * always call with the front engine
   928  * always call with the front engine
   973  */
   929  */
   974 static void NormaliseTrainConsist(Vehicle *v)
   930 static void NormaliseTrainConsist(Vehicle *v)
   975 {
   931 {
   976 	Vehicle *u;
       
   977 
       
   978 	if (IsFreeWagon(v)) return;
   932 	if (IsFreeWagon(v)) return;
   979 
   933 
   980 	assert(IsFrontEngine(v));
   934 	assert(IsFrontEngine(v));
   981 
   935 
   982 	for (; v != NULL; v = GetNextVehicle(v)) {
   936 	for (; v != NULL; v = GetNextVehicle(v)) {
   983 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
   937 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
   984 
   938 
   985 		/* make sure that there are no free cars before next engine */
   939 		/* make sure that there are no free cars before next engine */
   986 		for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next);
   940 		Vehicle *u;
       
   941 		for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next) {}
   987 
   942 
   988 		if (u == v->u.rail.other_multiheaded_part) continue;
   943 		if (u == v->u.rail.other_multiheaded_part) continue;
   989 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
   944 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
   990 	}
   945 	}
   991 }
   946 }
   999  */
   954  */
  1000 int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   955 int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1001 {
   956 {
  1002 	VehicleID s = GB(p1, 0, 16);
   957 	VehicleID s = GB(p1, 0, 16);
  1003 	VehicleID d = GB(p1, 16, 16);
   958 	VehicleID d = GB(p1, 16, 16);
  1004 	Vehicle *src, *dst, *src_head, *dst_head;
       
  1005 
   959 
  1006 	if (!IsValidVehicleID(s)) return CMD_ERROR;
   960 	if (!IsValidVehicleID(s)) return CMD_ERROR;
  1007 
   961 
  1008 	src = GetVehicle(s);
   962 	Vehicle *src = GetVehicle(s);
  1009 
   963 
  1010 	if (src->type != VEH_Train || !CheckOwnership(src->owner)) return CMD_ERROR;
   964 	if (src->type != VEH_Train || !CheckOwnership(src->owner)) return CMD_ERROR;
  1011 
   965 
  1012 	// if nothing is selected as destination, try and find a matching vehicle to drag to.
   966 	// if nothing is selected as destination, try and find a matching vehicle to drag to.
       
   967 	Vehicle *dst;
  1013 	if (d == INVALID_VEHICLE) {
   968 	if (d == INVALID_VEHICLE) {
  1014 		dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
   969 		dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
  1015 	} else {
   970 	} else {
  1016 		if (!IsValidVehicleID(d)) return CMD_ERROR;
   971 		if (!IsValidVehicleID(d)) return CMD_ERROR;
  1017 		dst = GetVehicle(d);
   972 		dst = GetVehicle(d);
  1026 
   981 
  1027 	// don't move the same vehicle..
   982 	// don't move the same vehicle..
  1028 	if (src == dst) return 0;
   983 	if (src == dst) return 0;
  1029 
   984 
  1030 	/* locate the head of the two chains */
   985 	/* locate the head of the two chains */
  1031 	src_head = GetFirstVehicleInChain(src);
   986 	Vehicle *src_head = GetFirstVehicleInChain(src);
       
   987 	Vehicle *dst_head;
  1032 	if (dst != NULL) {
   988 	if (dst != NULL) {
  1033 		dst_head = GetFirstVehicleInChain(dst);
   989 		dst_head = GetFirstVehicleInChain(dst);
  1034 		if (dst_head->tile != src_head->tile) return CMD_ERROR;
   990 		if (dst_head->tile != src_head->tile) return CMD_ERROR;
  1035 		// Now deal with articulated part of destination wagon
   991 		// Now deal with articulated part of destination wagon
  1036 		dst = GetLastEnginePart(dst);
   992 		dst = GetLastEnginePart(dst);
  1053 		}
  1009 		}
  1054 	}
  1010 	}
  1055 
  1011 
  1056 	if (IsTrainEngine(src) && dst_head != NULL) {
  1012 	if (IsTrainEngine(src) && dst_head != NULL) {
  1057 		/* we need to make sure that we didn't place it between a pair of multiheaded engines */
  1013 		/* we need to make sure that we didn't place it between a pair of multiheaded engines */
  1058 		Vehicle *u, *engine = NULL;
  1014 		Vehicle *engine = NULL;
  1059 
  1015 
  1060 		for (u = dst_head; u != NULL; u = u->next) {
  1016 		for (Vehicle *u = dst_head; u != NULL; u = u->next) {
  1061 			if (IsTrainEngine(u) && IsMultiheaded(u) && u->u.rail.other_multiheaded_part != NULL) {
  1017 			if (IsTrainEngine(u) && IsMultiheaded(u) && u->u.rail.other_multiheaded_part != NULL) {
  1062 				engine = u;
  1018 				engine = u;
  1063 			}
  1019 			}
  1064 			if (engine != NULL && engine->u.rail.other_multiheaded_part == u) {
  1020 			if (engine != NULL && engine->u.rail.other_multiheaded_part == u) {
  1065 				engine = NULL;
  1021 				engine = NULL;
  1075 
  1031 
  1076 	// when moving all wagons, we can't have the same src_head and dst_head
  1032 	// when moving all wagons, we can't have the same src_head and dst_head
  1077 	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
  1033 	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
  1078 
  1034 
  1079 	{
  1035 	{
  1080 		int src_len = 0;
       
  1081 		int max_len = _patches.mammoth_trains ? 100 : 9;
  1036 		int max_len = _patches.mammoth_trains ? 100 : 9;
  1082 
  1037 
  1083 		// check if all vehicles in the source train are stopped inside a depot.
  1038 		// check if all vehicles in the source train are stopped inside a depot.
  1084 		src_len = CheckTrainStoppedInDepot(src_head);
  1039 		int src_len = CheckTrainStoppedInDepot(src_head);
  1085 		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1040 		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1086 
  1041 
  1087 		// check the destination row if the source and destination aren't the same.
  1042 		// check the destination row if the source and destination aren't the same.
  1088 		if (src_head != dst_head) {
  1043 		if (src_head != dst_head) {
  1089 			int dst_len = 0;
  1044 			int dst_len = 0;
  1140 	}
  1095 	}
  1141 
  1096 
  1142 	/* do it? */
  1097 	/* do it? */
  1143 	if (flags & DC_EXEC) {
  1098 	if (flags & DC_EXEC) {
  1144 		/* clear the ->first cache */
  1099 		/* clear the ->first cache */
  1145 		{
  1100 		for (Vehicle *u = src_head; u != NULL; u = u->next) u->first = NULL;
  1146 			Vehicle *u;
  1101 		for (Vehicle *u = dst_head; u != NULL; u = u->next) u->first = NULL;
  1147 
       
  1148 			for (u = src_head; u != NULL; u = u->next) u->first = NULL;
       
  1149 			for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
       
  1150 		}
       
  1151 
  1102 
  1152 		if (HASBIT(p2, 0)) {
  1103 		if (HASBIT(p2, 0)) {
  1153 			// unlink ALL wagons
  1104 			// unlink ALL wagons
  1154 			if (src != src_head) {
  1105 			if (src != src_head) {
  1155 				Vehicle *v = src_head;
  1106 				Vehicle *v = src_head;
  1253 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1204 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1254 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
  1205 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
  1255 			}
  1206 			}
  1256 			/* Update the depot window */
  1207 			/* Update the depot window */
  1257 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1208 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1258 		};
  1209 		}
  1259 
  1210 
  1260 		if (dst_head != NULL) {
  1211 		if (dst_head != NULL) {
  1261 			NormaliseTrainConsist(dst_head);
  1212 			NormaliseTrainConsist(dst_head);
  1262 			TrainConsistChanged(dst_head);
  1213 			TrainConsistChanged(dst_head);
  1263 			if (IsFrontEngine(dst_head)) {
  1214 			if (IsFrontEngine(dst_head)) {
  1282  * @param p1 train to start/stop
  1233  * @param p1 train to start/stop
  1283  * @param p2 unused
  1234  * @param p2 unused
  1284  */
  1235  */
  1285 int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1236 int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1286 {
  1237 {
  1287 	Vehicle *v;
       
  1288 	uint16 callback;
       
  1289 
       
  1290 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1238 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1291 
  1239 
  1292 	v = GetVehicle(p1);
  1240 	Vehicle *v = GetVehicle(p1);
  1293 
  1241 
  1294 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1242 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1295 
  1243 
  1296 	/* Check if this train can be started/stopped. The callback will fail or
  1244 	/* Check if this train can be started/stopped. The callback will fail or
  1297 	 * return 0xFF if it can. */
  1245 	 * return 0xFF if it can. */
  1298 	callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
  1246 	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
  1299 	if (callback != CALLBACK_FAILED && callback != 0xFF) {
  1247 	if (callback != CALLBACK_FAILED && callback != 0xFF) {
  1300 		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
  1248 		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
  1301 		return_cmd_error(error);
  1249 		return_cmd_error(error);
  1302 	}
  1250 	}
  1303 
  1251 
  1326  * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
  1274  * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
  1327  *           all wagons of the same type will go on the same line. Used by the AI currently
  1275  *           all wagons of the same type will go on the same line. Used by the AI currently
  1328  */
  1276  */
  1329 int32 CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1277 int32 CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1330 {
  1278 {
  1331 	Vehicle *v, *tmp, *first;
       
  1332 	Vehicle *new_f = NULL;
       
  1333 	int32 cost = 0;
       
  1334 
       
  1335 	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
  1279 	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
  1336 
  1280 
  1337 	v = GetVehicle(p1);
  1281 	Vehicle *v = GetVehicle(p1);
  1338 
  1282 
  1339 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1283 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1340 
  1284 
  1341 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1285 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1342 
  1286 
  1343 	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
  1287 	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
  1344 	first = GetFirstVehicleInChain(v);
  1288 	Vehicle *first = GetFirstVehicleInChain(v);
  1345 
  1289 
  1346 	// make sure the vehicle is stopped in the depot
  1290 	// make sure the vehicle is stopped in the depot
  1347 	if (CheckTrainStoppedInDepot(first) < 0) {
  1291 	if (CheckTrainStoppedInDepot(first) < 0) {
  1348 		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1292 		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1349 	}
  1293 	}
  1356 		}
  1300 		}
  1357 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1301 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1358 		RebuildVehicleLists();
  1302 		RebuildVehicleLists();
  1359 	}
  1303 	}
  1360 
  1304 
       
  1305 	int32 cost = 0;
  1361 	switch (p2) {
  1306 	switch (p2) {
  1362 		case 0: case 2: { /* Delete given wagon */
  1307 		case 0: case 2: { /* Delete given wagon */
  1363 			bool switch_engine = false;    // update second wagon to engine?
  1308 			bool switch_engine = false;    // update second wagon to engine?
  1364 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1309 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1365 
  1310 
  1378 			}
  1323 			}
  1379 
  1324 
  1380 			/* 2. We are selling the first engine, some special action might be required
  1325 			/* 2. We are selling the first engine, some special action might be required
  1381 			 * here, so take attention */
  1326 			 * here, so take attention */
  1382 			if ((flags & DC_EXEC) && v == first) {
  1327 			if ((flags & DC_EXEC) && v == first) {
  1383 				new_f = GetNextVehicle(first);
  1328 				Vehicle *new_f = GetNextVehicle(first);
  1384 
  1329 
  1385 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
  1330 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
  1386 				for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
  1331 				for (Vehicle *tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
  1387 
  1332 
  1388 				/* 2.2 If there are wagons present after the deleted front engine, check
  1333 				/* 2.2 If there are wagons present after the deleted front engine, check
  1389          * if the second wagon (which will be first) is an engine. If it is one,
  1334          * if the second wagon (which will be first) is an engine. If it is one,
  1390          * promote it as a new train, retaining the unitnumber, orders */
  1335          * promote it as a new train, retaining the unitnumber, orders */
  1391 				if (new_f != NULL) {
  1336 				if (new_f != NULL) {
  1439 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1384 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1440 				 * up on a new line to be added to the newly built loco. Replace it is.
  1385 				 * up on a new line to be added to the newly built loco. Replace it is.
  1441 				 * Totally braindead cause building a new engine adds all loco-less
  1386 				 * Totally braindead cause building a new engine adds all loco-less
  1442 				 * engines to its train anyways */
  1387 				 * engines to its train anyways */
  1443 				if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
  1388 				if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
       
  1389 					Vehicle *tmp;
  1444 					for (v = first; v != NULL; v = tmp) {
  1390 					for (v = first; v != NULL; v = tmp) {
  1445 						tmp = GetNextVehicle(v);
  1391 						tmp = GetNextVehicle(v);
  1446 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1392 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1447 					}
  1393 					}
  1448 				}
  1394 				}
  1450 		} break;
  1396 		} break;
  1451 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1397 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1452 			/* Start deleting every vehicle after the selected one
  1398 			/* Start deleting every vehicle after the selected one
  1453 			 * If we encounter a matching rear-engine to a front-engine
  1399 			 * If we encounter a matching rear-engine to a front-engine
  1454 			 * earlier in the chain (before deletion), leave it alone */
  1400 			 * earlier in the chain (before deletion), leave it alone */
       
  1401 			Vehicle *tmp;
  1455 			for (; v != NULL; v = tmp) {
  1402 			for (; v != NULL; v = tmp) {
  1456 				tmp = GetNextVehicle(v);
  1403 				tmp = GetNextVehicle(v);
  1457 
  1404 
  1458 				if (IsMultiheaded(v)) {
  1405 				if (IsMultiheaded(v)) {
  1459 					if (IsTrainEngine(v)) {
  1406 					if (IsTrainEngine(v)) {
  1537 	}
  1484 	}
  1538 }
  1485 }
  1539 
  1486 
  1540 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1487 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1541 {
  1488 {
  1542 	byte flag1, flag2;
  1489 	byte flag1 = *swap_flag1;
  1543 
  1490 	byte flag2 = *swap_flag2;
  1544 	flag1 = *swap_flag1;
       
  1545 	flag2 = *swap_flag2;
       
  1546 
  1491 
  1547 	/* Clear the flags */
  1492 	/* Clear the flags */
  1548 	CLRBIT(*swap_flag1, VRF_GOINGUP);
  1493 	CLRBIT(*swap_flag1, VRF_GOINGUP);
  1549 	CLRBIT(*swap_flag1, VRF_GOINGDOWN);
  1494 	CLRBIT(*swap_flag1, VRF_GOINGDOWN);
  1550 	CLRBIT(*swap_flag2, VRF_GOINGUP);
  1495 	CLRBIT(*swap_flag2, VRF_GOINGUP);
  1634  * @param v First vehicle in chain
  1579  * @param v First vehicle in chain
  1635  * @param before Set to true for the call before reversing, false otherwise
  1580  * @param before Set to true for the call before reversing, false otherwise
  1636  */
  1581  */
  1637 static void AdvanceWagons(Vehicle *v, bool before)
  1582 static void AdvanceWagons(Vehicle *v, bool before)
  1638 {
  1583 {
  1639 	Vehicle* base;
  1584 	Vehicle *base = v;
  1640 	Vehicle* first;
  1585 	Vehicle *first = base->next;
  1641 	int length;
  1586 	uint length = CountVehiclesInChain(v);
  1642 
       
  1643 	base = v;
       
  1644 	first = base->next;
       
  1645 	length = CountVehiclesInChain(v);
       
  1646 
  1587 
  1647 	while (length > 2) {
  1588 	while (length > 2) {
  1648 		Vehicle* last;
       
  1649 		int differential;
       
  1650 		int i;
       
  1651 
       
  1652 		// find pairwise matching wagon
  1589 		// find pairwise matching wagon
  1653 		// start<>end, start+1<>end-1, ...
  1590 		// start<>end, start+1<>end-1, ...
  1654 		last = first;
  1591 		Vehicle *last = first;
  1655 		for (i = length - 3; i > 0; i--) last = last->next;
  1592 		for (uint i = length - 3; i > 0; i--) last = last->next;
  1656 
  1593 
  1657 		differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1594 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1658 		if (before) differential *= -1;
  1595 		if (before) differential *= -1;
  1659 
  1596 
  1660 		if (differential > 0) {
  1597 		if (differential > 0) {
  1661 			Vehicle* tempnext;
       
  1662 
       
  1663 			// disconnect last car to make sure only this subset moves
  1598 			// disconnect last car to make sure only this subset moves
  1664 			tempnext = last->next;
  1599 			Vehicle *tempnext = last->next;
  1665 			last->next = NULL;
  1600 			last->next = NULL;
  1666 
  1601 
  1667 			for (i = 0; i < differential; i++) TrainController(first, false);
  1602 			for (int i = 0; i < differential; i++) TrainController(first, false);
  1668 
  1603 
  1669 			last->next = tempnext;
  1604 			last->next = tempnext;
  1670 		}
  1605 		}
  1671 
  1606 
  1672 		base = first;
  1607 		base = first;
  1676 }
  1611 }
  1677 
  1612 
  1678 
  1613 
  1679 static void ReverseTrainDirection(Vehicle *v)
  1614 static void ReverseTrainDirection(Vehicle *v)
  1680 {
  1615 {
  1681 	int l = 0, r = -1;
       
  1682 	Vehicle *u;
       
  1683 
       
  1684 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1616 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1685 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1617 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1686 	}
  1618 	}
  1687 
  1619 
  1688 	/* Check if we were approaching a rail/road-crossing */
  1620 	/* Check if we were approaching a rail/road-crossing */
  1700 		/* Check if the train left a rail/road-crossing */
  1632 		/* Check if the train left a rail/road-crossing */
  1701 		DisableTrainCrossing(tile);
  1633 		DisableTrainCrossing(tile);
  1702 	}
  1634 	}
  1703 
  1635 
  1704 	// count number of vehicles
  1636 	// count number of vehicles
  1705 	u = v;
  1637 	int r = -1;
       
  1638 	const Vehicle *u = v;
  1706 	do r++; while ( (u = u->next) != NULL );
  1639 	do r++; while ( (u = u->next) != NULL );
  1707 
  1640 
  1708 	AdvanceWagons(v, true);
  1641 	AdvanceWagons(v, true);
  1709 
  1642 
  1710 	/* swap start<>end, start+1<>end-1, ... */
  1643 	/* swap start<>end, start+1<>end-1, ... */
       
  1644 	int l = 0;
  1711 	do {
  1645 	do {
  1712 		ReverseTrainSwapVeh(v, l++, r--);
  1646 		ReverseTrainSwapVeh(v, l++, r--);
  1713 	} while (l <= r);
  1647 	} while (l <= r);
  1714 
  1648 
  1715 	AdvanceWagons(v, false);
  1649 	AdvanceWagons(v, false);
  1726  * @param p1 train to reverse
  1660  * @param p1 train to reverse
  1727  * @param p2 if true, reverse a unit in a train (needs to be in a depot)
  1661  * @param p2 if true, reverse a unit in a train (needs to be in a depot)
  1728  */
  1662  */
  1729 int32 CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1663 int32 CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1730 {
  1664 {
  1731 	Vehicle *v;
       
  1732 
       
  1733 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1665 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1734 
  1666 
  1735 	v = GetVehicle(p1);
  1667 	Vehicle *v = GetVehicle(p1);
  1736 
  1668 
  1737 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1669 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1738 
  1670 
  1739 	if (p2) {
  1671 	if (p2) {
  1740 		// turn a single unit around
  1672 		// turn a single unit around
  1741 		Vehicle *front;
       
  1742 
  1673 
  1743 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
  1674 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
  1744 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1675 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1745 		}
  1676 		}
  1746 
  1677 
  1747 		front = GetFirstVehicleInChain(v);
  1678 		Vehicle *front = GetFirstVehicleInChain(v);
  1748 		// make sure the vehicle is stopped in the depot
  1679 		// make sure the vehicle is stopped in the depot
  1749 		if (CheckTrainStoppedInDepot(front) < 0) {
  1680 		if (CheckTrainStoppedInDepot(front) < 0) {
  1750 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1681 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1751 		}
  1682 		}
  1752 
  1683 
  1777  * @param p1 train to ignore the red signal
  1708  * @param p1 train to ignore the red signal
  1778  * @param p2 unused
  1709  * @param p2 unused
  1779  */
  1710  */
  1780 int32 CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1711 int32 CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1781 {
  1712 {
  1782 	Vehicle *v;
       
  1783 
       
  1784 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1713 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1785 
  1714 
  1786 	v = GetVehicle(p1);
  1715 	Vehicle *v = GetVehicle(p1);
  1787 
  1716 
  1788 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1717 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1789 
  1718 
  1790 	if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
  1719 	if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
  1791 
  1720 
  1801  */
  1730  */
  1802 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1731 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1803 {
  1732 {
  1804 	CargoID new_cid = GB(p2, 0, 8);
  1733 	CargoID new_cid = GB(p2, 0, 8);
  1805 	byte new_subtype = GB(p2, 8, 8);
  1734 	byte new_subtype = GB(p2, 8, 8);
  1806 	Vehicle *v;
       
  1807 	int32 cost;
       
  1808 	uint num;
       
  1809 
  1735 
  1810 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1736 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1811 
  1737 
  1812 	v = GetVehicle(p1);
  1738 	Vehicle *v = GetVehicle(p1);
  1813 
  1739 
  1814 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1740 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1815 	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
  1741 	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
  1816 
  1742 
  1817 	/* Check cargo */
  1743 	/* Check cargo */
  1818 	if (new_cid > NUM_CARGO) return CMD_ERROR;
  1744 	if (new_cid > NUM_CARGO) return CMD_ERROR;
  1819 
  1745 
  1820 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  1746 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  1821 
  1747 
  1822 	cost = 0;
  1748 	int32 cost = 0;
  1823 	num = 0;
  1749 	uint num = 0;
  1824 
  1750 
  1825 	do {
  1751 	do {
  1826 		/* XXX: We also refit all the attached wagons en-masse if they
  1752 		/* XXX: We also refit all the attached wagons en-masse if they
  1827 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1753 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1828 		 * some nice [Refit] button near each wagon. --pasky */
  1754 		 * some nice [Refit] button near each wagon. --pasky */
  1829 		if (!CanRefitTo(v->engine_type, new_cid)) continue;
  1755 		if (!CanRefitTo(v->engine_type, new_cid)) continue;
  1830 
  1756 
  1831 		if (v->cargo_cap != 0) {
  1757 		if (v->cargo_cap != 0) {
  1832 			const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
       
  1833 			uint16 amount = CALLBACK_FAILED;
  1758 			uint16 amount = CALLBACK_FAILED;
  1834 
  1759 
  1835 			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
  1760 			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
  1836 				/* Back up the vehicle's cargo type */
  1761 				/* Back up the vehicle's cargo type */
  1837 				CargoID temp_cid = v->cargo_type;
  1762 				CargoID temp_cid = v->cargo_type;
  1844 				v->cargo_type = temp_cid;
  1769 				v->cargo_type = temp_cid;
  1845 				v->cargo_subtype = temp_subtype;
  1770 				v->cargo_subtype = temp_subtype;
  1846 			}
  1771 			}
  1847 
  1772 
  1848 			if (amount == CALLBACK_FAILED) { // callback failed or not used, use default
  1773 			if (amount == CALLBACK_FAILED) { // callback failed or not used, use default
       
  1774 				const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1849 				CargoID old_cid = rvi->cargo_type;
  1775 				CargoID old_cid = rvi->cargo_type;
  1850 				/* normally, the capacity depends on the cargo type, a rail vehicle can
  1776 				/* normally, the capacity depends on the cargo type, a rail vehicle can
  1851 				 * carry twice as much mail/goods as normal cargo, and four times as
  1777 				 * carry twice as much mail/goods as normal cargo, and four times as
  1852 				 * many passengers
  1778 				 * many passengers
  1853 				 */
  1779 				 */
  1862 					case CT_PASSENGERS: break;
  1788 					case CT_PASSENGERS: break;
  1863 					case CT_MAIL:
  1789 					case CT_MAIL:
  1864 					case CT_GOODS: amount /= 2; break;
  1790 					case CT_GOODS: amount /= 2; break;
  1865 					default:       amount /= 4; break;
  1791 					default:       amount /= 4; break;
  1866 				}
  1792 				}
  1867 			};
  1793 			}
  1868 
  1794 
  1869 			if (amount != 0) {
  1795 			if (amount != 0) {
  1870 				if (new_cid != v->cargo_type) {
  1796 				if (new_cid != v->cargo_type) {
  1871 					cost += GetRefitCost(v->engine_type);
  1797 					cost += GetRefitCost(v->engine_type);
  1872 				}
  1798 				}
  1920 
  1846 
  1921 // returns the tile of a depot to goto to. The given vehicle must not be
  1847 // returns the tile of a depot to goto to. The given vehicle must not be
  1922 // crashed!
  1848 // crashed!
  1923 static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
  1849 static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
  1924 {
  1850 {
       
  1851 	assert(!(v->vehstatus & VS_CRASHED));
       
  1852 
  1925 	TrainFindDepotData tfdd;
  1853 	TrainFindDepotData tfdd;
  1926 	TileIndex tile = v->tile;
       
  1927 
       
  1928 	assert(!(v->vehstatus & VS_CRASHED));
       
  1929 
       
  1930 	tfdd.owner = v->owner;
  1854 	tfdd.owner = v->owner;
  1931 	tfdd.best_length = (uint)-1;
  1855 	tfdd.best_length = (uint)-1;
  1932 	tfdd.reverse = false;
  1856 	tfdd.reverse = false;
  1933 
  1857 
  1934 	if (IsTileDepotType(tile, TRANSPORT_RAIL)){
  1858 	TileIndex tile = v->tile;
       
  1859 	if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
  1935 		tfdd.tile = tile;
  1860 		tfdd.tile = tile;
  1936 		tfdd.best_length = 0;
  1861 		tfdd.best_length = 0;
  1937 		return tfdd;
  1862 		return tfdd;
  1938 	}
  1863 	}
  1939 
  1864 
  1940 	if (_patches.yapf.rail_use_yapf) {
  1865 	if (_patches.yapf.rail_use_yapf) {
  1941 		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  1866 		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  1942 		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
  1867 		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
  1943 	} else if (_patches.new_pathfinding_all) {
  1868 	} else if (_patches.new_pathfinding_all) {
  1944 		NPFFoundTargetData ftd;
       
  1945 		Vehicle* last = GetLastVehicleInChain(v);
  1869 		Vehicle* last = GetLastVehicleInChain(v);
  1946 		Trackdir trackdir = GetVehicleTrackdir(v);
  1870 		Trackdir trackdir = GetVehicleTrackdir(v);
  1947 		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  1871 		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  1948 
  1872 
  1949 		assert (trackdir != INVALID_TRACKDIR);
  1873 		assert(trackdir != INVALID_TRACKDIR);
  1950 		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
  1874 		NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
  1951 		if (ftd.best_bird_dist == 0) {
  1875 		if (ftd.best_bird_dist == 0) {
  1952 			/* Found target */
  1876 			/* Found target */
  1953 			tfdd.tile = ftd.node.tile;
  1877 			tfdd.tile = ftd.node.tile;
  1954 			/* Our caller expects a number of tiles, so we just approximate that
  1878 			/* Our caller expects a number of tiles, so we just approximate that
  1955 			 * number by this. It might not be completely what we want, but it will
  1879 			 * number by this. It might not be completely what we want, but it will
  1958 			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  1882 			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  1959 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  1883 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  1960 		}
  1884 		}
  1961 	} else {
  1885 	} else {
  1962 		// search in the forward direction first.
  1886 		// search in the forward direction first.
  1963 		DiagDirection i;
  1887 		DiagDirection i = DirToDiagDir(v->direction);
  1964 
       
  1965 		i = DirToDiagDir(v->direction);
       
  1966 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
  1888 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
  1967 			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
  1889 			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
  1968 		}
  1890 		}
  1969 		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  1891 		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  1970 		if (tfdd.best_length == (uint)-1){
  1892 		if (tfdd.best_length == (uint)-1){
  1988  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
  1910  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
  1989  * - p2 bit 8-10 - VLW flag (for mass goto depot)
  1911  * - p2 bit 8-10 - VLW flag (for mass goto depot)
  1990  */
  1912  */
  1991 int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1913 int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1992 {
  1914 {
  1993 	Vehicle *v;
       
  1994 	TrainFindDepotData tfdd;
       
  1995 
       
  1996 	if (p2 & DEPOT_MASS_SEND) {
  1915 	if (p2 & DEPOT_MASS_SEND) {
  1997 		/* Mass goto depot requested */
  1916 		/* Mass goto depot requested */
  1998 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
  1917 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
  1999 		return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
  1918 		return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
  2000 	}
  1919 	}
  2001 
  1920 
  2002 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1921 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  2003 
  1922 
  2004 	v = GetVehicle(p1);
  1923 	Vehicle *v = GetVehicle(p1);
  2005 
  1924 
  2006 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1925 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  2007 
  1926 
  2008 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  1927 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  2009 
  1928 
  2035 
  1954 
  2036 	/* check if at a standstill (not stopped only) in a depot
  1955 	/* check if at a standstill (not stopped only) in a depot
  2037 	 * the check is down here to make it possible to alter stop/service for trains entering the depot */
  1956 	 * the check is down here to make it possible to alter stop/service for trains entering the depot */
  2038 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && v->cur_speed == 0) return CMD_ERROR;
  1957 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && v->cur_speed == 0) return CMD_ERROR;
  2039 
  1958 
  2040 	tfdd = FindClosestTrainDepot(v, 0);
  1959 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0);
  2041 	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
  1960 	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
  2042 
  1961 
  2043 	if (flags & DC_EXEC) {
  1962 	if (flags & DC_EXEC) {
  2044 		v->dest_tile = tfdd.tile;
  1963 		v->dest_tile = tfdd.tile;
  2045 		v->current_order.type = OT_GOTO_DEPOT;
  1964 		v->current_order.type = OT_GOTO_DEPOT;
  2066 	1, 1, 1, 0, -1, -1, -1, 0
  1985 	1, 1, 1, 0, -1, -1, -1, 0
  2067 };
  1986 };
  2068 
  1987 
  2069 static void HandleLocomotiveSmokeCloud(const Vehicle* v)
  1988 static void HandleLocomotiveSmokeCloud(const Vehicle* v)
  2070 {
  1989 {
  2071 	const Vehicle* u;
       
  2072 	bool sound = false;
  1990 	bool sound = false;
  2073 
  1991 
  2074 	if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2)
  1992 	if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2)
  2075 		return;
  1993 		return;
  2076 
  1994 
  2077 	u = v;
  1995 	const Vehicle* u = v;
  2078 
  1996 
  2079 	do {
  1997 	do {
  2080 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1998 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  2081 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  1999 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  2082 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  2000 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  2083 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
  2001 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
  2084 		int x, y;
       
  2085 
  2002 
  2086 		// no smoke?
  2003 		// no smoke?
  2087 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  2004 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  2088 				disable_effect ||
  2005 				disable_effect ||
  2089 				rvi->railtype > RAILTYPE_ELECTRIC ||
  2006 				rvi->railtype > RAILTYPE_ELECTRIC ||
  2102 			effect_type = rvi->engclass;
  2019 			effect_type = rvi->engclass;
  2103 		} else {
  2020 		} else {
  2104 			effect_type--;
  2021 			effect_type--;
  2105 		}
  2022 		}
  2106 
  2023 
  2107 		x = _vehicle_smoke_pos[v->direction] * effect_offset;
  2024 		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
  2108 		y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
  2025 		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
  2109 
  2026 
  2110 		if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  2027 		if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  2111 			x = -x;
  2028 			x = -x;
  2112 			y = -y;
  2029 			y = -y;
  2113 		}
  2030 		}
  2148 		SND_04_TRAIN,
  2065 		SND_04_TRAIN,
  2149 		SND_0A_TRAIN_HORN,
  2066 		SND_0A_TRAIN_HORN,
  2150 		SND_0A_TRAIN_HORN
  2067 		SND_0A_TRAIN_HORN
  2151 	};
  2068 	};
  2152 
  2069 
       
  2070 	if (PlayVehicleSound(v, VSE_START)) return;
       
  2071 
  2153 	EngineID engtype = v->engine_type;
  2072 	EngineID engtype = v->engine_type;
  2154 
       
  2155 	if (PlayVehicleSound(v, VSE_START)) return;
       
  2156 
       
  2157 	switch (RailVehInfo(engtype)->railtype) {
  2073 	switch (RailVehInfo(engtype)->railtype) {
  2158 		case RAILTYPE_RAIL:
  2074 		case RAILTYPE_RAIL:
  2159 		case RAILTYPE_ELECTRIC:
  2075 		case RAILTYPE_ELECTRIC:
  2160 			SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
  2076 			SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
  2161 			break;
  2077 			break;
  2166 	}
  2082 	}
  2167 }
  2083 }
  2168 
  2084 
  2169 static bool CheckTrainStayInDepot(Vehicle *v)
  2085 static bool CheckTrainStayInDepot(Vehicle *v)
  2170 {
  2086 {
  2171 	Vehicle *u;
       
  2172 
       
  2173 	// bail out if not all wagons are in the same depot or not in a depot at all
  2087 	// bail out if not all wagons are in the same depot or not in a depot at all
  2174 	for (u = v; u != NULL; u = u->next) {
  2088 	for (const Vehicle *u = v; u != NULL; u = u->next) {
  2175 		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
  2089 		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
  2176 	}
  2090 	}
  2177 
  2091 
  2178 	// if the train got no power, then keep it in the depot
  2092 	// if the train got no power, then keep it in the depot
  2179 	if (v->u.rail.cached_power == 0) {
  2093 	if (v->u.rail.cached_power == 0) {
  2241 		 * approximation of where the station is */
  2155 		 * approximation of where the station is */
  2242 		// found station
  2156 		// found station
  2243 		ttfd->best_track = track;
  2157 		ttfd->best_track = track;
  2244 		return true;
  2158 		return true;
  2245 	} else {
  2159 	} else {
  2246 		uint dist;
       
  2247 
       
  2248 		// didn't find station, keep track of the best path so far.
  2160 		// didn't find station, keep track of the best path so far.
  2249 		dist = DistanceManhattan(tile, ttfd->dest_coords);
  2161 		uint dist = DistanceManhattan(tile, ttfd->dest_coords);
  2250 		if (dist < ttfd->best_bird_dist) {
  2162 		if (dist < ttfd->best_bird_dist) {
  2251 			ttfd->best_bird_dist = dist;
  2163 			ttfd->best_bird_dist = dist;
  2252 			ttfd->best_track = track;
  2164 			ttfd->best_track = track;
  2253 		}
  2165 		}
  2254 		return false;
  2166 		return false;
  2293 static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
  2205 static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
  2294 
  2206 
  2295 /* choose a track */
  2207 /* choose a track */
  2296 static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
  2208 static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
  2297 {
  2209 {
  2298 	TrainTrackFollowerData fd;
       
  2299 	Track best_track;
  2210 	Track best_track;
  2300 	// pathfinders are able to tell that route was only 'guessed'
  2211 	// pathfinders are able to tell that route was only 'guessed'
  2301 	bool path_not_found = false;
  2212 	bool path_not_found = false;
  2302 
  2213 
  2303 #ifdef PF_BENCHMARK
  2214 #ifdef PF_BENCHMARK
  2316 		} else {
  2227 		} else {
  2317 			best_track = FindFirstTrack(tracks);
  2228 			best_track = FindFirstTrack(tracks);
  2318 		}
  2229 		}
  2319 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2230 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2320 		void* perf = NpfBeginInterval();
  2231 		void* perf = NpfBeginInterval();
  2321 		int time = 0;
       
  2322 
  2232 
  2323 		NPFFindStationOrTileData fstd;
  2233 		NPFFindStationOrTileData fstd;
  2324 		NPFFoundTargetData ftd;
       
  2325 		Trackdir trackdir;
       
  2326 
       
  2327 		NPFFillWithOrderData(&fstd, v);
  2234 		NPFFillWithOrderData(&fstd, v);
  2328 		/* The enterdir for the new tile, is the exitdir for the old tile */
  2235 		/* The enterdir for the new tile, is the exitdir for the old tile */
  2329 		trackdir = GetVehicleTrackdir(v);
  2236 		Trackdir trackdir = GetVehicleTrackdir(v);
  2330 		assert(trackdir != 0xff);
  2237 		assert(trackdir != 0xff);
  2331 
  2238 
  2332 		ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
  2239 		NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
  2333 
  2240 
  2334 		if (ftd.best_trackdir == 0xff) {
  2241 		if (ftd.best_trackdir == 0xff) {
  2335 			/* We are already at our target. Just do something */
  2242 			/* We are already at our target. Just do something */
  2336 			//TODO: maybe display error?
  2243 			//TODO: maybe display error?
  2337 			//TODO: go straight ahead if possible?
  2244 			//TODO: go straight ahead if possible?
  2344 			if (ftd.best_bird_dist != 0) path_not_found = true;
  2251 			if (ftd.best_bird_dist != 0) path_not_found = true;
  2345 			/* Discard enterdir information, making it a normal track */
  2252 			/* Discard enterdir information, making it a normal track */
  2346 			best_track = TrackdirToTrack(ftd.best_trackdir);
  2253 			best_track = TrackdirToTrack(ftd.best_trackdir);
  2347 		}
  2254 		}
  2348 
  2255 
  2349 		time = NpfEndInterval(perf);
  2256 		int time = NpfEndInterval(perf);
  2350 		DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
  2257 		DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
  2351 	} else {
  2258 	} else {
  2352 		void* perf = NpfBeginInterval();
  2259 		void* perf = NpfBeginInterval();
  2353 		int time = 0;
  2260 
  2354 
  2261 		TrainTrackFollowerData fd;
  2355 		FillWithStationData(&fd, v);
  2262 		FillWithStationData(&fd, v);
  2356 
  2263 
  2357 		/* New train pathfinding */
  2264 		/* New train pathfinding */
  2358 		fd.best_bird_dist = (uint)-1;
  2265 		fd.best_bird_dist = (uint)-1;
  2359 		fd.best_track_dist = (uint)-1;
  2266 		fd.best_track_dist = (uint)-1;
  2370 			best_track = FindFirstTrack(tracks);
  2277 			best_track = FindFirstTrack(tracks);
  2371 		} else {
  2278 		} else {
  2372 			best_track = TrackdirToTrack(fd.best_track);
  2279 			best_track = TrackdirToTrack(fd.best_track);
  2373 		}
  2280 		}
  2374 
  2281 
  2375 		time = NpfEndInterval(perf);
  2282 		int time = NpfEndInterval(perf);
  2376 		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
  2283 		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
  2377 	}
  2284 	}
  2378 	// handle "path not found" state
  2285 	// handle "path not found" state
  2379 	if (path_not_found) {
  2286 	if (path_not_found) {
  2380 		// PF didn't find the route
  2287 		// PF didn't find the route
  2408 }
  2315 }
  2409 
  2316 
  2410 
  2317 
  2411 static bool CheckReverseTrain(Vehicle *v)
  2318 static bool CheckReverseTrain(Vehicle *v)
  2412 {
  2319 {
  2413 	TrainTrackFollowerData fd;
       
  2414 	int i, r;
       
  2415 	int best_track;
       
  2416 	uint best_bird_dist  = 0;
       
  2417 	uint best_track_dist = 0;
       
  2418 	uint reverse, reverse_best;
       
  2419 
       
  2420 	if (_opt.diff.line_reverse_mode != 0 ||
  2320 	if (_opt.diff.line_reverse_mode != 0 ||
  2421 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2321 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2422 			!(v->direction & 1))
  2322 			!(v->direction & 1))
  2423 		return false;
  2323 		return false;
  2424 
  2324 
       
  2325 	TrainTrackFollowerData fd;
  2425 	FillWithStationData(&fd, v);
  2326 	FillWithStationData(&fd, v);
  2426 
  2327 
  2427 	best_track = -1;
  2328 	uint reverse_best = 0;
  2428 	reverse_best = reverse = 0;
       
  2429 
  2329 
  2430 	assert(v->u.rail.track);
  2330 	assert(v->u.rail.track);
  2431 
  2331 
  2432 	i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
  2332 	int i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
  2433 
  2333 
  2434 	if (_patches.yapf.rail_use_yapf) {
  2334 	if (_patches.yapf.rail_use_yapf) {
  2435 		reverse_best = YapfCheckReverseTrain(v);
  2335 		reverse_best = YapfCheckReverseTrain(v);
  2436 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2336 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2437 		NPFFindStationOrTileData fstd;
  2337 		NPFFindStationOrTileData fstd;
  2456 			} else {
  2356 			} else {
  2457 				reverse_best = false;
  2357 				reverse_best = false;
  2458 			}
  2358 			}
  2459 		}
  2359 		}
  2460 	} else {
  2360 	} else {
       
  2361 		int best_track = -1;
       
  2362 		uint reverse = 0;
       
  2363 		uint best_bird_dist  = 0;
       
  2364 		uint best_track_dist = 0;
       
  2365 
  2461 		for (;;) {
  2366 		for (;;) {
  2462 			fd.best_bird_dist = (uint)-1;
  2367 			fd.best_bird_dist = (uint)-1;
  2463 			fd.best_track_dist = (uint)-1;
  2368 			fd.best_track_dist = (uint)-1;
  2464 
  2369 
  2465 			NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
  2370 			NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
  2485 					}
  2390 					}
  2486 				}
  2391 				}
  2487 
  2392 
  2488 				/* if we reach this position, there's two paths of equal value so far.
  2393 				/* if we reach this position, there's two paths of equal value so far.
  2489 				 * pick one randomly. */
  2394 				 * pick one randomly. */
  2490 				r = GB(Random(), 0, 8);
  2395 				int r = GB(Random(), 0, 8);
  2491 				if (_pick_track_table[i] == (v->direction & 3)) r += 80;
  2396 				if (_pick_track_table[i] == (v->direction & 3)) r += 80;
  2492 				if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
  2397 				if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
  2493 				if (r <= 127) goto bad;
  2398 				if (r <= 127) goto bad;
  2494 			}
  2399 			}
  2495 good:;
  2400 good:;
  2506 	return reverse_best != 0;
  2411 	return reverse_best != 0;
  2507 }
  2412 }
  2508 
  2413 
  2509 static bool ProcessTrainOrder(Vehicle *v)
  2414 static bool ProcessTrainOrder(Vehicle *v)
  2510 {
  2415 {
  2511 	const Order *order;
       
  2512 	bool at_waypoint = false;
       
  2513 
       
  2514 	switch (v->current_order.type) {
  2416 	switch (v->current_order.type) {
  2515 		case OT_GOTO_DEPOT:
  2417 		case OT_GOTO_DEPOT:
  2516 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return false;
  2418 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return false;
  2517 			if ((v->current_order.flags & OF_SERVICE_IF_NEEDED) &&
  2419 			if ((v->current_order.flags & OF_SERVICE_IF_NEEDED) &&
  2518 					!VehicleNeedsService(v)) {
  2420 					!VehicleNeedsService(v)) {
  2526 
  2428 
  2527 		default: break;
  2429 		default: break;
  2528 	}
  2430 	}
  2529 
  2431 
  2530 	// check if we've reached the waypoint?
  2432 	// check if we've reached the waypoint?
       
  2433 	bool at_waypoint = false;
  2531 	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
  2434 	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
  2532 		v->cur_order_index++;
  2435 		v->cur_order_index++;
  2533 		at_waypoint = true;
  2436 		at_waypoint = true;
  2534 	}
  2437 	}
  2535 
  2438 
  2542 	}
  2445 	}
  2543 
  2446 
  2544 	// Get the current order
  2447 	// Get the current order
  2545 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
  2448 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
  2546 
  2449 
  2547 	order = GetVehicleOrder(v, v->cur_order_index);
  2450 	const Order *order = GetVehicleOrder(v, v->cur_order_index);
  2548 
  2451 
  2549 	// If no order, do nothing.
  2452 	// If no order, do nothing.
  2550 	if (order == NULL) {
  2453 	if (order == NULL) {
  2551 		v->current_order.type = OT_NOTHING;
  2454 		v->current_order.type = OT_NOTHING;
  2552 		v->current_order.flags = 0;
  2455 		v->current_order.flags = 0;
  2647 	InvalidateVehicleOrder(v);
  2550 	InvalidateVehicleOrder(v);
  2648 }
  2551 }
  2649 
  2552 
  2650 static int UpdateTrainSpeed(Vehicle *v)
  2553 static int UpdateTrainSpeed(Vehicle *v)
  2651 {
  2554 {
  2652 	uint spd;
       
  2653 	uint accel;
  2555 	uint accel;
  2654 
  2556 
  2655 	if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) {
  2557 	if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) {
  2656 		if (_patches.realistic_acceleration) {
  2558 		if (_patches.realistic_acceleration) {
  2657 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2559 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2664 		} else {
  2566 		} else {
  2665 			accel = v->acceleration;
  2567 			accel = v->acceleration;
  2666 		}
  2568 		}
  2667 	}
  2569 	}
  2668 
  2570 
  2669 	spd = v->subspeed + accel * 2;
  2571 	uint spd = v->subspeed + accel * 2;
  2670 	v->subspeed = (byte)spd;
  2572 	v->subspeed = (byte)spd;
  2671 	{
  2573 	{
  2672 		int tempmax = v->max_speed;
  2574 		int tempmax = v->max_speed;
  2673 		if (v->cur_speed > v->max_speed)
  2575 		if (v->cur_speed > v->max_speed)
  2674 			tempmax = v->cur_speed - (v->cur_speed / 10) - 1;
  2576 			tempmax = v->cur_speed - (v->cur_speed / 10) - 1;
  2682 	return (spd >> 8);
  2584 	return (spd >> 8);
  2683 }
  2585 }
  2684 
  2586 
  2685 static void TrainEnterStation(Vehicle *v, StationID station)
  2587 static void TrainEnterStation(Vehicle *v, StationID station)
  2686 {
  2588 {
  2687 	Station *st;
       
  2688 	uint32 flags;
       
  2689 
       
  2690 	v->last_station_visited = station;
  2589 	v->last_station_visited = station;
  2691 
  2590 
  2692 	/* check if a train ever visited this station before */
  2591 	/* check if a train ever visited this station before */
  2693 	st = GetStation(station);
  2592 	Station *st = GetStation(station);
  2694 	if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
  2593 	if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
  2695 		st->had_vehicle_of_type |= HVOT_TRAIN;
  2594 		st->had_vehicle_of_type |= HVOT_TRAIN;
  2696 		SetDParam(0, st->index);
  2595 		SetDParam(0, st->index);
  2697 		flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
  2596 		uint32 flags = v->owner == _local_player ?
       
  2597 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) :
       
  2598 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ARRIVAL_OTHER,  0);
  2698 		AddNewsItem(
  2599 		AddNewsItem(
  2699 			STR_8801_CITIZENS_CELEBRATE_FIRST,
  2600 			STR_8801_CITIZENS_CELEBRATE_FIRST,
  2700 			flags,
  2601 			flags,
  2701 			v->index,
  2602 			v->index,
  2702 			0
  2603 			0
  2728 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2629 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2729 }
  2630 }
  2730 
  2631 
  2731 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2632 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2732 {
  2633 {
  2733 	byte new_z, old_z;
       
  2734 
       
  2735 	// need this hint so it returns the right z coordinate on bridges.
  2634 	// need this hint so it returns the right z coordinate on bridges.
  2736 	new_z = GetSlopeZ(v->x_pos, v->y_pos);
  2635 	byte new_z = GetSlopeZ(v->x_pos, v->y_pos);
  2737 
  2636 
  2738 	old_z = v->z_pos;
  2637 	byte old_z = v->z_pos;
  2739 	v->z_pos = new_z;
  2638 	v->z_pos = new_z;
  2740 
  2639 
  2741 	if (new_tile) {
  2640 	if (new_tile) {
  2742 		CLRBIT(v->u.rail.flags, VRF_GOINGUP);
  2641 		CLRBIT(v->u.rail.flags, VRF_GOINGUP);
  2743 		CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
  2642 		CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
  2828 };
  2727 };
  2829 
  2728 
  2830 /* Modify the speed of the vehicle due to a turn */
  2729 /* Modify the speed of the vehicle due to a turn */
  2831 static void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
  2730 static void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
  2832 {
  2731 {
  2833 	DirDiff diff;
       
  2834 	const RailtypeSlowdownParams *rsp;
       
  2835 
       
  2836 	if (_patches.realistic_acceleration) return;
  2732 	if (_patches.realistic_acceleration) return;
  2837 
  2733 
  2838 	diff = DirDifference(v->direction, new_dir);
  2734 	DirDiff diff = DirDifference(v->direction, new_dir);
  2839 	if (diff == DIRDIFF_SAME) return;
  2735 	if (diff == DIRDIFF_SAME) return;
  2840 
  2736 
  2841 	rsp = &_railtype_slowdown[v->u.rail.railtype];
  2737 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2842 	v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
  2738 	v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
  2843 }
  2739 }
  2844 
  2740 
  2845 /* Modify the speed of the vehicle due to a change in altitude */
  2741 /* Modify the speed of the vehicle due to a change in altitude */
  2846 static void AffectSpeedByZChange(Vehicle *v, byte old_z)
  2742 static void AffectSpeedByZChange(Vehicle *v, byte old_z)
  2847 {
  2743 {
  2848 	const RailtypeSlowdownParams *rsp;
       
  2849 	if (old_z == v->z_pos || _patches.realistic_acceleration) return;
  2744 	if (old_z == v->z_pos || _patches.realistic_acceleration) return;
  2850 
  2745 
  2851 	rsp = &_railtype_slowdown[v->u.rail.railtype];
  2746 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2852 
  2747 
  2853 	if (old_z < v->z_pos) {
  2748 	if (old_z < v->z_pos) {
  2854 		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
  2749 		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
  2855 	} else {
  2750 	} else {
  2856 		uint16 spd = v->cur_speed + rsp->z_down;
  2751 		uint16 spd = v->cur_speed + rsp->z_down;
  2895 	}
  2790 	}
  2896 }
  2791 }
  2897 
  2792 
  2898 static void SetVehicleCrashed(Vehicle *v)
  2793 static void SetVehicleCrashed(Vehicle *v)
  2899 {
  2794 {
  2900 	Vehicle *u;
       
  2901 
       
  2902 	if (v->u.rail.crash_anim_pos != 0) return;
  2795 	if (v->u.rail.crash_anim_pos != 0) return;
  2903 
  2796 
  2904 	v->u.rail.crash_anim_pos++;
  2797 	v->u.rail.crash_anim_pos++;
  2905 
  2798 
  2906 	u = v;
  2799 	Vehicle *u = v;
  2907 	BEGIN_ENUM_WAGONS(v)
  2800 	BEGIN_ENUM_WAGONS(v)
  2908 		v->vehstatus |= VS_CRASHED;
  2801 		v->vehstatus |= VS_CRASHED;
  2909 	END_ENUM_WAGONS(v)
  2802 	END_ENUM_WAGONS(v)
  2910 
  2803 
  2911 	InvalidateWindowWidget(WC_VEHICLE_VIEW, u->index, STATUS_BAR);
  2804 	InvalidateWindowWidget(WC_VEHICLE_VIEW, u->index, STATUS_BAR);
  2926  * Reports the incident in a flashy news item, modifies station ratings and
  2819  * Reports the incident in a flashy news item, modifies station ratings and
  2927  * plays a sound.
  2820  * plays a sound.
  2928  */
  2821  */
  2929 static void CheckTrainCollision(Vehicle *v)
  2822 static void CheckTrainCollision(Vehicle *v)
  2930 {
  2823 {
  2931 	TrainCollideChecker tcc;
       
  2932 	Vehicle *coll;
       
  2933 	Vehicle *realcoll;
       
  2934 	uint num;
       
  2935 
       
  2936 	/* can't collide in depot */
  2824 	/* can't collide in depot */
  2937 	if (v->u.rail.track == TRACK_BIT_DEPOT) return;
  2825 	if (v->u.rail.track == TRACK_BIT_DEPOT) return;
  2938 
  2826 
  2939 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2827 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2940 
  2828 
       
  2829 	TrainCollideChecker tcc;
  2941 	tcc.v = v;
  2830 	tcc.v = v;
  2942 	tcc.v_skip = v->next;
  2831 	tcc.v_skip = v->next;
  2943 
  2832 
  2944 	/* find colliding vehicle */
  2833 	/* find colliding vehicle */
  2945 	realcoll = (Vehicle*)VehicleFromPos(TileVirtXY(v->x_pos, v->y_pos), &tcc, FindTrainCollideEnum);
  2834 	Vehicle *realcoll = (Vehicle*)VehicleFromPos(TileVirtXY(v->x_pos, v->y_pos), &tcc, FindTrainCollideEnum);
  2946 	if (realcoll == NULL) return;
  2835 	if (realcoll == NULL) return;
  2947 
  2836 
  2948 	coll = GetFirstVehicleInChain(realcoll);
  2837 	Vehicle *coll = GetFirstVehicleInChain(realcoll);
  2949 
  2838 
  2950 	/* it can't collide with its own wagons */
  2839 	/* it can't collide with its own wagons */
  2951 	if (v == coll ||
  2840 	if (v == coll ||
  2952 			(v->u.rail.track == TRACK_BIT_WORMHOLE && (v->direction & 2) != (realcoll->direction & 2)))
  2841 			(v->u.rail.track == TRACK_BIT_WORMHOLE && (v->direction & 2) != (realcoll->direction & 2)))
  2953 		return;
  2842 		return;
  2954 
  2843 
  2955 	//two drivers + passangers killed in train v
  2844 	//two drivers + passangers killed in train v
  2956 	num = 2 + CountPassengersInTrain(v);
  2845 	uint num = 2 + CountPassengersInTrain(v);
  2957 	if (!(coll->vehstatus & VS_CRASHED))
  2846 	if (!(coll->vehstatus & VS_CRASHED))
  2958 		//two drivers + passangers killed in train coll (if it was not crashed already)
  2847 		//two drivers + passangers killed in train coll (if it was not crashed already)
  2959 		num += 2 + CountPassengersInTrain(coll);
  2848 		num += 2 + CountPassengersInTrain(coll);
  2960 
  2849 
  2961 	SetVehicleCrashed(v);
  2850 	SetVehicleCrashed(v);
  2991 
  2880 
  2992 static void TrainController(Vehicle *v, bool update_image)
  2881 static void TrainController(Vehicle *v, bool update_image)
  2993 {
  2882 {
  2994 	Vehicle *prev;
  2883 	Vehicle *prev;
  2995 	GetNewVehiclePosResult gp;
  2884 	GetNewVehiclePosResult gp;
  2996 	uint32 r, tracks, ts;
  2885 	uint32 ts;
  2997 	Trackdir i;
       
  2998 	DiagDirection enterdir;
  2886 	DiagDirection enterdir;
  2999 	Direction dir;
  2887 	Direction dir;
  3000 	Direction newdir;
       
  3001 	Direction chosen_dir;
       
  3002 	TrackBits chosen_track;
       
  3003 	byte old_z;
       
  3004 
  2888 
  3005 	/* For every vehicle after and including the given vehicle */
  2889 	/* For every vehicle after and including the given vehicle */
  3006 	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
  2890 	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
  3007 		BeginVehicleMove(v);
  2891 		BeginVehicleMove(v);
  3008 
  2892 
  3017 				} else {
  2901 				} else {
  3018 					/* Not inside depot */
  2902 					/* Not inside depot */
  3019 
  2903 
  3020 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  2904 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  3021 
  2905 
  3022 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2906 					uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  3023 					if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2907 					if (HASBIT(r, VETS_CANNOT_ENTER)) {
  3024 						goto invalid_rail;
  2908 						goto invalid_rail;
  3025 					}
  2909 					}
  3026 					if (HASBIT(r, VETS_ENTERED_STATION)) {
  2910 					if (HASBIT(r, VETS_ENTERED_STATION)) {
  3027 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  2911 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  3048 				ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
  2932 				ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
  3049 
  2933 
  3050 				/* Combine the from & to directions.
  2934 				/* Combine the from & to directions.
  3051 				 * Now, the lower byte contains the track status, and the byte at bit 16 contains
  2935 				 * Now, the lower byte contains the track status, and the byte at bit 16 contains
  3052 				 * the signal status. */
  2936 				 * the signal status. */
  3053 				tracks = ts | (ts >> 8);
  2937 				uint32 tracks = ts | (ts >> 8);
  3054 				bits = (TrackBits)(tracks & TRACK_BIT_MASK);
  2938 				bits = (TrackBits)(tracks & TRACK_BIT_MASK);
  3055 				if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
  2939 				if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
  3056 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  2940 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  3057 					 * can be switched on halfway a turn */
  2941 					 * can be switched on halfway a turn */
  3058 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  2942 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  3062 
  2946 
  3063 				/* Check if the new tile contrains tracks that are compatible
  2947 				/* Check if the new tile contrains tracks that are compatible
  3064 				 * with the current train, if not, bail out. */
  2948 				 * with the current train, if not, bail out. */
  3065 				if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail;
  2949 				if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail;
  3066 
  2950 
       
  2951 				TrackBits chosen_track;
  3067 				if (prev == NULL) {
  2952 				if (prev == NULL) {
  3068 					/* Currently the locomotive is active. Determine which one of the
  2953 					/* Currently the locomotive is active. Determine which one of the
  3069 					 * available tracks to choose */
  2954 					 * available tracks to choose */
  3070 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  2955 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  3071 					assert(chosen_track & tracks);
  2956 					assert(chosen_track & tracks);
  3089 						chosen_track == TRACK_BIT_X     || chosen_track == TRACK_BIT_Y ||
  2974 						chosen_track == TRACK_BIT_X     || chosen_track == TRACK_BIT_Y ||
  3090 						chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER ||
  2975 						chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER ||
  3091 						chosen_track == TRACK_BIT_LEFT  || chosen_track == TRACK_BIT_RIGHT);
  2976 						chosen_track == TRACK_BIT_LEFT  || chosen_track == TRACK_BIT_RIGHT);
  3092 
  2977 
  3093 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  2978 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  3094 				{
  2979 				const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
  3095 					const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
  2980 				gp.x = (gp.x & ~0xF) | b[0];
  3096 					gp.x = (gp.x & ~0xF) | b[0];
  2981 				gp.y = (gp.y & ~0xF) | b[1];
  3097 					gp.y = (gp.y & ~0xF) | b[1];
  2982 				Direction chosen_dir = (Direction)b[2];
  3098 					chosen_dir = (Direction)b[2];
       
  3099 				}
       
  3100 
  2983 
  3101 				/* Call the landscape function and tell it that the vehicle entered the tile */
  2984 				/* Call the landscape function and tell it that the vehicle entered the tile */
  3102 				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2985 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  3103 				if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2986 				if (HASBIT(r, VETS_CANNOT_ENTER)) {
  3104 					goto invalid_rail;
  2987 					goto invalid_rail;
  3105 				}
  2988 				}
  3106 
  2989 
  3107 				if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
  2990 				if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
  3149 				continue;
  3032 				continue;
  3150 			}
  3033 			}
  3151 		}
  3034 		}
  3152 
  3035 
  3153 		/* update image of train, as well as delta XY */
  3036 		/* update image of train, as well as delta XY */
  3154 		newdir = GetNewVehicleDirection(v, gp.x, gp.y);
  3037 		Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y);
  3155 		UpdateTrainDeltaXY(v, newdir);
  3038 		UpdateTrainDeltaXY(v, newdir);
  3156 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
  3039 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
  3157 
  3040 
  3158 		v->x_pos = gp.x;
  3041 		v->x_pos = gp.x;
  3159 		v->y_pos = gp.y;
  3042 		v->y_pos = gp.y;
  3160 
  3043 
  3161 		/* update the Z position of the vehicle */
  3044 		/* update the Z position of the vehicle */
  3162 		old_z = AfterSetTrainPos(v, (gp.new_tile != gp.old_tile));
  3045 		byte old_z = AfterSetTrainPos(v, (gp.new_tile != gp.old_tile));
  3163 
  3046 
  3164 		if (prev == NULL) {
  3047 		if (prev == NULL) {
  3165 			/* This is the first vehicle in the train */
  3048 			/* This is the first vehicle in the train */
  3166 			AffectSpeedByZChange(v, old_z);
  3049 			AffectSpeedByZChange(v, old_z);
  3167 		}
  3050 		}
  3175 
  3058 
  3176 red_light: {
  3059 red_light: {
  3177 	/* We're in front of a red signal ?? */
  3060 	/* We're in front of a red signal ?? */
  3178 		/* find the first set bit in ts. need to do it in 2 steps, since
  3061 		/* find the first set bit in ts. need to do it in 2 steps, since
  3179 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
  3062 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
  3180 		i = FindFirstTrackdir((TrackdirBits)(uint16)ts);
  3063 		Trackdir i = FindFirstTrackdir((TrackdirBits)(uint16)ts);
  3181 
  3064 
  3182 		if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
  3065 		if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
  3183 			v->cur_speed = 0;
  3066 			v->cur_speed = 0;
  3184 			v->subspeed = 0;
  3067 			v->subspeed = 0;
  3185 			v->progress = 255 - 100;
  3068 			v->progress = 255 - 100;
  3216  * or inside a tunnel, recalculate the signals as they might need updating
  3099  * or inside a tunnel, recalculate the signals as they might need updating
  3217  * @param v the @Vehicle of which last wagon is to be removed
  3100  * @param v the @Vehicle of which last wagon is to be removed
  3218  */
  3101  */
  3219 static void DeleteLastWagon(Vehicle *v)
  3102 static void DeleteLastWagon(Vehicle *v)
  3220 {
  3103 {
  3221 	Vehicle *u = v;
       
  3222 
       
  3223 	/* Go to the last wagon and delete the link pointing there
  3104 	/* Go to the last wagon and delete the link pointing there
  3224 	 * *u is then the one-before-last wagon, and *v the last
  3105 	 * *u is then the one-before-last wagon, and *v the last
  3225 	 * one which will physicially be removed */
  3106 	 * one which will physicially be removed */
       
  3107 	Vehicle *u = v;
  3226 	for (; v->next != NULL; v = v->next) u = v;
  3108 	for (; v->next != NULL; v = v->next) u = v;
  3227 	u->next = NULL;
  3109 	u->next = NULL;
  3228 
  3110 
  3229 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3111 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3230 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3112 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3288 }
  3170 }
  3289 
  3171 
  3290 static void HandleCrashedTrain(Vehicle *v)
  3172 static void HandleCrashedTrain(Vehicle *v)
  3291 {
  3173 {
  3292 	int state = ++v->u.rail.crash_anim_pos;
  3174 	int state = ++v->u.rail.crash_anim_pos;
  3293 	uint32 r;
       
  3294 	Vehicle *u;
       
  3295 
  3175 
  3296 	if (state == 4 && !(v->vehstatus & VS_HIDDEN)) {
  3176 	if (state == 4 && !(v->vehstatus & VS_HIDDEN)) {
  3297 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
  3177 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
  3298 	}
  3178 	}
  3299 
  3179 
       
  3180 	uint32 r;
  3300 	if (state <= 200 && CHANCE16R(1, 7, r)) {
  3181 	if (state <= 200 && CHANCE16R(1, 7, r)) {
  3301 		int index = (r * 10 >> 16);
  3182 		int index = (r * 10 >> 16);
  3302 
  3183 
  3303 		u = v;
  3184 		Vehicle *u = v;
  3304 		do {
  3185 		do {
  3305 			if (--index < 0) {
  3186 			if (--index < 0) {
  3306 				r = Random();
  3187 				r = Random();
  3307 
  3188 
  3308 				CreateEffectVehicleRel(u,
  3189 				CreateEffectVehicleRel(u,
  3357 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  3238 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  3358 };
  3239 };
  3359 
  3240 
  3360 static bool TrainCheckIfLineEnds(Vehicle *v)
  3241 static bool TrainCheckIfLineEnds(Vehicle *v)
  3361 {
  3242 {
  3362 	TileIndex tile;
  3243 	int t = v->breakdown_ctr;
  3363 	uint x,y;
       
  3364 	uint16 break_speed;
       
  3365 	DiagDirection dir;
       
  3366 	int t;
       
  3367 	uint32 ts;
       
  3368 
       
  3369 	t = v->breakdown_ctr;
       
  3370 	if (t > 1) {
  3244 	if (t > 1) {
  3371 		v->vehstatus |= VS_TRAIN_SLOWING;
  3245 		v->vehstatus |= VS_TRAIN_SLOWING;
  3372 
  3246 
  3373 		break_speed = _breakdown_speeds[GB(~t, 4, 4)];
  3247 		uint16 break_speed = _breakdown_speeds[GB(~t, 4, 4)];
  3374 		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3248 		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3375 	} else {
  3249 	} else {
  3376 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  3250 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  3377 	}
  3251 	}
  3378 
  3252 
  3379 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) return true; // exit if inside a tunnel
  3253 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) return true; // exit if inside a tunnel
  3380 	if (v->u.rail.track == TRACK_BIT_DEPOT) return true; // exit if inside a depot
  3254 	if (v->u.rail.track == TRACK_BIT_DEPOT) return true; // exit if inside a depot
  3381 
  3255 
  3382 	tile = v->tile;
  3256 	TileIndex tile = v->tile;
  3383 
  3257 
  3384 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
  3258 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
  3385 		DiagDirection dir;
  3259 		DiagDirection dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
  3386 
       
  3387 		dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
       
  3388 		if (DiagDirToDir(dir) == v->direction) return true;
  3260 		if (DiagDirToDir(dir) == v->direction) return true;
  3389 	}
  3261 	}
  3390 
  3262 
  3391 	// depot?
  3263 	// depot?
  3392 	/* XXX -- When enabled, this makes it possible to crash trains of others
  3264 	/* XXX -- When enabled, this makes it possible to crash trains of others
  3393 	     (by building a depot right against a station) */
  3265 	     (by building a depot right against a station) */
  3394 /*	if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
  3266 /*	if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
  3395 		return true;*/
  3267 		return true;*/
  3396 
  3268 
  3397 	/* Determine the non-diagonal direction in which we will exit this tile */
  3269 	/* Determine the non-diagonal direction in which we will exit this tile */
  3398 	dir = DirToDiagDir(v->direction);
  3270 	DiagDirection dir = DirToDiagDir(v->direction);
  3399 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
  3271 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
  3400 		dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
  3272 		dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
  3401 	}
  3273 	}
  3402 	/* Calculate next tile */
  3274 	/* Calculate next tile */
  3403 	tile += TileOffsByDiagDir(dir);
  3275 	tile += TileOffsByDiagDir(dir);
  3404 	// determine the track status on the next tile.
  3276 	// determine the track status on the next tile.
  3405 	ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[dir];
  3277 	uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[dir];
  3406 
  3278 
  3407 	/* Calc position within the current tile ?? */
  3279 	/* Calc position within the current tile ?? */
  3408 	x = v->x_pos & 0xF;
  3280 	uint x = v->x_pos & 0xF;
  3409 	y = v->y_pos & 0xF;
  3281 	uint y = v->y_pos & 0xF;
  3410 
  3282 
  3411 	switch (v->direction) {
  3283 	switch (v->direction) {
  3412 		case DIR_N : x = ~x + ~y + 24; break;
  3284 		case DIR_N : x = ~x + ~y + 24; break;
  3413 		case DIR_NW: x = y;            /* FALLTHROUGH */
  3285 		case DIR_NW: x = y;            /* FALLTHROUGH */
  3414 		case DIR_NE: x = ~x + 16;      break;
  3286 		case DIR_NE: x = ~x + 16;      break;
  3446 		return false;
  3318 		return false;
  3447 	}
  3319 	}
  3448 
  3320 
  3449 	// slow down
  3321 	// slow down
  3450 	v->vehstatus |= VS_TRAIN_SLOWING;
  3322 	v->vehstatus |= VS_TRAIN_SLOWING;
  3451 	break_speed = _breakdown_speeds[x & 0xF];
  3323 	uint16 break_speed = _breakdown_speeds[x & 0xF];
  3452 	if (!(v->direction & 1)) break_speed >>= 1;
  3324 	if (!(v->direction & 1)) break_speed >>= 1;
  3453 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3325 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3454 
  3326 
  3455 	return true;
  3327 	return true;
  3456 }
  3328 }
  3457 
  3329 
  3458 static void TrainLocoHandler(Vehicle *v, bool mode)
  3330 static void TrainLocoHandler(Vehicle *v, bool mode)
  3459 {
  3331 {
  3460 	int j;
       
  3461 
       
  3462 	/* train has crashed? */
  3332 	/* train has crashed? */
  3463 	if (v->u.rail.crash_anim_pos != 0) {
  3333 	if (v->u.rail.crash_anim_pos != 0) {
  3464 		if (!mode) HandleCrashedTrain(v);
  3334 		if (!mode) HandleCrashedTrain(v);
  3465 		return;
  3335 		return;
  3466 	}
  3336 	}
  3497 
  3367 
  3498 	if (CheckTrainStayInDepot(v)) return;
  3368 	if (CheckTrainStayInDepot(v)) return;
  3499 
  3369 
  3500 	if (!mode) HandleLocomotiveSmokeCloud(v);
  3370 	if (!mode) HandleLocomotiveSmokeCloud(v);
  3501 
  3371 
  3502 	j = UpdateTrainSpeed(v);
  3372 	int j = UpdateTrainSpeed(v);
  3503 	if (j == 0) {
  3373 	if (j == 0) {
  3504 		// if the vehicle has speed 0, update the last_speed field.
  3374 		// if the vehicle has speed 0, update the last_speed field.
  3505 		if (v->cur_speed != 0) return;
  3375 		if (v->cur_speed != 0) return;
  3506 	} else {
  3376 	} else {
  3507 		TrainCheckIfLineEnds(v);
  3377 		TrainCheckIfLineEnds(v);
  3540 
  3410 
  3541 #define MAX_ACCEPTABLE_DEPOT_DIST 16
  3411 #define MAX_ACCEPTABLE_DEPOT_DIST 16
  3542 
  3412 
  3543 static void CheckIfTrainNeedsService(Vehicle *v)
  3413 static void CheckIfTrainNeedsService(Vehicle *v)
  3544 {
  3414 {
  3545 	const Depot* depot;
       
  3546 	TrainFindDepotData tfdd;
       
  3547 
       
  3548 	if (_patches.servint_trains == 0)                   return;
  3415 	if (_patches.servint_trains == 0)                   return;
  3549 	if (!VehicleNeedsService(v))                        return;
  3416 	if (!VehicleNeedsService(v))                        return;
  3550 	if (v->vehstatus & VS_STOPPED)                      return;
  3417 	if (v->vehstatus & VS_STOPPED)                      return;
  3551 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
  3418 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
  3552 
  3419 
  3559 	if (CheckTrainIsInsideDepot(v)) {
  3426 	if (CheckTrainIsInsideDepot(v)) {
  3560 		VehicleServiceInDepot(v);
  3427 		VehicleServiceInDepot(v);
  3561 		return;
  3428 		return;
  3562 	}
  3429 	}
  3563 
  3430 
  3564 	tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3431 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3565 	/* Only go to the depot if it is not too far out of our way. */
  3432 	/* Only go to the depot if it is not too far out of our way. */
  3566 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
  3433 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
  3567 		if (v->current_order.type == OT_GOTO_DEPOT) {
  3434 		if (v->current_order.type == OT_GOTO_DEPOT) {
  3568 			/* If we were already heading for a depot but it has
  3435 			/* If we were already heading for a depot but it has
  3569 			 * suddenly moved farther away, we continue our normal
  3436 			 * suddenly moved farther away, we continue our normal
  3573 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3440 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3574 		}
  3441 		}
  3575 		return;
  3442 		return;
  3576 	}
  3443 	}
  3577 
  3444 
  3578 	depot = GetDepotByTile(tfdd.tile);
  3445 	const Depot* depot = GetDepotByTile(tfdd.tile);
  3579 
  3446 
  3580 	if (v->current_order.type == OT_GOTO_DEPOT &&
  3447 	if (v->current_order.type == OT_GOTO_DEPOT &&
  3581 			v->current_order.dest != depot->index &&
  3448 			v->current_order.dest != depot->index &&
  3582 			!CHANCE16(3, 16)) {
  3449 			!CHANCE16(3, 16)) {
  3583 		return;
  3450 		return;
  3603 	return cost;
  3470 	return cost;
  3604 }
  3471 }
  3605 
  3472 
  3606 void OnNewDay_Train(Vehicle *v)
  3473 void OnNewDay_Train(Vehicle *v)
  3607 {
  3474 {
  3608 	TileIndex tile;
       
  3609 
       
  3610 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3475 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3611 
  3476 
  3612 	if (IsFrontEngine(v)) {
  3477 	if (IsFrontEngine(v)) {
  3613 		CheckVehicleBreakdown(v);
  3478 		CheckVehicleBreakdown(v);
  3614 		AgeVehicle(v);
  3479 		AgeVehicle(v);
  3616 		CheckIfTrainNeedsService(v);
  3481 		CheckIfTrainNeedsService(v);
  3617 
  3482 
  3618 		CheckOrders(v);
  3483 		CheckOrders(v);
  3619 
  3484 
  3620 		/* update destination */
  3485 		/* update destination */
  3621 		if (v->current_order.type == OT_GOTO_STATION &&
  3486 		if (v->current_order.type == OT_GOTO_STATION) {
  3622 				(tile = GetStation(v->current_order.dest)->train_tile) != 0) {
  3487 			TileIndex tile = GetStation(v->current_order.dest)->train_tile;
  3623 			v->dest_tile = tile;
  3488 			if (tile != 0) v->dest_tile = tile;
  3624 		}
  3489 		}
  3625 
  3490 
  3626 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3491 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3627 			/* running costs */
  3492 			/* running costs */
  3628 			int32 cost = GetTrainRunningCost(v) / 364;
  3493 			int32 cost = GetTrainRunningCost(v) / 364;
  3642 {
  3507 {
  3643 	Vehicle *v;
  3508 	Vehicle *v;
  3644 
  3509 
  3645 	FOR_ALL_VEHICLES(v) {
  3510 	FOR_ALL_VEHICLES(v) {
  3646 		if (v->type == VEH_Train && IsFrontEngine(v)) {
  3511 		if (v->type == VEH_Train && IsFrontEngine(v)) {
  3647 
       
  3648 			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
  3512 			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
  3649 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
  3513 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
  3650 				SetDParam(1, v->profit_this_year);
  3514 				SetDParam(1, v->profit_this_year);
  3651 				SetDParam(0, v->unitnumber);
  3515 				SetDParam(0, v->unitnumber);
  3652 				AddNewsItem(
  3516 				AddNewsItem(
  3695 						/* we got a rear car without a front car. We will convert it to a front one */
  3559 						/* we got a rear car without a front car. We will convert it to a front one */
  3696 						SetTrainEngine(u);
  3560 						SetTrainEngine(u);
  3697 						u->spritenum--;
  3561 						u->spritenum--;
  3698 					}
  3562 					}
  3699 
  3563 
  3700 					{
  3564 					Vehicle *w;
  3701 						Vehicle *w;
  3565 					for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
  3702 
  3566 					if (w != NULL) {
  3703 						for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
  3567 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3704 						if (w != NULL) {
  3568 						if (IsTrainEngine(w)) {
  3705 							/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3569 							ClearTrainEngine(w);
  3706 							if (IsTrainEngine(w)) {
  3570 							w->spritenum++;
  3707 								ClearTrainEngine(w);
       
  3708 								w->spritenum++;
       
  3709 							}
       
  3710 						}
  3571 						}
  3711 
  3572 						w->u.rail.other_multiheaded_part = u;
  3712 						if (w != NULL) {
  3573 						u->u.rail.other_multiheaded_part = w;
  3713 							w->u.rail.other_multiheaded_part = u;
  3574 					} else {
  3714 							u->u.rail.other_multiheaded_part = w;
  3575 						/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
  3715 						} else {
  3576 						ClearMultiheaded(u);
  3716 							/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
       
  3717 							ClearMultiheaded(u);
       
  3718 						}
       
  3719 					}
  3577 					}
  3720 				}
  3578 				}
  3721 			} END_ENUM_WAGONS(u)
  3579 			} END_ENUM_WAGONS(u)
  3722 		}
  3580 		}
  3723 	}
  3581 	}