Advertisement
Guest User

Untitled

a guest
Jan 10th, 2020
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.20 KB | None | 0 0
  1. static bool CanMoveGoodsToStation(const Station *st, CargoID type) {
  2.     if (st->owner != OWNER_NONE && st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) return false;
  3.  
  4.     if (st->goods[type].rating == 0) return false; // Lowest possible rating, better not to give cargo anymore
  5.  
  6.     if (_settings_game.order.selectgoods && !st->goods[type].HasVehicleEverTriedLoading()) return false; // Selectively servicing stations, and not this one
  7.  
  8.     if (IsCargoInClass(type, CC_PASSENGERS)) {
  9.         if (st->facilities == FACIL_TRUCK_STOP) return false; // passengers are never served by just a truck stop
  10.     } else {
  11.         if (st->facilities == FACIL_BUS_STOP) return false; // non-passengers are never served by just a bus stop
  12.     }
  13.     return true;
  14. }
  15.  
  16. /** The type of cargo to be compared. */
  17. static CargoID _cargo_type_comparator;
  18.  
  19. static bool CompareCargoRatings(const Station *a, const Station *b)
  20. {
  21.     return b->goods[_cargo_type_comparator].rating < a->goods[_cargo_type_comparator].rating;
  22. }
  23.  
  24. uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
  25. {
  26.     /* Return if nothing to do. Also the rounding below fails for 0. */
  27.     if (amount == 0) return 0;
  28.  
  29.     uint company_best[MAX_COMPANIES + 1] = {};  // best rating for each company, including OWNER_NONE
  30.     uint company_sum[MAX_COMPANIES + 1] = {};   // sum of ratings for each company
  31.     uint best_rating = 0;
  32.     uint best_sum = 0;  // sum of best ratings for each company
  33.  
  34.     typedef std::vector<Station *> UsedStations;
  35.     UsedStations used_stations;
  36.  
  37.     for (Station *st : *all_stations) {
  38.         if (!CanMoveGoodsToStation(st, type)) continue;
  39.  
  40.         used_stations.emplace_back(st);
  41.         uint st_owner = st->owner;
  42.         if (st_owner == OWNER_NONE) st_owner = MAX_COMPANIES; // OWNER_NONE is remapped
  43.  
  44.         byte r = st->goods[type].rating;
  45.         if (r > company_best[st_owner]) {
  46.             best_sum += r - company_best[st_owner];  // it's usually faster than iterating companies later
  47.             company_best[st_owner] = r;
  48.             if (r > best_rating) {
  49.                 best_rating = r;
  50.             }
  51.         }
  52.         company_sum[st_owner] += r;
  53.     }
  54.  
  55.     /* no stations around at all? */
  56.     if (best_rating == 0) return 0;
  57.  
  58.     /* From now we'll calculate with fractal cargo amounts.
  59.      * First determine how much cargo we really have. */
  60.     amount *= best_rating + 1;
  61.  
  62.     typedef std::map<int, int> StationCargoMoved;
  63.     StationCargoMoved st_moved;
  64.  
  65.     uint moved_sum = 0;
  66.     for (Station *st : used_stations) {
  67.         uint st_owner = st->owner;
  68.         if (st_owner == OWNER_NONE) st_owner = MAX_COMPANIES;
  69.         uint station_amount = amount * company_best[st_owner] * st->goods[type].rating / best_sum / company_sum[st_owner];
  70.         moved_sum += station_amount;
  71.         st_moved.emplace(st->index, station_amount);
  72.     }
  73.  
  74.     int remainder = amount - moved_sum;
  75.     if (remainder > 0) {
  76.         std::sort(used_stations.begin(), used_stations.end(), CompareCargoRatings);
  77.         while (remainder > 0) {
  78.             for (Station *st : used_stations) {
  79.                 if (remainder > 0) {
  80.                     st_moved[st->index]++;
  81.                     remainder--;
  82.                 } else {
  83.                     break;
  84.                 }
  85.             }
  86.         }
  87.     }
  88.  
  89.     uint moving = 0;
  90.     for (Station *st : used_stations) {
  91.         moving += UpdateStationWaiting(st, type, st_moved[st->index], source_type, source_id);
  92.     }
  93.  
  94.     return moving;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement