/** * Finds out if a given company's vehicles are allowed to enter a given tile. * @param owner The owner of the vehicle. * @param tile The tile that is about to be entered. * @param enterdir The direction in which the vehicle wants to enter the tile. * @return true if the vehicle can enter the tile. * @todo This function should be used in other places than just NPF, * maybe moved to another file too. */ static bool CanEnterTileOwnerCheck(Owner owner, TileIndex tile, DiagDirection enterdir) { if (IsTileType(tile, MP_RAILWAY) || // Rail tile (also rail depot) HasStationTileRail(tile) || // Rail station tile/waypoint IsRoadDepotTile(tile) || // Road depot tile IsStandardRoadStopTile(tile)) { // Road station tile (but not drive-through stops) return IsTileOwner(tile, owner); // You need to own these tiles entirely to use them } switch (GetTileType(tile)) { case MP_ROAD: /* rail-road crossing : are we looking at the railway part? */ if (IsLevelCrossing(tile) && DiagDirToAxis(enterdir) != GetCrossingRoadAxis(tile)) { return IsTileOwner(tile, owner); // Railway needs owner check, while the street is public } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) { return IsTileOwner(tile, owner); } break; default: break; } return true; // no need to check }
/* static */ TileIndex ScriptRoad::GetRoadDepotFrontTile(TileIndex depot) { if (!IsRoadDepotTile(depot)) return INVALID_TILE; return depot + ::TileOffsByDiagDir(::GetRoadDepotDirection(depot)); }
/** Called by YAPF to detect if node ends in the desired destination */ inline bool PfDetectDestination(Node& n) { bool bDest = IsRoadDepotTile(n.m_segment_last_tile); return bDest; }
inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) { return IsRoadDepotTile(tile); }
/** * Called by YAPF to calculate the cost from the origin to the given node. * Calculates only the cost of given node, adds it to the parent node cost * and stores the result into Node::m_cost member */ inline bool PfCalcCost(Node& n, const TrackFollower *tf) { int segment_cost = 0; uint tiles = 0; /* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */ TileIndex tile = n.m_key.m_tile; Trackdir trackdir = n.m_key.m_td; for (;;) { /* base tile cost depending on distance between edges */ segment_cost += Yapf().OneTileCost(tile, trackdir); const RoadVehicle *v = Yapf().GetVehicle(); /* we have reached the vehicle's destination - segment should end here to avoid target skipping */ if (Yapf().PfDetectDestinationTile(tile, trackdir)) break; /* stop if we have just entered the depot */ if (IsRoadDepotTile(tile) && trackdir == DiagDirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) { /* next time we will reverse and leave the depot */ break; } /* if there are no reachable trackdirs on new tile, we have end of road */ TrackFollower F(Yapf().GetVehicle()); if (!F.Follow(tile, trackdir)) break; /* if there are more trackdirs available & reachable, we are at the end of segment */ if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break; Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits); /* stop if RV is on simple loop with no junctions */ if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false; /* if we skipped some tunnel tiles, add their cost */ segment_cost += F.m_tiles_skipped * YAPF_TILE_LENGTH; tiles += F.m_tiles_skipped + 1; /* add hilly terrain penalty */ segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir); /* add min/max speed penalties */ int min_speed = 0; int max_veh_speed = v->GetDisplayMaxSpeed(); int max_speed = F.GetSpeedLimit(&min_speed); if (max_speed < max_veh_speed) segment_cost += 1 * (max_veh_speed - max_speed); if (min_speed > max_veh_speed) segment_cost += 10 * (min_speed - max_veh_speed); /* move to the next tile */ tile = F.m_new_tile; trackdir = new_td; if (tiles > MAX_MAP_SIZE) break; } /* save end of segment back to the node */ n.m_segment_last_tile = tile; n.m_segment_last_td = trackdir; /* save also tile cost */ int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0; n.m_cost = parent_cost + segment_cost; return true; }