npf.c
changeset 2493 f6b4300cc2b0
parent 2416 ba01d6a50765
child 2605 0e7993eabf16
equal deleted inserted replaced
2492:b4785c8f3700 2493:f6b4300cc2b0
    58 	byte exitdir = TrackdirToExitdir(trackdir);
    58 	byte exitdir = TrackdirToExitdir(trackdir);
    59 	TileIndex dst_tile;
    59 	TileIndex dst_tile;
    60 	uint32 ts;
    60 	uint32 ts;
    61 
    61 
    62 	/* Can always go into a tunnel */
    62 	/* Can always go into a tunnel */
    63 	if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (_m[tile].m5 & 3) == exitdir)
    63 	if (IsTileType(tile, MP_TUNNELBRIDGE) && GB(_m[tile].m5, 4, 4) == 0 &&
       
    64 			GB(_m[tile].m5, 0, 2) == exitdir) {
    64 		return false;
    65 		return false;
       
    66 	}
    65 
    67 
    66 	/* Cannot go through the back of a depot */
    68 	/* Cannot go through the back of a depot */
    67 	if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != GetDepotDirection(tile, TRANSPORT_RAIL)))
    69 	if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != GetDepotDirection(tile, TRANSPORT_RAIL)))
    68 		return true;
    70 		return true;
    69 
    71 
    86 		/* Prevent us from entering a depot from behind */
    88 		/* Prevent us from entering a depot from behind */
    87 		if (IsTileDepotType(dst_tile, TRANSPORT_RAIL) && (exitdir != ReverseDiagdir(GetDepotDirection(dst_tile, TRANSPORT_RAIL))))
    89 		if (IsTileDepotType(dst_tile, TRANSPORT_RAIL) && (exitdir != ReverseDiagdir(GetDepotDirection(dst_tile, TRANSPORT_RAIL))))
    88 			return true;
    90 			return true;
    89 
    91 
    90 		/* Prevent us from falling off a slope into a tunnel exit */
    92 		/* Prevent us from falling off a slope into a tunnel exit */
    91 		if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_m[dst_tile].m5 & 0xF0)==0 && (DiagDirection)(_m[dst_tile].m5 & 3) == ReverseDiagdir(exitdir))
    93 		if (IsTileType(dst_tile, MP_TUNNELBRIDGE) &&
    92 				return true;
    94 				GB(_m[dst_tile].m5, 4, 4) == 0 &&
       
    95 				(DiagDirection)GB(_m[dst_tile].m5, 0, 2) == ReverseDiagdir(exitdir)) {
       
    96 			return true;
       
    97 		}
    93 
    98 
    94 		/* Check for oneway signal against us */
    99 		/* Check for oneway signal against us */
    95 		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TYPE_SIGNALS) {
   100 		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TYPE_SIGNALS) {
    96 			if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(FindFirstBit2x64(ts))) && !HasSignalOnTrackdir(dst_tile, FindFirstBit2x64(ts)))
   101 			if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(FindFirstBit2x64(ts))) && !HasSignalOnTrackdir(dst_tile, FindFirstBit2x64(ts)))
    97 				// if one way signal not pointing towards us, stop going in this direction.
   102 				// if one way signal not pointing towards us, stop going in this direction.
   310  * including the exit tile. Requires that this is a Tunnel tile */
   315  * including the exit tile. Requires that this is a Tunnel tile */
   311 static uint NPFTunnelCost(AyStarNode* current)
   316 static uint NPFTunnelCost(AyStarNode* current)
   312 {
   317 {
   313 	DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
   318 	DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
   314 	TileIndex tile = current->tile;
   319 	TileIndex tile = current->tile;
   315 	if ( (DiagDirection)(_m[tile].m5 & 3) == ReverseDiagdir(exitdir)) {
   320 	if ((DiagDirection)GB(_m[tile].m5, 0, 2) == ReverseDiagdir(exitdir)) {
   316 		/* We just popped out if this tunnel, since were
   321 		/* We just popped out if this tunnel, since were
   317 		 * facing the tunnel exit */
   322 		 * facing the tunnel exit */
   318 		FindLengthOfTunnelResult flotr;
   323 		FindLengthOfTunnelResult flotr;
   319 		flotr = FindLengthOfTunnel(tile, ReverseDiagdir(exitdir));
   324 		flotr = FindLengthOfTunnel(tile, ReverseDiagdir(exitdir));
   320 		return flotr.length * NPF_TILE_LENGTH;
   325 		return flotr.length * NPF_TILE_LENGTH;
   362 		switch(GetTileType(tile)) {
   367 		switch(GetTileType(tile)) {
   363 			case MP_RAILWAY:
   368 			case MP_RAILWAY:
   364 				/* DEBUG: mark visited tiles by mowing the grass under them
   369 				/* DEBUG: mark visited tiles by mowing the grass under them
   365 				 * ;-) */
   370 				 * ;-) */
   366 				if (!IsTileDepotType(tile, TRANSPORT_RAIL)) {
   371 				if (!IsTileDepotType(tile, TRANSPORT_RAIL)) {
   367 					_m[tile].m2 &= ~15; /* Clear bits 0-3 */
   372 					SB(_m[tile].m2, 0, 4, 0);
   368 					MarkTileDirtyByTile(tile);
   373 					MarkTileDirtyByTile(tile);
   369 				}
   374 				}
   370 				break;
   375 				break;
   371 			case MP_STREET:
   376 			case MP_STREET:
   372 				if (!IsTileDepotType(tile, TRANSPORT_ROAD)) {
   377 				if (!IsTileDepotType(tile, TRANSPORT_ROAD)) {
   373 					_m[tile].m4 &= ~0x70; /* Clear bits 4-6 */
   378 					SB(_m[tile].m2, 4, 3, 0);
   374 					MarkTileDirtyByTile(tile);
   379 					MarkTileDirtyByTile(tile);
   375 				}
   380 				}
   376 				break;
   381 				break;
   377 			default:
   382 			default:
   378 				break;
   383 				break;
   406 	int32 cost = 0;
   411 	int32 cost = 0;
   407 
   412 
   408 	/* Determine base length */
   413 	/* Determine base length */
   409 	switch (GetTileType(tile)) {
   414 	switch (GetTileType(tile)) {
   410 		case MP_TUNNELBRIDGE:
   415 		case MP_TUNNELBRIDGE:
   411 			if ((_m[tile].m5 & 0xF0)==0) {
   416 			if (GB(_m[tile].m5, 4, 4) == 0) {
   412 				cost = NPFTunnelCost(current);
   417 				cost = NPFTunnelCost(current);
   413 				break;
   418 				break;
   414 			}
   419 			}
   415 			/* Fall through if above if is false, it is a bridge
   420 			/* Fall through if above if is false, it is a bridge
   416 			 * then. We treat that as ordinary road */
   421 			 * then. We treat that as ordinary road */
   450 	OpenListNode new_node;
   455 	OpenListNode new_node;
   451 
   456 
   452 	/* Determine base length */
   457 	/* Determine base length */
   453 	switch (GetTileType(tile)) {
   458 	switch (GetTileType(tile)) {
   454 		case MP_TUNNELBRIDGE:
   459 		case MP_TUNNELBRIDGE:
   455 			if ((_m[tile].m5 & 0xF0)==0) {
   460 			if (GB(_m[tile].m5, 4, 4) == 0) {
   456 				cost = NPFTunnelCost(current);
   461 				cost = NPFTunnelCost(current);
   457 				break;
   462 				break;
   458 			}
   463 			}
   459 			/* Fall through if above if is false, it is a bridge
   464 			/* Fall through if above if is false, it is a bridge
   460 			 * then. We treat that as ordinary rail */
   465 			 * then. We treat that as ordinary rail */
   657 #if 0
   662 #if 0
   658 /* OPTIMISATION: If we are on the middle of a bridge, we will not do the cpu
   663 /* OPTIMISATION: If we are on the middle of a bridge, we will not do the cpu
   659  * intensive owner check, instead we will just assume that if the vehicle
   664  * intensive owner check, instead we will just assume that if the vehicle
   660  * managed to get on the bridge, it is probably allowed to :-)
   665  * managed to get on the bridge, it is probably allowed to :-)
   661  */
   666  */
   662 			if ((_m[tile].m5 & 0xC6) == 0xC0 && (unsigned)(_m[tile].m5 & 0x1) == (enterdir & 0x1)) {
   667 			if ((_m[tile].m5 & 0xC6) == 0xC0 && GB(_m[tile].m5, 0, 1) == (enterdir & 0x1)) {
   663 				/* on the middle part of a railway bridge: find bridge ending */
   668 				/* on the middle part of a railway bridge: find bridge ending */
   664 				while (IsTileType(tile, MP_TUNNELBRIDGE) && !((_m[tile].m5 & 0xC6) == 0x80)) {
   669 				while (IsTileType(tile, MP_TUNNELBRIDGE) && !((_m[tile].m5 & 0xC6) == 0x80)) {
   665 					tile += TileOffsByDir(_m[tile].m5 & 0x1);
   670 					tile += TileOffsByDir(GB(_m[tile].m5, 0, 1));
   666 				}
   671 				}
   667 			}
   672 			}
   668 			/* if we were on a railway middle part, we are now at a railway bridge ending */
   673 			/* if we were on a railway middle part, we are now at a railway bridge ending */
   669 #endif
   674 #endif
   670 			if (
   675 			if (
   671 				(_m[tile].m5 & 0xFC) == 0 /* railway tunnel */
   676 				(_m[tile].m5 & 0xFC) == 0 /* railway tunnel */
   672 				|| (_m[tile].m5 & 0xC6) == 0x80 /* railway bridge ending */
   677 				|| (_m[tile].m5 & 0xC6) == 0x80 /* railway bridge ending */
   673 				|| ((_m[tile].m5 & 0xF8) == 0xE0 && ((unsigned)_m[tile].m5 & 0x1) != (enterdir & 0x1)) /* railway under bridge */
   678 				|| ((_m[tile].m5 & 0xF8) == 0xE0 && GB(_m[tile].m5, 0, 1) != (enterdir & 0x1)) /* railway under bridge */
   674 				)
   679 				)
   675 				return IsTileOwner(tile, owner);
   680 				return IsTileOwner(tile, owner);
   676 			break;
   681 			break;
   677 		default:
   682 		default:
   678 			break;
   683 			break;
   702 	DEBUG(npf, 4)("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
   707 	DEBUG(npf, 4)("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
   703 
   708 
   704 	aystar->EndNodeCheck(aystar, current);
   709 	aystar->EndNodeCheck(aystar, current);
   705 
   710 
   706 	/* Find dest tile */
   711 	/* Find dest tile */
   707 	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_m[src_tile].m5 & 0xF0)==0 && (DiagDirection)(_m[src_tile].m5 & 3) == src_exitdir) {
   712 	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && GB(_m[src_tile].m5, 4, 4) == 0 &&
       
   713 			(DiagDirection)GB(_m[src_tile].m5, 0, 2) == src_exitdir) {
   708 		/* This is a tunnel. We know this tunnel is our type,
   714 		/* This is a tunnel. We know this tunnel is our type,
   709 		 * otherwise we wouldn't have got here. It is also facing us,
   715 		 * otherwise we wouldn't have got here. It is also facing us,
   710 		 * so we should skip it's body */
   716 		 * so we should skip it's body */
   711 		flotr = FindLengthOfTunnel(src_tile, src_exitdir);
   717 		flotr = FindLengthOfTunnel(src_tile, src_exitdir);
   712 		dst_tile = flotr.tile;
   718 		dst_tile = flotr.tile;
   747 	}
   753 	}
   748 
   754 
   749 	/* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note
   755 	/* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note
   750 	 * that I can enter the tunnel from a tile below the tunnel entrance. This
   756 	 * that I can enter the tunnel from a tile below the tunnel entrance. This
   751 	 * solves the problem of vehicles wanting to drive off a tunnel entrance */
   757 	 * solves the problem of vehicles wanting to drive off a tunnel entrance */
   752 	if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_m[dst_tile].m5 & 0xF0) == 0 && GetTileZ(dst_tile) < GetTileZ(src_tile))
   758 	if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && GB(_m[dst_tile].m5, 4, 4) == 0 &&
       
   759 			GetTileZ(dst_tile) < GetTileZ(src_tile)) {
   753 		return;
   760 		return;
       
   761 	}
   754 
   762 
   755 	/* check correct rail type (mono, maglev, etc) */
   763 	/* check correct rail type (mono, maglev, etc) */
   756 	if (type == TRANSPORT_RAIL) {
   764 	if (type == TRANSPORT_RAIL) {
   757 		RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
   765 		RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
   758 		if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type))
   766 		if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type))