train_cmd.c
changeset 742 c71e6120b789
parent 737 05082439a150
child 743 da4d304b52d2
equal deleted inserted replaced
741:422ce499322b 742:c71e6120b789
    16 #define is_firsthead_sprite(spritenum) \
    16 #define is_firsthead_sprite(spritenum) \
    17 	(is_custom_sprite(spritenum) \
    17 	(is_custom_sprite(spritenum) \
    18 		? is_custom_firsthead_sprite(spritenum) \
    18 		? is_custom_firsthead_sprite(spritenum) \
    19 		: _engine_sprite_add[spritenum] == 0)
    19 		: _engine_sprite_add[spritenum] == 0)
    20 
    20 
       
    21 static bool TrainCheckIfLineEnds(Vehicle *v);
    21 
    22 
    22 static const byte _vehicle_initial_x_fract[4] = {10,8,4,8};
    23 static const byte _vehicle_initial_x_fract[4] = {10,8,4,8};
    23 static const byte _vehicle_initial_y_fract[4] = {8,4,8,10};
    24 static const byte _vehicle_initial_y_fract[4] = {8,4,8,10};
    24 static const byte _state_dir_table[4] = { 0x20, 8, 0x10, 4 };
    25 static const byte _state_dir_table[4] = { 0x20, 8, 0x10, 4 };
    25 
    26 
  1272 static bool CheckTrainStayInDepot(Vehicle *v)
  1273 static bool CheckTrainStayInDepot(Vehicle *v)
  1273 {
  1274 {
  1274 	Vehicle *u;
  1275 	Vehicle *u;
  1275 
  1276 
  1276 	// bail out if not all wagons are in the same depot or not in a depot at all
  1277 	// bail out if not all wagons are in the same depot or not in a depot at all
  1277 	for (u = v; u != NULL; u = u->next) 
  1278 	for (u = v; u != NULL; u = u->next)
  1278 		if (u->u.rail.track != 0x80 || u->tile != v->tile)
  1279 		if (u->u.rail.track != 0x80 || u->tile != v->tile)
  1279 			return false;
  1280 			return false;
  1280 
  1281 
  1281 	if (v->u.rail.force_proceed == 0) {
  1282 	if (v->u.rail.force_proceed == 0) {
  1282 		if (++v->load_unload_time_rem < 37)
  1283 		if (++v->load_unload_time_rem < 37)
  2065 					/* inside depot */
  2066 					/* inside depot */
  2066 					gp.x = v->x_pos;
  2067 					gp.x = v->x_pos;
  2067 					gp.y = v->y_pos;
  2068 					gp.y = v->y_pos;
  2068 				} else {
  2069 				} else {
  2069 					/* is not inside depot */
  2070 					/* is not inside depot */
       
  2071 
       
  2072 					if (!TrainCheckIfLineEnds(v))
       
  2073 						return;
       
  2074 
  2070 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2075 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2071 					if (r & 0x8)
  2076 					if (r & 0x8)
  2072 						goto invalid_rail;
  2077 						goto invalid_rail;
  2073 					if (r & 0x2) {
  2078 					if (r & 0x2) {
  2074 						TrainEnterStation(v, r >> 8);
  2079 						TrainEnterStation(v, r >> 8);
  2361 
  2366 
  2362 static const byte _breakdown_speeds[16] = {
  2367 static const byte _breakdown_speeds[16] = {
  2363 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  2368 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  2364 };
  2369 };
  2365 
  2370 
  2366 static void TrainCheckIfLineEnds(Vehicle *v)
  2371 static bool TrainCheckIfLineEnds(Vehicle *v)
  2367 {
  2372 {
  2368 	uint tile;
  2373 	uint tile;
  2369 	uint x,y;
  2374 	uint x,y;
  2370 	int t;
  2375 	int t;
  2371 	uint32 ts;
  2376 	uint32 ts;
  2380 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  2385 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  2381 	}
  2386 	}
  2382 
  2387 
  2383 	// exit if inside a tunnel
  2388 	// exit if inside a tunnel
  2384 	if (v->u.rail.track & 0x40)
  2389 	if (v->u.rail.track & 0x40)
  2385 		return;
  2390 		return true;
  2386 
  2391 
  2387 	tile = v->tile;
  2392 	tile = v->tile;
  2388 
  2393 
  2389 	// tunnel entrance?
  2394 	// tunnel entrance?
  2390 	if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) &&
  2395 	if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) &&
  2391 			(_map5[tile] & 0xF0) == 0 && (byte)((_map5[tile] & 3)*2+1) == v->direction)
  2396 			(_map5[tile] & 0xF0) == 0 && (byte)((_map5[tile] & 3)*2+1) == v->direction)
  2392 				return;
  2397 				return true;
  2393 
  2398 
  2394 	// depot?
  2399 	// depot?
  2395 	if (IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile] & 0xFC) == 0xC0)
  2400 	/* XXX -- When enabled, this makes it possible to crash trains of others
  2396 		return;
  2401 	     (by building a depot right against a station) */
       
  2402 /*	if (IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile] & 0xFC) == 0xC0)
       
  2403 		return true;*/
  2397 
  2404 
  2398 	/* Determine the non-diagonal direction in which we will exit this tile */
  2405 	/* Determine the non-diagonal direction in which we will exit this tile */
  2399 	t = v->direction >> 1;
  2406 	t = v->direction >> 1;
  2400 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[t]) {
  2407 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[t]) {
  2401 		t = (t - 1) & 3;
  2408 		t = (t - 1) & 3;
  2432 		x = (~y) + x + 8;
  2439 		x = (~y) + x + 8;
  2433 		break;
  2440 		break;
  2434 	}
  2441 	}
  2435 
  2442 
  2436 	if ( (uint16)ts != 0) {
  2443 	if ( (uint16)ts != 0) {
       
  2444 		/* If we approach a rail-piece which we can't enter, don't enter it! */
       
  2445 		if (x + 4 > 15 && !CheckCompatibleRail(v, tile)) {
       
  2446 			v->cur_speed = 0;
       
  2447 			ReverseTrainDirection(v);
       
  2448 			return false;
       
  2449 		}
  2437 		if ((ts &= (ts >> 16)) == 0) {
  2450 		if ((ts &= (ts >> 16)) == 0) {
  2438 			// make a rail/road crossing red
  2451 			// make a rail/road crossing red
  2439 			if (IS_TILETYPE(tile, MP_STREET) && (_map5[tile] & 0xF0)==0x10) {
  2452 			if (IS_TILETYPE(tile, MP_STREET) && (_map5[tile] & 0xF0)==0x10) {
  2440 				if (!(_map5[tile] & 4)) {
  2453 				if (!(_map5[tile] & 4)) {
  2441 					_map5[tile] |= 4;
  2454 					_map5[tile] |= 4;
  2442 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
  2455 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
  2443 					MarkTileDirtyByTile(tile);
  2456 					MarkTileDirtyByTile(tile);
  2444 				}
  2457 				}
  2445 			}
  2458 			}
  2446 			return;
  2459 			return true;
  2447 		}
  2460 		}
  2448 	} else if (x + 4 > 15) {
  2461 	} else if (x + 4 > 15) {
  2449 		v->cur_speed = 0;
  2462 		v->cur_speed = 0;
  2450 		ReverseTrainDirection(v);
  2463 		ReverseTrainDirection(v);
  2451 		return;
  2464 		return false;
  2452 	}
  2465 	}
  2453 
  2466 
  2454 	// slow down
  2467 	// slow down
  2455 	v->vehstatus |= VS_TRAIN_SLOWING;
  2468 	v->vehstatus |= VS_TRAIN_SLOWING;
  2456 	t = _breakdown_speeds[x & 0xF];
  2469 	t = _breakdown_speeds[x & 0xF];
  2457 	if (!(v->direction&1)) t>>=1;
  2470 	if (!(v->direction&1)) t>>=1;
  2458 	if ((uint16)t < v->cur_speed)
  2471 	if ((uint16)t < v->cur_speed)
  2459 		v->cur_speed = t;
  2472 		v->cur_speed = t;
       
  2473 
       
  2474 	return true;
  2460 }
  2475 }
  2461 
  2476 
  2462 static void TrainLocoHandler(Vehicle *v, bool mode)
  2477 static void TrainLocoHandler(Vehicle *v, bool mode)
  2463 {
  2478 {
  2464 	int j;
  2479 	int j;