| 3945 | |
| 3946 | |
| 3947 | static bool TrainLocoHandler(Train *v, bool mode) |
| 3948 | { |
| 3949 | /* train has crashed? */ |
| 3950 | if (v->vehstatus.Test(VehState::Crashed)) { |
| 3951 | return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here |
| 3952 | } |
| 3953 | |
| 3954 | if (v->force_proceed != TFP_NONE) { |
| 3955 | v->flags.Reset(VehicleRailFlag::Stuck); |
| 3956 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
| 3957 | } |
| 3958 | |
| 3959 | /* train is broken down? */ |
| 3960 | if (v->HandleBreakdown()) return true; |
| 3961 | |
| 3962 | if (v->flags.Test(VehicleRailFlag::Reversing) && v->cur_speed == 0) { |
| 3963 | ReverseTrainDirection(v); |
| 3964 | } |
| 3965 | |
| 3966 | /* exit if train is stopped */ |
| 3967 | if (v->vehstatus.Test(VehState::Stopped) && v->cur_speed == 0) return true; |
| 3968 | |
| 3969 | bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL; |
| 3970 | if (ProcessOrders(v) && CheckReverseTrain(v)) { |
| 3971 | v->wait_counter = 0; |
| 3972 | v->cur_speed = 0; |
| 3973 | v->subspeed = 0; |
| 3974 | v->flags.Reset(VehicleRailFlag::LeavingStation); |
| 3975 | ReverseTrainDirection(v); |
| 3976 | return true; |
| 3977 | } else if (v->flags.Test(VehicleRailFlag::LeavingStation)) { |
| 3978 | /* Try to reserve a path when leaving the station as we |
| 3979 | * might not be marked as wanting a reservation, e.g. |
| 3980 | * when an overlength train gets turned around in a station. */ |
| 3981 | DiagDirection dir = VehicleExitDir(v->direction, v->track); |
| 3982 | if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR; |
| 3983 | |
| 3984 | if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) { |
| 3985 | TryPathReserve(v, true, true); |
| 3986 | } |
| 3987 | v->flags.Reset(VehicleRailFlag::LeavingStation); |
| 3988 | } |
| 3989 | |
| 3990 | v->HandleLoading(mode); |
| 3991 | |
| 3992 | if (v->current_order.IsType(OT_LOADING)) return true; |
| 3993 | |
| 3994 | if (CheckTrainStayInDepot(v)) return true; |
| 3995 | |
| 3996 | if (!mode) v->ShowVisualEffect(); |
| 3997 | |
| 3998 | /* We had no order but have an order now, do look ahead. */ |
| 3999 | if (!valid_order && !v->current_order.IsType(OT_NOTHING)) { |
| 4000 | CheckNextTrainTile(v); |
| 4001 | } |
| 4002 | |
| 4003 | /* Handle stuck trains. */ |
| 4004 | if (!mode && v->flags.Test(VehicleRailFlag::Stuck)) { |
no test coverage detected