From ca1caa1aa572f60102b6bb2dbdd8bc55614dd171 Mon Sep 17 00:00:00 2001 From: zacc Date: Wed, 13 Mar 2024 12:22:45 +0900 Subject: [PATCH] Change: Calculate Drive Through RoadStop occupied level with regard to when a stopped vehicle is blocking access to tiles. --- src/roadstop.cpp | 20 +++++++++++++++----- src/roadstop_base.h | 5 +++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/roadstop.cpp b/src/roadstop.cpp index 2e4f441973..29674df483 100644 --- a/src/roadstop.cpp +++ b/src/roadstop.cpp @@ -221,7 +221,7 @@ void RoadStop::Leave(RoadVehicle *rv) this->SetEntranceBusy(false); } else { /* Otherwise just leave the drive through's entry cache. */ - this->GetEntry(DirToDiagDir(rv->direction))->Leave(rv); + this->GetEntry(DirToDiagDir(rv->direction))->Leave(); } } @@ -275,11 +275,17 @@ bool RoadStop::Enter(RoadVehicle *rv) /** * Leave the road stop - * @param rv the vehicle that leaves the stop */ -void RoadStop::Entry::Leave(const RoadVehicle *rv) +void RoadStop::Entry::Leave() { - this->occupied -= rv->gcache.cached_total_length; + this->vehicles -= 1; + + /* Only re-set occupied when the stop is fully clear of RVs. + * occupied should match the last-entered vehicle so how many free spaces + * at the entry to the stop can be calculated by pathfinders. */ + if (this->vehicles == 0) this->occupied = 0; + + assert(this->vehicles >= 0); assert(this->occupied >= 0); } @@ -292,7 +298,9 @@ void RoadStop::Entry::Enter(const RoadVehicle *rv) /* we cannot assert on this->occupied < this->length because of the * remote possibility that RVs are running through each other when * trying to prevention an infinite jam. */ + this->vehicles += 1; this->occupied += rv->gcache.cached_total_length; + assert(this->vehicles >= 0); } /** @@ -367,8 +375,10 @@ void RoadStop::Entry::Rebuild(const RoadStop *rs, int side) } this->occupied = 0; + this->vehicles = 0; for (const auto &it : rserh.vehicles) { this->occupied += it->gcache.cached_total_length; + this->vehicles += 1; } } @@ -386,5 +396,5 @@ void RoadStop::Entry::CheckIntegrity(const RoadStop *rs) const Entry temp; temp.Rebuild(rs, rs->east == this); - if (temp.length != this->length || temp.occupied != this->occupied) NOT_REACHED(); + if (temp.length != this->length || temp.occupied != this->occupied || temp.vehicles != this->vehicles) NOT_REACHED(); } diff --git a/src/roadstop_base.h b/src/roadstop_base.h index 768b54282d..c46d7356b5 100644 --- a/src/roadstop_base.h +++ b/src/roadstop_base.h @@ -33,12 +33,13 @@ struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> { private: int length; ///< The length of the stop in tile 'units' int occupied; ///< The amount of occupied stop in tile 'units' + int vehicles; ///< The number of vehicles in the stop public: friend struct RoadStop; ///< Oh yeah, the road stop may play with me. /** Create an entry */ - Entry() : length(0), occupied(0) {} + Entry() : length(0), occupied(0), vehicles(0) {} /** * Get the length of this drive through stop. @@ -58,7 +59,7 @@ struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> { return this->occupied; } - void Leave(const RoadVehicle *rv); + void Leave(); void Enter(const RoadVehicle *rv); void CheckIntegrity(const RoadStop *rs) const; void Rebuild(const RoadStop *rs, int side = -1);