* Prepare everything to begin the loading when arriving at a station. * @pre IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP. */
| 2181 | * @pre IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP. |
| 2182 | */ |
| 2183 | void Vehicle::BeginLoading() |
| 2184 | { |
| 2185 | assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP); |
| 2186 | |
| 2187 | TimerGameTick::Ticks travel_time = TimerGameTick::counter - this->last_loading_tick; |
| 2188 | if (this->current_order.IsType(OT_GOTO_STATION) && |
| 2189 | this->current_order.GetDestination() == this->last_station_visited) { |
| 2190 | this->DeleteUnreachedImplicitOrders(); |
| 2191 | |
| 2192 | /* Now both order indices point to the destination station, and we can start loading */ |
| 2193 | this->current_order.MakeLoading(true); |
| 2194 | UpdateVehicleTimetable(this, true); |
| 2195 | |
| 2196 | /* Furthermore add the Non Stop flag to mark that this station |
| 2197 | * is the actual destination of the vehicle, which is (for example) |
| 2198 | * necessary to be known for HandleTrainLoading to determine |
| 2199 | * whether the train is lost or not; not marking a train lost |
| 2200 | * that arrives at random stations is bad. */ |
| 2201 | this->current_order.SetNonStopType({OrderNonStopFlag::NoIntermediate, OrderNonStopFlag::NoDestination}); |
| 2202 | |
| 2203 | } else { |
| 2204 | /* We weren't scheduled to stop here. Insert an implicit order |
| 2205 | * to show that we are stopping here. |
| 2206 | * While only groundvehicles have implicit orders, e.g. aircraft might still enter |
| 2207 | * the 'wrong' terminal when skipping orders etc. */ |
| 2208 | Order *in_list = this->GetOrder(this->cur_implicit_order_index); |
| 2209 | if (this->IsGroundVehicle() && |
| 2210 | (in_list == nullptr || !in_list->IsType(OT_IMPLICIT) || |
| 2211 | in_list->GetDestination() != this->last_station_visited)) { |
| 2212 | bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS); |
| 2213 | /* Do not create consecutive duplicates of implicit orders */ |
| 2214 | const Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr); |
| 2215 | if (prev_order == nullptr || |
| 2216 | (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) || |
| 2217 | prev_order->GetDestination() != this->last_station_visited) { |
| 2218 | |
| 2219 | /* Prefer deleting implicit orders instead of inserting new ones, |
| 2220 | * so test whether the right order follows later. In case of only |
| 2221 | * implicit orders treat the last order in the list like an |
| 2222 | * explicit one, except if the overall number of orders surpasses |
| 2223 | * IMPLICIT_ORDER_ONLY_CAP. */ |
| 2224 | int target_index = this->cur_implicit_order_index; |
| 2225 | bool found = false; |
| 2226 | while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) { |
| 2227 | const Order *order = this->GetOrder(target_index); |
| 2228 | if (order == nullptr) break; // No orders. |
| 2229 | if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) { |
| 2230 | found = true; |
| 2231 | break; |
| 2232 | } |
| 2233 | target_index++; |
| 2234 | if (target_index >= this->orders->GetNumOrders()) { |
| 2235 | if (this->GetNumManualOrders() == 0 && |
| 2236 | this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) { |
| 2237 | break; |
| 2238 | } |
| 2239 | target_index = 0; |
| 2240 | } |
no test coverage detected