(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.
authorrubidium
Fri, 24 Aug 2007 19:19:18 +0000
changeset 7965 c1a170885a60
parent 7964 46224d0b4752
child 7966 24f03a15d679
(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.
src/roadveh_cmd.cpp
src/station.cpp
src/station.h
src/station_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);
--- 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;
+}
--- 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<Station, StationID, &_Station_pool> {
-	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;
--- 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);