diff --git a/src/roadstop.cpp b/src/roadstop.cpp --- a/src/roadstop.cpp +++ b/src/roadstop.cpp @@ -47,6 +47,63 @@ RoadStop *RoadStop::GetNextRoadStop(cons } /** + * 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