SHARE
TWEET

Untitled

a guest Dec 31st, 2019 19 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** The type of cargo to be compared. */
  2. static CargoID _cargo_type_comparator;
  3.  
  4. static int CDECL CompareCargoRatings(Station * const *a, Station * const *b)
  5. {
  6.     return (*b)->goods[_cargo_type_comparator].rating - (*a)->goods[_cargo_type_comparator].rating;
  7. }
  8.  
  9. uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
  10. {
  11.     /* Return if nothing to do. Also the rounding below fails for 0. */
  12.     if (amount == 0) return 0;
  13.  
  14. //  SmallVector<Station *, 1> used_stations;
  15.     typedef std::vector<Station *> UsedStations;
  16.     UsedStations used_stations;
  17.  
  18.     for (Station *st : *all_stations) {
  19.         /* Is the station reserved exclusively for somebody else? */
  20.         if (st->owner != OWNER_NONE && st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) continue;
  21.  
  22.         if (st->goods[type].rating == 0) continue; // Lowest possible rating, better not to give cargo anymore
  23.  
  24.         if (_settings_game.order.selectgoods && !st->goods[type].HasVehicleEverTriedLoading()) continue; // Selectively servicing stations, and not this one
  25.  
  26.         if (IsCargoInClass(type, CC_PASSENGERS)) {
  27.             if (st->facilities == FACIL_TRUCK_STOP) continue; // passengers are never served by just a truck stop
  28.         } else {
  29.             if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop
  30.         }
  31.  
  32.         /* This station can be used, add it to the list */
  33.         used_stations.emplace_back(st);
  34.     }
  35.  
  36.     const uint num_stations = (uint)used_stations.size(); // total number of stations added
  37.  
  38.     /* no stations around at all? */
  39.     if (num_stations == 0) return 0;
  40.  
  41.     /* Sort the stations by cargo rating in descending order. */
  42.     _cargo_type_comparator = type;
  43.     QSortT<Station *>(used_stations.begin(), used_stations.size(), CompareCargoRatings);
  44.     Station *best_station = *used_stations.begin();
  45.  
  46.     /* From now we'll calculate with fractal cargo amounts.
  47.      * First determine how much cargo we really have. */
  48.     amount *= best_station->goods[type].rating + 1;
  49.  
  50.     /* several stations around */
  51.     uint ratings_square_sum = 0;
  52.     for (Station * const *st_iter = used_stations.begin(); st_iter != used_stations.end(); ++st_iter) {
  53.         Station *st = *st_iter;
  54.  
  55.         ratings_square_sum += st->goods[type].rating * st->goods[type].rating;
  56.     }
  57.  
  58.     uint moved = 0;
  59.     for (Station * const *st_iter = used_stations.end(); st_iter != used_stations.begin(); --st_iter) {
  60.         Station *st = *(st_iter - 1);
  61.  
  62.         if (st != best_station) {
  63.             /* Determine the amount the worst station gets, which is the last one from the list.
  64.              * Then determine the amount the next worst gets by iterating backwards, until the
  65.              * best station remains. We do it this way as the best should get a bonus, which in
  66.              * this case is the rounding difference from the last time this calculation is done.
  67.              * In reality that will mean the bonus will be pretty low. Nevertheless, the best
  68.              * station should always get the most cargo regardless of rounding issues. */
  69.             uint cur_worst = amount * st->goods[type].rating * st->goods[type].rating / ratings_square_sum;
  70.  
  71.             /* And then send the cargo to the stations! */
  72.             moved += UpdateStationWaiting(st, type, cur_worst, source_type, source_id);
  73.  
  74.             amount -= cur_worst;
  75.             ratings_square_sum -= st->goods[type].rating * st->goods[type].rating;
  76.         } else {
  77.             /* These two UpdateStationWaiting's can't be in the statement as then the order
  78.              * of execution would be undefined and that could cause desyncs with callbacks. */
  79.             moved += UpdateStationWaiting(st, type, amount, source_type, source_id);
  80.         }
  81.     }
  82.     return moved;
  83. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top