diff options
-rw-r--r-- | src/roadveh_cmd.cpp | 22 | ||||
-rw-r--r-- | src/station.cpp | 49 | ||||
-rw-r--r-- | src/station.h | 10 | ||||
-rw-r--r-- | src/station_cmd.cpp | 22 |
4 files changed, 76 insertions, 27 deletions
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 3a898373e..3c1278985 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -490,11 +490,11 @@ static void ClearCrashedStation(Vehicle *v) { RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); - // mark station as not busy - CLRBIT(rs->status, 7); + /* Mark the station entrance as not busy */ + rs->SetEntranceBusy(false); - // free parking bay - SETBIT(rs->status, HASBIT(v->u.road.state, 1) ? 1 : 0); + /* Free the parking bay */ + rs->FreeBay(HASBIT(v->u.road.state, 1) ? 1 : 0); } static void RoadVehDelete(Vehicle *v) @@ -1080,7 +1080,7 @@ static int RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection enterdir } else { // proper station type, check if there is free loading bay if (!_patches.roadveh_queue && - GB(GetRoadStopByTile(tile, rstype)->status, 0, 2) == 0) { + !GetRoadStopByTile(tile, rstype)->HasFreeBay()) { // station is full and RV queuing is off bitmask = 0; } @@ -1411,8 +1411,8 @@ again: RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); /* Vehicle is leaving a road stop tile, mark bay as free and clear the usage bit */ - SETBIT(rs->status, v->u.road.state & 2 ? 1 : 0); // set bay as free - CLRBIT(rs->status, 7); // usage bit + rs->FreeBay(HASBIT(v->u.road.state, 1) ? 1 : 0); + rs->SetEntranceBusy(false); } } @@ -1527,7 +1527,7 @@ again: Order old_order; /* Clear road stop busy bit to allow another vehicle to enter or leave */ - CLRBIT(rs->status, 7); + rs->SetEntranceBusy(false); v->last_station_visited = GetStationIndex(v->tile); @@ -1554,8 +1554,8 @@ again: /* Vehicle is ready to leave a bay in a road stop */ if (v->current_order.type != OT_GOTO_DEPOT) { - if (HASBIT(rs->status, 7)) { - /* Road stop is busy, so wait */ + if (rs->IsEntranceBusy()) { + /* Road stop entrance is busy, so wait */ v->cur_speed = 0; return; } @@ -1564,7 +1564,7 @@ again: ClearSlot(v); } /* Set road stop busy bit to prevent another vehicle trying to enter or leave */ - SETBIT(rs->status, 7); + rs->SetEntranceBusy(true); if (rs == v->u.road.slot) { /* We are leaving the correct station */ diff --git a/src/station.cpp b/src/station.cpp index 985d39850..296a974fd 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -437,3 +437,52 @@ bool RoadStop::IsValid() const { return xy != INVALID_TILE; } + +/** Checks whether there is a free bay in this road stop */ +bool RoadStop::HasFreeBay() const +{ + return GB(status, 0, MAX_BAY_COUNT) != 0; +} + +/** + * Allocates a bay + * @return the allocated bay number + * @pre this->HasFreeBay() + */ +uint RoadStop::AllocateBay() +{ + /* Find the first free bay. If the bit is set, the bay is free. */ + for (uint bay_nr = 0; bay_nr < MAX_BAY_COUNT; bay_nr++) { + if (HASBIT(status, bay_nr)) { + CLRBIT(status, bay_nr); + return bay_nr; + } + } + + /* There has to be a free bay (precondition) */ + NOT_REACHED(); + return 0; +} + +/** + * Frees the given bay + * @param nr the number of the bay to free + */ +void RoadStop::FreeBay(uint nr) +{ + assert(nr < MAX_BAY_COUNT); + SETBIT(status, nr); +} + + +/** Checks whether the entrance of the road stop is occupied by a vehicle */ +bool RoadStop::IsEntranceBusy() const +{ + return HASBIT(status, 7); +} + +/** Makes an entrance occupied or free */ +void RoadStop::SetEntranceBusy(bool busy) +{ + SB(status, 7, 1, !!busy); +} diff --git a/src/station.h b/src/station.h index eb345f0d0..d9f6d0c32 100644 --- a/src/station.h +++ b/src/station.h @@ -44,10 +44,11 @@ struct RoadStop { static const int cDebugCtorLevel = 3; ///< Debug level on which Contructor / Destructor messages are printed static const uint LIMIT = 16; ///< The maximum amount of roadstops that are allowed at a single station + static const uint MAX_BAY_COUNT = 2; ///< The maximum number of loading bays TileIndex xy; ///< Position on the map RoadStopID index; ///< Global (i.e. pool-wide) index - byte status; ///< Current status of the Stop. Like which spot is taken. TODO - enumify this + byte status; ///< Current status of the Stop. Like which spot is taken. Access using *Bay and *Busy functions. byte num_vehicles; ///< Number of vehicles currently slotted to this stop struct RoadStop *next; ///< Next stop of the given type at this station @@ -62,6 +63,13 @@ struct RoadStop { void operator delete(void *rs, int index); bool IsValid() const; + + /* For accessing status */ + bool HasFreeBay() const; + uint AllocateBay(); + void FreeBay(uint nr); + bool IsEntranceBusy() const; + void SetEntranceBusy(bool busy); protected: static RoadStop *AllocateRaw(void); }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 49cfa5ca3..2e3ae49c6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2278,25 +2278,17 @@ static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y) /* Attempt to allocate a parking bay in a road stop */ RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); - /* rs->status bits 0 and 1 describe current the two parking spots. - * 0 means occupied, 1 means free. */ - - // Check if station is busy or if there are no free bays. - if (HASBIT(rs->status, 7) || GB(rs->status, 0, 2) == 0) - return 8; + /* Check if station is busy or if there are no free bays. */ + if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return 8; v->u.road.state += 32; - // if the first bay is free, allocate that, else the second bay must be free. - if (HASBIT(rs->status, 0)) { - CLRBIT(rs->status, 0); - } else { - CLRBIT(rs->status, 1); - v->u.road.state += 2; - } + /* Allocate a bay and update the road state */ + uint bay_nr = rs->AllocateBay(); + SB(v->u.road.state, 1, 1, bay_nr); - // mark the station as busy - SETBIT(rs->status, 7); + /* Mark the station entrace as busy */ + rs->SetEntranceBusy(true); } } } |