# HG changeset patch # User rubidium # Date 1187983158 0 # Node ID c1a170885a60f183157fab67fca9961e79aad88b # Parent 46224d0b47527f688cd42297087ba42427760de7 (svn r10974) -Fix [FS#1144, FS#1155]: road vehicles that could not (properly) use a road stop still tried to go to that road stop. diff -r 46224d0b4752 -r c1a170885a60 src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp Fri Aug 24 17:49:42 2007 +0000 +++ b/src/roadveh_cmd.cpp Fri Aug 24 19:19:18 2007 +0000 @@ -794,24 +794,17 @@ switch (order->type) { case OT_GOTO_STATION: { - const RoadStop* rs; - if (order->dest == v->last_station_visited) { v->last_station_visited = INVALID_STATION; } - rs = GetStation(order->dest)->GetPrimaryRoadStop( - IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK - ); + const RoadStop *rs = GetStation(order->dest)->GetPrimaryRoadStop(v); TileIndex dest = INVALID_TILE; if (rs != NULL) { uint mindist = MAX_UVALUE(uint); - for (; rs != NULL; rs = rs->next) { - /* The vehicle cannot go to this roadstop */ - if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) == ROADTYPES_NONE) continue; - + for (; rs != NULL; rs = rs->GetNextRoadStop(v)) { uint dist = DistanceManhattan(v->tile, rs->xy); if (dist < mindist) { @@ -1143,7 +1136,7 @@ FindRoadToChooseData frd; Trackdir best_track; - uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes); + uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes); TrackdirBits signal = (TrackdirBits)GB(r, 16, 16); TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16); @@ -1154,8 +1147,9 @@ } } else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) { /* Standard road stop (drive-through stops are treated as normal road) */ - if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) { - /* different station owner or wrong orientation */ + + if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) { + /* different station owner or wrong orientation or the vehicle has articulated parts */ trackdirs = TRACKDIR_BIT_NONE; } else { /* Our station */ @@ -1166,7 +1160,7 @@ trackdirs = TRACKDIR_BIT_NONE; } else { /* Proper station type, check if there is free loading bay */ - if (!_patches.roadveh_queue && IsStandardRoadStopTile(tile) && + if (!_patches.roadveh_queue && IsStandardRoadStopTile(tile) && !GetRoadStopByTile(tile, rstype)->HasFreeBay()) { /* Station is full and RV queuing is off */ trackdirs = TRACKDIR_BIT_NONE; @@ -1922,9 +1916,9 @@ /* update destination */ if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) { - Station* st = GetStation(v->current_order.dest); - RoadStop* rs = st->GetPrimaryRoadStop(IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK); - RoadStop* best = NULL; + Station *st = GetStation(v->current_order.dest); + RoadStop *rs = st->GetPrimaryRoadStop(v); + RoadStop *best = NULL; if (rs != NULL) { /* We try to obtain a slot if: @@ -1941,7 +1935,7 @@ v->unitnumber, v->index, st->index, st->xy ); /* Now we find the nearest road stop that has a free slot */ - for (; rs != NULL; rs = rs->next) { + for (; rs != NULL; rs = rs->GetNextRoadStop(v)) { dist = RoadFindPathToStop(v, rs->xy); if (dist == UINT_MAX) { DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy); diff -r 46224d0b4752 -r c1a170885a60 src/station.cpp --- a/src/station.cpp Fri Aug 24 17:49:42 2007 +0000 +++ b/src/station.cpp Fri Aug 24 19:19:18 2007 +0000 @@ -34,6 +34,8 @@ #include "yapf/yapf.h" #include "date.h" #include "helpers.hpp" +#include "cargotype.h" +#include "roadveh.h" Station::Station(TileIndex tile) { @@ -92,6 +94,29 @@ } } + +/** + * Get the primary road stop (the first road stop) that the given vehicle can load/unload. + * @param v the vehicle to get the first road stop for + * @return the first roadstop that this vehicle can load at + */ +RoadStop *Station::GetPrimaryRoadStop(const Vehicle *v) const +{ + RoadStop *rs = this->GetPrimaryRoadStop(IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK); + + for (; rs != NULL; rs = rs->next) { + /* The vehicle cannot go to this roadstop (different roadtype) */ + if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) == ROADTYPES_NONE) continue; + /* The vehicle is articulated and can therefor not go the a standard road stop */ + if (IsStandardRoadStopTile(rs->xy) && RoadVehHasArticPart(v)) continue; + + /* The vehicle can actually go to this road stop. So, return it! */ + break; + } + + return rs; +} + /** Called when new facility is built on the station. If it is the first facility * it initializes also 'xy' and 'random_bits' members */ void Station::AddFacility(byte new_facility_bit, TileIndex facil_xy) @@ -480,3 +505,23 @@ { SB(status, 7, 1, busy); } + +/** + * Get the next road stop accessible by this vehicle. + * @param v the vehicle to get the next road stop for. + * @return the next road stop accessible. + */ +RoadStop *RoadStop::GetNextRoadStop(const Vehicle *v) const +{ + for (RoadStop *rs = this->next; rs != NULL; rs = rs->next) { + /* The vehicle cannot go to this roadstop (different roadtype) */ + if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) != ROADTYPES_NONE) continue; + /* The vehicle is articulated and can therefor not go the a standard road stop */ + if (IsStandardRoadStopTile(rs->xy) && RoadVehHasArticPart(v)) continue; + + /* The vehicle can actually go to this road stop. So, return it! */ + return rs; + } + + return NULL; +} diff -r 46224d0b4752 -r c1a170885a60 src/station.h --- a/src/station.h Fri Aug 24 17:49:42 2007 +0000 +++ b/src/station.h Fri Aug 24 19:19:18 2007 +0000 @@ -70,6 +70,8 @@ void FreeBay(uint nr); bool IsEntranceBusy() const; void SetEntranceBusy(bool busy); + + RoadStop *GetNextRoadStop(const Vehicle *v) const; }; struct StationSpecList { @@ -102,17 +104,19 @@ }; struct Station : PoolItem { - public: - RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const - { - return type == RoadStop::BUS ? bus_stops : truck_stops; - } +public: + RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const + { + return type == RoadStop::BUS ? bus_stops : truck_stops; + } - const AirportFTAClass *Airport() const - { - if (airport_tile == 0) return GetAirport(AT_DUMMY); - return GetAirport(airport_type); - } + RoadStop *GetPrimaryRoadStop(const Vehicle *v) const; + + const AirportFTAClass *Airport() const + { + if (airport_tile == 0) return GetAirport(AT_DUMMY); + return GetAirport(airport_type); + } TileIndex xy; RoadStop *bus_stops; diff -r 46224d0b4752 -r c1a170885a60 src/station_cmd.cpp --- a/src/station_cmd.cpp Fri Aug 24 17:49:42 2007 +0000 +++ b/src/station_cmd.cpp Fri Aug 24 19:19:18 2007 +0000 @@ -2343,8 +2343,8 @@ } /* For normal (non drive-through) road stops */ - /* Check if station is busy or if there are no free bays. */ - if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER; + /* Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */ + if (rs->IsEntranceBusy() || !rs->HasFreeBay() || RoadVehHasArticPart(v)) return VETSB_CANNOT_ENTER; SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);