mirror of https://github.com/OpenTTD/OpenTTD.git
(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.
This commit is contained in:
parent
6c061ecfb4
commit
8a86526d05
|
@ -794,24 +794,17 @@ static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
|
|
||||||
switch (order->type) {
|
switch (order->type) {
|
||||||
case OT_GOTO_STATION: {
|
case OT_GOTO_STATION: {
|
||||||
const RoadStop* rs;
|
|
||||||
|
|
||||||
if (order->dest == v->last_station_visited) {
|
if (order->dest == v->last_station_visited) {
|
||||||
v->last_station_visited = INVALID_STATION;
|
v->last_station_visited = INVALID_STATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
rs = GetStation(order->dest)->GetPrimaryRoadStop(
|
const RoadStop *rs = GetStation(order->dest)->GetPrimaryRoadStop(v);
|
||||||
IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK
|
|
||||||
);
|
|
||||||
|
|
||||||
TileIndex dest = INVALID_TILE;
|
TileIndex dest = INVALID_TILE;
|
||||||
if (rs != NULL) {
|
if (rs != NULL) {
|
||||||
uint mindist = MAX_UVALUE(uint);
|
uint mindist = MAX_UVALUE(uint);
|
||||||
|
|
||||||
for (; rs != NULL; rs = rs->next) {
|
for (; rs != NULL; rs = rs->GetNextRoadStop(v)) {
|
||||||
/* The vehicle cannot go to this roadstop */
|
|
||||||
if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) == ROADTYPES_NONE) continue;
|
|
||||||
|
|
||||||
uint dist = DistanceManhattan(v->tile, rs->xy);
|
uint dist = DistanceManhattan(v->tile, rs->xy);
|
||||||
|
|
||||||
if (dist < mindist) {
|
if (dist < mindist) {
|
||||||
|
@ -1143,7 +1136,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
|
||||||
FindRoadToChooseData frd;
|
FindRoadToChooseData frd;
|
||||||
Trackdir best_track;
|
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 signal = (TrackdirBits)GB(r, 16, 16);
|
||||||
TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16);
|
TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16);
|
||||||
|
|
||||||
|
@ -1154,8 +1147,9 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
|
||||||
}
|
}
|
||||||
} else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
|
} else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
|
||||||
/* Standard road stop (drive-through stops are treated as normal road) */
|
/* 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;
|
trackdirs = TRACKDIR_BIT_NONE;
|
||||||
} else {
|
} else {
|
||||||
/* Our station */
|
/* Our station */
|
||||||
|
@ -1166,7 +1160,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
|
||||||
trackdirs = TRACKDIR_BIT_NONE;
|
trackdirs = TRACKDIR_BIT_NONE;
|
||||||
} else {
|
} else {
|
||||||
/* Proper station type, check if there is free loading bay */
|
/* 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()) {
|
!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
|
||||||
/* Station is full and RV queuing is off */
|
/* Station is full and RV queuing is off */
|
||||||
trackdirs = TRACKDIR_BIT_NONE;
|
trackdirs = TRACKDIR_BIT_NONE;
|
||||||
|
@ -1922,9 +1916,9 @@ void OnNewDay_RoadVeh(Vehicle *v)
|
||||||
|
|
||||||
/* update destination */
|
/* update destination */
|
||||||
if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) {
|
if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) {
|
||||||
Station* st = GetStation(v->current_order.dest);
|
Station *st = GetStation(v->current_order.dest);
|
||||||
RoadStop* rs = st->GetPrimaryRoadStop(IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK);
|
RoadStop *rs = st->GetPrimaryRoadStop(v);
|
||||||
RoadStop* best = NULL;
|
RoadStop *best = NULL;
|
||||||
|
|
||||||
if (rs != NULL) {
|
if (rs != NULL) {
|
||||||
/* We try to obtain a slot if:
|
/* We try to obtain a slot if:
|
||||||
|
@ -1941,7 +1935,7 @@ void OnNewDay_RoadVeh(Vehicle *v)
|
||||||
v->unitnumber, v->index, st->index, st->xy
|
v->unitnumber, v->index, st->index, st->xy
|
||||||
);
|
);
|
||||||
/* Now we find the nearest road stop that has a free slot */
|
/* 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);
|
dist = RoadFindPathToStop(v, rs->xy);
|
||||||
if (dist == UINT_MAX) {
|
if (dist == UINT_MAX) {
|
||||||
DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy);
|
DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy);
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "yapf/yapf.h"
|
#include "yapf/yapf.h"
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
#include "cargotype.h"
|
||||||
|
#include "roadveh.h"
|
||||||
|
|
||||||
Station::Station(TileIndex tile)
|
Station::Station(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +94,29 @@ Station::~Station()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
/** Called when new facility is built on the station. If it is the first facility
|
||||||
* it initializes also 'xy' and 'random_bits' members */
|
* it initializes also 'xy' and 'random_bits' members */
|
||||||
void Station::AddFacility(byte new_facility_bit, TileIndex facil_xy)
|
void Station::AddFacility(byte new_facility_bit, TileIndex facil_xy)
|
||||||
|
@ -480,3 +505,23 @@ void RoadStop::SetEntranceBusy(bool busy)
|
||||||
{
|
{
|
||||||
SB(status, 7, 1, busy);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ struct RoadStop : PoolItem<RoadStop, RoadStopID, &_RoadStop_pool> {
|
||||||
void FreeBay(uint nr);
|
void FreeBay(uint nr);
|
||||||
bool IsEntranceBusy() const;
|
bool IsEntranceBusy() const;
|
||||||
void SetEntranceBusy(bool busy);
|
void SetEntranceBusy(bool busy);
|
||||||
|
|
||||||
|
RoadStop *GetNextRoadStop(const Vehicle *v) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StationSpecList {
|
struct StationSpecList {
|
||||||
|
@ -102,17 +104,19 @@ struct StationRect : public Rect {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Station : PoolItem<Station, StationID, &_Station_pool> {
|
struct Station : PoolItem<Station, StationID, &_Station_pool> {
|
||||||
public:
|
public:
|
||||||
RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const
|
RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const
|
||||||
{
|
{
|
||||||
return type == RoadStop::BUS ? bus_stops : truck_stops;
|
return type == RoadStop::BUS ? bus_stops : truck_stops;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AirportFTAClass *Airport() const
|
RoadStop *GetPrimaryRoadStop(const Vehicle *v) const;
|
||||||
{
|
|
||||||
if (airport_tile == 0) return GetAirport(AT_DUMMY);
|
const AirportFTAClass *Airport() const
|
||||||
return GetAirport(airport_type);
|
{
|
||||||
}
|
if (airport_tile == 0) return GetAirport(AT_DUMMY);
|
||||||
|
return GetAirport(airport_type);
|
||||||
|
}
|
||||||
|
|
||||||
TileIndex xy;
|
TileIndex xy;
|
||||||
RoadStop *bus_stops;
|
RoadStop *bus_stops;
|
||||||
|
|
|
@ -2343,8 +2343,8 @@ static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For normal (non drive-through) road stops */
|
/* For normal (non drive-through) road stops */
|
||||||
/* Check if station is busy or if there are no free bays. */
|
/* Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */
|
||||||
if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
|
if (rs->IsEntranceBusy() || !rs->HasFreeBay() || RoadVehHasArticPart(v)) return VETSB_CANNOT_ENTER;
|
||||||
|
|
||||||
SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
|
SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue