src/pathfind.cpp
changeset 7567 8723fa633d31
parent 7179 3e123c2b7c93
child 7576 38425ad72aaf
equal deleted inserted replaced
7566:435e3c4dbf28 7567:8723fa633d31
   252 32, 40, 40, 42, 40, 44, 44, 46,
   252 32, 40, 40, 42, 40, 44, 44, 46,
   253 32, 48, 48, 50, 48, 52, 52, 54,
   253 32, 48, 48, 50, 48, 52, 52, 54,
   254 48, 56, 56, 58, 56, 60, 60, 62,
   254 48, 56, 56, 58, 56, 60, 60, 62,
   255 };
   255 };
   256 
   256 
       
   257 static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction);
       
   258 
       
   259 /** Most code of the "Normal" case of TPF Mode 1; for signals special tricks
       
   260  * have to be done, but those happen in TPFMode1; this is just to prevent
       
   261  * gotos ;). */
       
   262 static inline void TPFMode1_NormalCase(TrackPathFinder* tpf, TileIndex tile, TileIndex tile_org, DiagDirection direction)
       
   263 {
       
   264 	/* Check in case of rail if the owner is the same */
       
   265 	if (tpf->tracktype == TRANSPORT_RAIL) {
       
   266 		/* don't enter train depot from the back */
       
   267 		if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
       
   268 
       
   269 		if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
       
   270 			if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
       
   271 				if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
       
   272 	}
       
   273 
       
   274 	/* check if the new tile can be entered from that direction */
       
   275 	if (tpf->tracktype == TRANSPORT_ROAD) {
       
   276 		/* road stops and depots now have a track (r4419)
       
   277 		 * don't enter road stop from the back */
       
   278 		if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
       
   279 		/* don't enter road depot from the back */
       
   280 		if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
       
   281 	}
       
   282 
       
   283 	/* Check if the new tile is a tunnel or bridge head and that the direction
       
   284 	 * and transport type match */
       
   285 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
       
   286 		if (IsTunnel(tile)) {
       
   287 			if (GetTunnelDirection(tile) != direction ||
       
   288 					GetTunnelTransportType(tile) != tpf->tracktype) {
       
   289 				return;
       
   290 			}
       
   291 		} else if (IsBridge(tile)) {
       
   292 			if (GetBridgeRampDirection(tile) != direction ||
       
   293 					GetBridgeTransportType(tile) != tpf->tracktype) {
       
   294 				return;
       
   295 			}
       
   296 		}
       
   297 	}
       
   298 
       
   299 	tpf->rd.cur_length++;
       
   300 
       
   301 	uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
       
   302 
       
   303 	if ((byte)bits != tpf->var2) {
       
   304 		bits &= _tpfmode1_and[direction];
       
   305 		bits = bits | (bits >> 8);
       
   306 	}
       
   307 	bits &= 0xBF;
       
   308 
       
   309 	if (bits != 0) {
       
   310 		if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) {
       
   311 			do {
       
   312 				int i = FIND_FIRST_BIT(bits);
       
   313 				bits = KILL_FIRST_BIT(bits);
       
   314 
       
   315 				tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
       
   316 				RememberData rd = tpf->rd;
       
   317 
       
   318 				if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
       
   319 						!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
       
   320 					TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
       
   321 				}
       
   322 				tpf->rd = rd;
       
   323 			} while (bits != 0);
       
   324 		}
       
   325 	}
       
   326 }
       
   327 
   257 static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
   328 static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
   258 {
   329 {
   259 	uint bits;
       
   260 	int i;
       
   261 	RememberData rd;
       
   262 	TileIndex tile_org = tile;
   330 	TileIndex tile_org = tile;
   263 
   331 
   264 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   332 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   265 		if (IsTunnel(tile)) {
   333 		if (IsTunnel(tile)) {
   266 			if (GetTunnelDirection(tile) != direction ||
   334 			if (GetTunnelDirection(tile) != direction ||
   283 			TPFSetTileBit(tpf, tile, 14);
   351 			TPFSetTileBit(tpf, tile, 14);
   284 		}
   352 		}
   285 	}
   353 	}
   286 	tile += TileOffsByDiagDir(direction);
   354 	tile += TileOffsByDiagDir(direction);
   287 
   355 
   288 	/* Check in case of rail if the owner is the same */
   356 	TPFMode1_NormalCase(tpf, tile, tile_org, direction);
   289 	if (tpf->tracktype == TRANSPORT_RAIL) {
       
   290 		/* don't enter train depot from the back */
       
   291 		if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
       
   292 
       
   293 		if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
       
   294 			if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
       
   295 				if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
       
   296 	}
       
   297 
       
   298 	/* check if the new tile can be entered from that direction */
       
   299 	if (tpf->tracktype == TRANSPORT_ROAD) {
       
   300 		/* road stops and depots now have a track (r4419)
       
   301 		 * don't enter road stop from the back */
       
   302 		if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
       
   303 		/* don't enter road depot from the back */
       
   304 		if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
       
   305 	}
       
   306 
       
   307 	/* Check if the new tile is a tunnel or bridge head and that the direction
       
   308 	 * and transport type match */
       
   309 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
       
   310 		if (IsTunnel(tile)) {
       
   311 			if (GetTunnelDirection(tile) != direction ||
       
   312 					GetTunnelTransportType(tile) != tpf->tracktype) {
       
   313 				return;
       
   314 			}
       
   315 		} else if (IsBridge(tile)) {
       
   316 			if (GetBridgeRampDirection(tile) != direction ||
       
   317 					GetBridgeTransportType(tile) != tpf->tracktype) {
       
   318 				return;
       
   319 			}
       
   320 		}
       
   321 	}
       
   322 
       
   323 	tpf->rd.cur_length++;
       
   324 
       
   325 	bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
       
   326 
       
   327 	if ((byte)bits != tpf->var2) {
       
   328 		bits &= _tpfmode1_and[direction];
       
   329 		bits = bits | (bits >> 8);
       
   330 	}
       
   331 	bits &= 0xBF;
       
   332 
       
   333 	if (bits != 0) {
       
   334 		if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) {
       
   335 			do {
       
   336 				i = FIND_FIRST_BIT(bits);
       
   337 				bits = KILL_FIRST_BIT(bits);
       
   338 
       
   339 				tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
       
   340 				rd = tpf->rd;
       
   341 
       
   342 				if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
       
   343 						!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
       
   344 					TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
       
   345 				}
       
   346 				tpf->rd = rd;
       
   347 			} while (bits != 0);
       
   348 		}
       
   349 	}
       
   350 
   357 
   351 	/* the next is only used when signals are checked.
   358 	/* the next is only used when signals are checked.
   352 	 * seems to go in 2 directions simultaneously */
   359 	 * seems to go in 2 directions simultaneously */
   353 
   360 
   354 	/* if i can get rid of this, tail end recursion can be used to minimize
   361 	/* if i can get rid of this, tail end recursion can be used to minimize
   361 		return;
   368 		return;
   362 
   369 
   363 	direction = ReverseDiagDir(direction);
   370 	direction = ReverseDiagDir(direction);
   364 	tile += TileOffsByDiagDir(direction);
   371 	tile += TileOffsByDiagDir(direction);
   365 
   372 
   366 	bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
   373 	uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
   367 	bits |= (bits >> 8);
   374 	bits |= (bits >> 8);
   368 
   375 
   369 	if ( (byte)bits != tpf->var2) {
   376 	if ( (byte)bits != tpf->var2) {
   370 		bits &= _bits_mask[direction];
   377 		bits &= _bits_mask[direction];
   371 	}
   378 	}
   373 	bits &= 0xBF;
   380 	bits &= 0xBF;
   374 	if (bits == 0)
   381 	if (bits == 0)
   375 		return;
   382 		return;
   376 
   383 
   377 	do {
   384 	do {
   378 		i = FIND_FIRST_BIT(bits);
   385 		uint i = FIND_FIRST_BIT(bits);
   379 		bits = KILL_FIRST_BIT(bits);
   386 		bits = KILL_FIRST_BIT(bits);
   380 
   387 
   381 		tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   388 		tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   382 		rd = tpf->rd;
   389 		RememberData rd = tpf->rd;
   383 		if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   390 		if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   384 				!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
   391 				!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
   385 			TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
   392 			TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
   386 		}
   393 		}
   387 		tpf->rd = rd;
   394 		tpf->rd = rd;