src/roadveh_cmd.cpp
branchcustombridgeheads
changeset 5650 aefc131bf5ce
parent 5649 55c8267c933f
equal deleted inserted replaced
5649:55c8267c933f 5650:aefc131bf5ce
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #include "stdafx.h"
     3 #include "stdafx.h"
     4 #include <limits.h>
       
     5 #include "openttd.h"
     4 #include "openttd.h"
     6 #include "debug.h"
     5 #include "debug.h"
     7 #include "functions.h"
     6 #include "functions.h"
     8 #include "road_map.h"
     7 #include "road_map.h"
     9 #include "roadveh.h"
     8 #include "roadveh.h"
   142 		int y;
   141 		int y;
   143 
   142 
   144 		const RoadVehicleInfo *rvi = RoadVehInfo(p1);
   143 		const RoadVehicleInfo *rvi = RoadVehInfo(p1);
   145 
   144 
   146 		v->unitnumber = unit_num;
   145 		v->unitnumber = unit_num;
   147 		v->direction = 0;
   146 		v->direction = INVALID_DIR;
   148 		v->owner = _current_player;
   147 		v->owner = _current_player;
   149 
   148 
   150 		v->tile = tile;
   149 		v->tile = tile;
   151 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   150 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   152 		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
   151 		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
   294 }
   293 }
   295 
   294 
   296 typedef struct RoadFindDepotData {
   295 typedef struct RoadFindDepotData {
   297 	uint best_length;
   296 	uint best_length;
   298 	TileIndex tile;
   297 	TileIndex tile;
   299 	byte owner;
   298 	OwnerByte owner;
   300 } RoadFindDepotData;
   299 } RoadFindDepotData;
   301 
   300 
   302 static const DiagDirection _road_pf_directions[] = {
   301 static const DiagDirection _road_pf_directions[] = {
   303 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 255, 255,
   302 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR,
   304 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, 255, 255
   303 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR
   305 };
   304 };
   306 
   305 
   307 static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, int track, uint length, byte* state)
   306 static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
   308 {
   307 {
   309 	RoadFindDepotData* rfdd = data;
   308 	RoadFindDepotData* rfdd = (RoadFindDepotData*)data;
   310 
   309 
   311 	tile += TileOffsByDiagDir(_road_pf_directions[track]);
   310 	tile += TileOffsByDiagDir(_road_pf_directions[trackdir]);
   312 
   311 
   313 	if (IsTileType(tile, MP_STREET) &&
   312 	if (IsTileType(tile, MP_STREET) &&
   314 			GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
   313 			GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
   315 			IsTileOwner(tile, rfdd->owner) &&
   314 			IsTileOwner(tile, rfdd->owner) &&
   316 			length < rfdd->best_length) {
   315 			length < rfdd->best_length) {
   339 			return NULL; /* Target not found */
   338 			return NULL; /* Target not found */
   340 		}
   339 		}
   341 		/* We do not search in two directions here, why should we? We can't reverse right now can we? */
   340 		/* We do not search in two directions here, why should we? We can't reverse right now can we? */
   342 	} else {
   341 	} else {
   343 		RoadFindDepotData rfdd;
   342 		RoadFindDepotData rfdd;
   344 		DiagDirection i;
       
   345 
   343 
   346 		rfdd.owner = v->owner;
   344 		rfdd.owner = v->owner;
   347 		rfdd.best_length = (uint)-1;
   345 		rfdd.best_length = (uint)-1;
   348 
   346 
   349 		/* search in all directions */
   347 		/* search in all directions */
   350 		for (i = 0; i != 4; i++) {
   348 		for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) {
   351 			FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd);
   349 			FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd);
   352 		}
   350 		}
   353 
   351 
   354 		if (rfdd.best_length == (uint)-1) return NULL;
   352 		if (rfdd.best_length == (uint)-1) return NULL;
   355 
   353 
   562 	}
   560 	}
   563 }
   561 }
   564 
   562 
   565 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   563 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   566 {
   564 {
   567 	const Vehicle* u = data;
   565 	const Vehicle* u = (Vehicle*)data;
   568 
   566 
   569 	return
   567 	return
   570 		v->type == VEH_Train &&
   568 		v->type == VEH_Train &&
   571 		myabs(v->z_pos - u->z_pos) <= 6 &&
   569 		myabs(v->z_pos - u->z_pos) <= 6 &&
   572 		myabs(v->x_pos - u->x_pos) <= 4 &&
   570 		myabs(v->x_pos - u->x_pos) <= 4 &&
   787 static void* EnumCheckRoadVehClose(Vehicle *v, void* data)
   785 static void* EnumCheckRoadVehClose(Vehicle *v, void* data)
   788 {
   786 {
   789 	static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
   787 	static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
   790 	static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
   788 	static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
   791 
   789 
   792 	const RoadVehFindData* rvf = data;
   790 	const RoadVehFindData* rvf = (RoadVehFindData*)data;
   793 
   791 
   794 	short x_diff = v->x_pos - rvf->x;
   792 	short x_diff = v->x_pos - rvf->x;
   795 	short y_diff = v->y_pos - rvf->y;
   793 	short y_diff = v->y_pos - rvf->y;
   796 
   794 
   797 	return
   795 	return
   816 
   814 
   817 	rvf.x = x;
   815 	rvf.x = x;
   818 	rvf.y = y;
   816 	rvf.y = y;
   819 	rvf.dir = dir;
   817 	rvf.dir = dir;
   820 	rvf.veh = v;
   818 	rvf.veh = v;
   821 	u = VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose);
   819 	u = (Vehicle*)VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose);
   822 
   820 
   823 	// This code protects a roadvehicle from being blocked for ever
   821 	// This code protects a roadvehicle from being blocked for ever
   824 	//  If more than 1480 / 74 days a road vehicle is blocked, it will
   822 	//  If more than 1480 / 74 days a road vehicle is blocked, it will
   825 	//  drive just through it. The ultimate backup-code of TTD.
   823 	//  drive just through it. The ultimate backup-code of TTD.
   826 	// It can be disabled.
   824 	// It can be disabled.
   898 }
   896 }
   899 
   897 
   900 static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y)
   898 static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y)
   901 {
   899 {
   902 	static const Direction _roadveh_new_dir[] = {
   900 	static const Direction _roadveh_new_dir[] = {
   903 		DIR_N , DIR_NW, DIR_W , 0,
   901 		DIR_N , DIR_NW, DIR_W , INVALID_DIR,
   904 		DIR_NE, DIR_N , DIR_SW, 0,
   902 		DIR_NE, DIR_N , DIR_SW, INVALID_DIR,
   905 		DIR_E , DIR_SE, DIR_S
   903 		DIR_E , DIR_SE, DIR_S
   906 	};
   904 	};
   907 
   905 
   908 	x = x - v->x_pos + 1;
   906 	x = x - v->x_pos + 1;
   909 	y = y - v->y_pos + 1;
   907 	y = y - v->y_pos + 1;
   912 	return _roadveh_new_dir[y * 4 + x];
   910 	return _roadveh_new_dir[y * 4 + x];
   913 }
   911 }
   914 
   912 
   915 static Direction RoadVehGetSlidingDirection(const Vehicle* v, int x, int y)
   913 static Direction RoadVehGetSlidingDirection(const Vehicle* v, int x, int y)
   916 {
   914 {
   917 	Direction new = RoadVehGetNewDirection(v, x, y);
   915 	Direction new_dir = RoadVehGetNewDirection(v, x, y);
   918 	Direction old = v->direction;
   916 	Direction old_dir = v->direction;
   919 	DirDiff delta;
   917 	DirDiff delta;
   920 
   918 
   921 	if (new == old) return old;
   919 	if (new_dir == old_dir) return old_dir;
   922 	delta = (DirDifference(new, old) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
   920 	delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
   923 	return ChangeDir(old, delta);
   921 	return ChangeDir(old_dir, delta);
   924 }
   922 }
   925 
   923 
   926 typedef struct OvertakeData {
   924 typedef struct OvertakeData {
   927 	const Vehicle* u;
   925 	const Vehicle* u;
   928 	const Vehicle* v;
   926 	const Vehicle* v;
   930 	byte tilebits;
   928 	byte tilebits;
   931 } OvertakeData;
   929 } OvertakeData;
   932 
   930 
   933 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
   931 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
   934 {
   932 {
   935 	const OvertakeData* od = data;
   933 	const OvertakeData* od = (OvertakeData*)data;
   936 
   934 
   937 	return
   935 	return
   938 		v->tile == od->tile && v->type == VEH_Road && v != od->u && v != od->v ?
   936 		v->tile == od->tile && v->type == VEH_Road && v != od->u && v != od->v ?
   939 			v : NULL;
   937 			v : NULL;
   940 }
   938 }
  1023 	TileIndex dest;
  1021 	TileIndex dest;
  1024 	uint maxtracklen;
  1022 	uint maxtracklen;
  1025 	uint mindist;
  1023 	uint mindist;
  1026 } FindRoadToChooseData;
  1024 } FindRoadToChooseData;
  1027 
  1025 
  1028 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, int track, uint length, byte* state)
  1026 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1029 {
  1027 {
  1030 	FindRoadToChooseData* frd = data;
  1028 	FindRoadToChooseData* frd = (FindRoadToChooseData*)data;
  1031 	uint dist = DistanceManhattan(tile, frd->dest);
  1029 	uint dist = DistanceManhattan(tile, frd->dest);
  1032 
  1030 
  1033 	if (dist <= frd->mindist) {
  1031 	if (dist <= frd->mindist) {
  1034 		if (dist != frd->mindist || length < frd->maxtracklen) {
  1032 		if (dist != frd->mindist || length < frd->maxtracklen) {
  1035 			frd->maxtracklen = length;
  1033 			frd->maxtracklen = length;
  1131 		if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
  1129 		if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
  1132 		return_track(PickRandomBit(bitmask));
  1130 		return_track(PickRandomBit(bitmask));
  1133 	} else if (_patches.new_pathfinding_all) {
  1131 	} else if (_patches.new_pathfinding_all) {
  1134 		NPFFindStationOrTileData fstd;
  1132 		NPFFindStationOrTileData fstd;
  1135 		NPFFoundTargetData ftd;
  1133 		NPFFoundTargetData ftd;
  1136 		byte trackdir;
  1134 		Trackdir trackdir;
  1137 
  1135 
  1138 		NPFFillWithOrderData(&fstd, v);
  1136 		NPFFillWithOrderData(&fstd, v);
  1139 		trackdir = DiagdirToDiagTrackdir(enterdir);
  1137 		trackdir = DiagdirToDiagTrackdir(enterdir);
  1140 		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
  1138 		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
  1141 
  1139 
  1213 		// use YAPF
  1211 		// use YAPF
  1214 		dist = YapfRoadVehDistanceToTile(v, tile);
  1212 		dist = YapfRoadVehDistanceToTile(v, tile);
  1215 	} else {
  1213 	} else {
  1216 		// use NPF
  1214 		// use NPF
  1217 		NPFFindStationOrTileData fstd;
  1215 		NPFFindStationOrTileData fstd;
  1218 		byte trackdir = GetVehicleTrackdir(v);
  1216 		Trackdir trackdir = GetVehicleTrackdir(v);
  1219 		assert(trackdir != 0xFF);
  1217 		assert(trackdir != 0xFF);
  1220 
  1218 
  1221 		fstd.dest_coords = tile;
  1219 		fstd.dest_coords = tile;
  1222 		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
  1220 		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
  1223 
  1221 
  1361 	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1359 	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1362 
  1360 
  1363 // switch to another tile
  1361 // switch to another tile
  1364 	if (rd.x & 0x80) {
  1362 	if (rd.x & 0x80) {
  1365 		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
  1363 		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
  1366 		int dir = RoadFindPathToDest(v, tile, rd.x & 3);
  1364 		int dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
  1367 		uint32 r;
  1365 		uint32 r;
  1368 		Direction newdir;
  1366 		Direction newdir;
  1369 		const RoadDriveEntry *rdp;
  1367 		const RoadDriveEntry *rdp;
  1370 
  1368 
  1371 		if (dir == -1) {
  1369 		if (dir == -1) {
  1426 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1424 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1427 		return;
  1425 		return;
  1428 	}
  1426 	}
  1429 
  1427 
  1430 	if (rd.x & 0x40) {
  1428 	if (rd.x & 0x40) {
  1431 		int dir = RoadFindPathToDest(v, v->tile, rd.x & 3);
  1429 		int dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
  1432 		uint32 r;
  1430 		uint32 r;
  1433 		int tmp;
  1431 		int tmp;
  1434 		Direction newdir;
  1432 		Direction newdir;
  1435 		const RoadDriveEntry *rdp;
  1433 		const RoadDriveEntry *rdp;
  1436 
  1434