summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pathfinder/yapf/yapf_road.cpp3
-rw-r--r--src/roadstop.cpp57
-rw-r--r--src/roadstop_base.h49
-rw-r--r--src/roadveh_cmd.cpp20
-rw-r--r--src/saveload/afterload.cpp2
-rw-r--r--src/station_cmd.cpp40
6 files changed, 89 insertions, 82 deletions
diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp
index a565def27..789100b3f 100644
--- a/src/pathfinder/yapf/yapf_road.cpp
+++ b/src/pathfinder/yapf/yapf_road.cpp
@@ -10,10 +10,9 @@
/** @file yapf_road.cpp The road pathfinding. */
#include "../../stdafx.h"
-#include "../../roadstop_base.h"
-
#include "yapf.hpp"
#include "yapf_node_road.hpp"
+#include "../../roadstop_base.h"
template <class Types>
diff --git a/src/roadstop.cpp b/src/roadstop.cpp
index 67b54fdbd..7d9497de4 100644
--- a/src/roadstop.cpp
+++ b/src/roadstop.cpp
@@ -47,6 +47,63 @@ RoadStop *RoadStop::GetNextRoadStop(const RoadVehicle *v) const
}
/**
+ * Leave the road stop
+ * @param rv the vehicle that leaves the stop
+ */
+void RoadStop::Leave(RoadVehicle *rv)
+{
+ /* Vehicle is leaving a road stop tile, mark bay as free
+ * For drive-through stops, only do it if the vehicle stopped here */
+ if (IsStandardRoadStopTile(rv->tile) || HasBit(rv->state, RVS_IS_STOPPING)) {
+ this->FreeBay(HasBit(rv->state, RVS_USING_SECOND_BAY));
+ ClrBit(rv->state, RVS_IS_STOPPING);
+ }
+ if (IsStandardRoadStopTile(rv->tile)) this->SetEntranceBusy(false);
+}
+
+/**
+ * Enter the road stop
+ * @param rv the vehicle that enters the stop
+ * @return whether the road stop could actually be entered
+ */
+bool RoadStop::Enter(RoadVehicle *rv)
+{
+ if (IsStandardRoadStopTile(this->xy)) {
+ /* For normal (non drive-through) road stops
+ * Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */
+ if (this->IsEntranceBusy() || !this->HasFreeBay() || rv->HasArticulatedPart()) return false;
+
+ SetBit(rv->state, RVS_IN_ROAD_STOP);
+
+ /* Allocate a bay and update the road state */
+ uint bay_nr = this->AllocateBay();
+ SB(rv->state, RVS_USING_SECOND_BAY, 1, bay_nr);
+
+ /* Mark the station entrace as busy */
+ this->SetEntranceBusy(true);
+ return true;
+ }
+
+ /* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
+ byte side = ((DirToDiagDir(rv->direction) == ReverseDiagDir(GetRoadStopDir(this->xy))) == (rv->overtaking == 0)) ? 0 : 1;
+
+ if (!this->IsFreeBay(side)) return false;
+
+ /* Check if the vehicle is stopping at this road stop */
+ if (GetRoadStopType(this->xy) == (rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
+ rv->current_order.ShouldStopAtStation(rv, GetStationIndex(this->xy))) {
+ SetBit(rv->state, RVS_IS_STOPPING);
+ this->AllocateDriveThroughBay(side);
+ }
+
+ /* Indicate if vehicle is using second bay. */
+ if (side == 1) SetBit(rv->state, RVS_USING_SECOND_BAY);
+ /* Indicate a drive-through stop */
+ SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
+ return true;
+}
+
+/**
* Find a roadstop at given tile
* @param tile tile with roadstop
* @param type roadstop type
diff --git a/src/roadstop_base.h b/src/roadstop_base.h
index 4548de4bf..c3cd359bd 100644
--- a/src/roadstop_base.h
+++ b/src/roadstop_base.h
@@ -63,6 +63,32 @@ struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> {
}
/**
+ * Checks whether the entrance of the road stop is occupied by a vehicle
+ * @return is entrance busy?
+ */
+ FORCEINLINE bool IsEntranceBusy() const
+ {
+ return HasBit(this->status, RSSFB_ENTRY_BUSY);
+ }
+
+ /**
+ * Makes an entrance occupied or free
+ * @param busy if true, marks busy; free otherwise
+ */
+ FORCEINLINE void SetEntranceBusy(bool busy)
+ {
+ SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
+ }
+
+ void Leave(RoadVehicle *rv);
+ bool Enter(RoadVehicle *rv);
+
+ RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
+
+ static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
+
+private:
+ /**
* Allocates a bay
* @return the allocated bay number
* @pre this->HasFreeBay()
@@ -98,29 +124,6 @@ struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> {
assert(nr < RSSFB_BAY_COUNT);
SetBit(this->status, nr);
}
-
-
- /**
- * Checks whether the entrance of the road stop is occupied by a vehicle
- * @return is entrance busy?
- */
- FORCEINLINE bool IsEntranceBusy() const
- {
- return HasBit(this->status, RSSFB_ENTRY_BUSY);
- }
-
- /**
- * Makes an entrance occupied or free
- * @param busy if true, marks busy; free otherwise
- */
- FORCEINLINE void SetEntranceBusy(bool busy)
- {
- SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
- }
-
- RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
-
- static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
};
#define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start)
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index 92b10b5ff..ab9982b87 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -465,13 +465,7 @@ void RoadVehicle::UpdateDeltaXY(Direction direction)
static void ClearCrashedStation(RoadVehicle *v)
{
- RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
-
- /* Mark the station entrance as not busy */
- rs->SetEntranceBusy(false);
-
- /* Free the parking bay */
- rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
+ RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
}
static void DeleteLastRoadVeh(RoadVehicle *v)
@@ -1317,17 +1311,7 @@ again:
v->cur_speed = 0;
return false;
}
- if (IsRoadStop(v->tile)) {
- RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
-
- /* Vehicle is leaving a road stop tile, mark bay as free
- * For drive-through stops, only do it if the vehicle stopped here */
- if (IsStandardRoadStopTile(v->tile) || HasBit(v->state, RVS_IS_STOPPING)) {
- rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
- ClrBit(v->state, RVS_IS_STOPPING);
- }
- if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false);
- }
+ if (IsRoadStop(v->tile)) RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
}
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 2d7013291..281b3bc33 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -12,7 +12,6 @@
#include "../stdafx.h"
#include "../void_map.h"
#include "../signs_base.h"
-#include "../roadstop_base.h"
#include "../depot_base.h"
#include "../window_func.h"
#include "../fios.h"
@@ -33,6 +32,7 @@
#include "../train.h"
#include "../station_base.h"
#include "../waypoint_base.h"
+#include "../roadstop_base.h"
#include "../tunnelbridge_map.h"
#include "../landscape.h"
#include "../pathfinder/yapf/yapf_cache.h"
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 2fd46ca82..f83daf62d 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2648,9 +2648,8 @@ static bool ClickTile_Station(TileIndex tile)
static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
{
- StationID station_id = GetStationIndex(tile);
-
if (v->type == VEH_TRAIN) {
+ StationID station_id = GetStationIndex(tile);
if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
if (!IsRailStation(tile) || !Train::From(v)->IsFrontEngine()) return VETSB_CONTINUE;
@@ -2688,42 +2687,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) {
if (IsRoadStop(tile) && rv->IsRoadVehFront()) {
/* Attempt to allocate a parking bay in a road stop */
- RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile));
-
- if (IsDriveThroughStopTile(tile)) {
- if (!rv->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
-
- /* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
- byte side = ((DirToDiagDir(rv->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (rv->overtaking == 0)) ? 0 : 1;
-
- if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
-
- /* Check if the vehicle is stopping at this road stop */
- if (GetRoadStopType(tile) == (rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
- rv->current_order.GetDestination() == GetStationIndex(tile)) {
- SetBit(rv->state, RVS_IS_STOPPING);
- rs->AllocateDriveThroughBay(side);
- }
-
- /* Indicate if vehicle is using second bay. */
- if (side == 1) SetBit(rv->state, RVS_USING_SECOND_BAY);
- /* Indicate a drive-through stop */
- SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
- return VETSB_CONTINUE;
- }
-
- /* For normal (non drive-through) road stops
- * Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */
- if (rs->IsEntranceBusy() || !rs->HasFreeBay() || rv->HasArticulatedPart()) return VETSB_CANNOT_ENTER;
-
- SetBit(rv->state, RVS_IN_ROAD_STOP);
-
- /* Allocate a bay and update the road state */
- uint bay_nr = rs->AllocateBay();
- SB(rv->state, RVS_USING_SECOND_BAY, 1, bay_nr);
-
- /* Mark the station entrace as busy */
- rs->SetEntranceBusy(true);
+ return RoadStop::GetByTile(tile, GetRoadStopType(tile))->Enter(rv) ? VETSB_CONTINUE : VETSB_CANNOT_ENTER;
}
}
}