Loading

Paste #pbftxsvuw

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

Comments