* Periodic update of a station's rating. * @param st The station to update. */
| 3971 | * @param st The station to update. |
| 3972 | */ |
| 3973 | static void UpdateStationRating(Station *st) |
| 3974 | { |
| 3975 | bool waiting_changed = false; |
| 3976 | |
| 3977 | byte_inc_sat(&st->time_since_load); |
| 3978 | byte_inc_sat(&st->time_since_unload); |
| 3979 | |
| 3980 | for (const CargoSpec *cs : CargoSpec::Iterate()) { |
| 3981 | GoodsEntry *ge = &st->goods[cs->Index()]; |
| 3982 | |
| 3983 | /* The station might not currently be moving this cargo. */ |
| 3984 | if (!ge->HasRating()) { |
| 3985 | /* Slowly increase the rating back to its original level in the case we |
| 3986 | * didn't deliver cargo yet to this station. This happens when a bribe |
| 3987 | * failed while you didn't moved that cargo yet to a station. */ |
| 3988 | if (ge->rating < INITIAL_STATION_RATING) ge->rating++; |
| 3989 | |
| 3990 | /* Nothing else to do with this cargo. */ |
| 3991 | continue; |
| 3992 | } |
| 3993 | |
| 3994 | byte_inc_sat(&ge->time_since_pickup); |
| 3995 | |
| 3996 | /* If this cargo hasn't been picked up in a long time, get rid of it. */ |
| 3997 | if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) { |
| 3998 | ge->status.Reset(GoodsEntry::State::Rating); |
| 3999 | ge->last_speed = 0; |
| 4000 | TruncateCargo(cs, ge); |
| 4001 | waiting_changed = true; |
| 4002 | continue; |
| 4003 | } |
| 4004 | |
| 4005 | bool skip = false; |
| 4006 | int rating = 0; |
| 4007 | uint waiting = ge->AvailableCount(); |
| 4008 | |
| 4009 | /* num_dests is at least 1 if there is any cargo as |
| 4010 | * StationID::Invalid() is also a destination. |
| 4011 | */ |
| 4012 | uint num_dests = ge->HasData() ? static_cast<uint>(ge->GetData().cargo.Packets()->MapSize()) : 0; |
| 4013 | |
| 4014 | /* Average amount of cargo per next hop, but prefer solitary stations |
| 4015 | * with only one or two next hops. They are allowed to have more |
| 4016 | * cargo waiting per next hop. |
| 4017 | * With manual cargo distribution waiting_avg = waiting / 2 as then |
| 4018 | * StationID::Invalid() is the only destination. |
| 4019 | */ |
| 4020 | uint waiting_avg = waiting / (num_dests + 1); |
| 4021 | |
| 4022 | if (_cheats.station_rating.value) { |
| 4023 | ge->rating = rating = MAX_STATION_RATING; |
| 4024 | skip = true; |
| 4025 | } else if (cs->callback_mask.Test(CargoCallbackMask::StationRatingCalc)) { |
| 4026 | /* Perform custom station rating. If it succeeds the speed, days in transit and |
| 4027 | * waiting cargo ratings must not be executed. */ |
| 4028 | |
| 4029 | /* NewGRFs expect last speed to be 0xFF when no vehicle has arrived yet. */ |
| 4030 | uint last_speed = ge->HasVehicleEverTriedLoading() ? ge->last_speed : 0xFF; |
no test coverage detected