Loading

Paste #pempnuqzd

  1. uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
  2. {
  3.     /* Return if nothing to do. Also the rounding below fails for 0. */
  4.     if (amount == 0) return 0;
  5.     Station *st1 = NULL;   // Station with best rating
  6.     Station *st2 = NULL;   // Second best station
  7.     Station *st3 = NULL;   // Third best station
  8.     Station *st4 = NULL;   // Fourth best station
  9.     Station *st5 = NULL;   // Fifth best station
  10.     Station *st6 = NULL;   // Sixth best station
  11.     uint best_rating1 = 0; // rating of st1
  12.     uint best_rating2 = 0; // rating of st2
  13.     uint best_rating3 = 0; // rating of st3
  14.     uint best_rating4 = 0; // rating of st4
  15.     uint best_rating5 = 0; // rating of st5
  16.     uint best_rating6 = 0; // rating of st6
  17.  
  18.     for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) {
  19.         Station *st = *st_iter;
  20.  
  21.         /* Is the station reserved exclusively for somebody else? */
  22.         if (st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) continue;
  23.  
  24.         if (st->goods[type].rating == 0) continue; // Lowest possible rating, better not to give cargo anymore
  25.  
  26.         if (_settings_game.order.selectgoods && !st->goods[type].HasVehicleEverTriedLoading()) continue; // Selectively servicing stations, and not this one
  27.  
  28.         if (IsCargoInClass(type, CC_PASSENGERS)) {
  29.             if (st->facilities == FACIL_TRUCK_STOP) continue; // passengers are never served by just a truck stop
  30.         } else {
  31.             if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop
  32.         }
  33.  
  34.         /* This station can be used, add it to st1/st2/st3/st4/st5/st6 */
  35.         if (st1 == NULL || st->goods[type].rating >= best_rating1) {
  36.             st6 = st5; best_rating6 = best_rating5;
  37.             st5 = st4; best_rating5 = best_rating4;
  38.             st4 = st3; best_rating4 = best_rating3;
  39.             st3 = st2; best_rating3 = best_rating2;
  40.             st2 = st1; best_rating2 = best_rating1;
  41.             st1 = st; best_rating1 = st->goods[type].rating;
  42.         } else if (st2 == NULL || st->goods[type].rating >= best_rating2) {
  43.             st6 = st5; best_rating6 = best_rating5;
  44.             st5 = st4; best_rating5 = best_rating4;
  45.             st4 = st3; best_rating4 = best_rating3;
  46.             st3 = st2; best_rating3 = best_rating2;
  47.             st2 = st; best_rating2 = st->goods[type].rating;
  48.         } else if (st3 == NULL || st->goods[type].rating >= best_rating3) {
  49.             st6 = st5; best_rating6 = best_rating5;
  50.             st5 = st4; best_rating5 = best_rating4;
  51.             st4 = st3; best_rating4 = best_rating3;
  52.             st3 = st; best_rating3 = st->goods[type].rating;
  53.         } else if (st4 == NULL || st->goods[type].rating >= best_rating4) {
  54.             st6 = st5; best_rating6 = best_rating5;
  55.             st5 = st4; best_rating5 = best_rating4;
  56.             st4 = st; best_rating4 = st->goods[type].rating;
  57.         } else if (st5 == NULL || st->goods[type].rating >= best_rating5) {
  58.             st6 = st5; best_rating6 = best_rating5;
  59.             st5 = st; best_rating5 = st->goods[type].rating;
  60.         } else if (st6 == NULL || st->goods[type].rating >= best_rating6) {
  61.             st6 = st; best_rating6 = st->goods[type].rating;
  62.         }
  63.     }
  64.  
  65.     /* no stations around at all? */
  66.     if (st1 == NULL) return 0;
  67.  
  68.     /* From now we'll calculate with fractal cargo amounts.
  69.      * First determine how much cargo we really have. */
  70.     amount *= best_rating1 + 1;
  71.  
  72.     if (st2 == NULL) {
  73.         /* only one station around */
  74.         return UpdateStationWaiting(st1, type, amount, source_type, source_id);
  75.     }
  76.  
  77.     if (st3 == NULL) {
  78.         /* two stations around, the best two (highest rating) are in st1 and st2 */
  79.         assert(st1 != NULL);
  80.         assert(st2 != NULL);
  81.         assert(best_rating1 != 0 || best_rating2 != 0);
  82.  
  83.         /* Then determine the amount the worst station gets. We do it this way as the
  84.          * best should get a bonus, which in this case is the rounding difference from
  85.          * this calculation. In reality that will mean the bonus will be pretty low.
  86.          * Nevertheless, the best station should always get the most cargo regardless
  87.          * of rounding issues. */
  88.         uint cargo_st2 = amount * best_rating2 / (best_rating1 + best_rating2);
  89.         assert(cargo_st2 <= (amount - cargo_st2));
  90.        
  91.         uint cargo_st1 = amount - cargo_st2;
  92.         assert(amount = cargo_st1 + cargo_st2);
  93.  
  94.         /* And then send the cargo to the stations! */
  95.         uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id);
  96.         /* These two UpdateStationWaiting's can't be in the statement as then the order
  97.          * of execution would be undefined and that could cause desyncs with callbacks. */
  98.         return moved + UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id);
  99.     }
  100.  
  101.     if (st4 == NULL) {
  102.         /* three stations around, the best three (highest rating) are in st1, st2 and st3 */
  103.         assert(st1 != NULL);
  104.         assert(st2 != NULL);
  105.         assert(st3 != NULL);
  106.         assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0);
  107.  
  108.         /* Then determine the amount the worst stations get. We do it this way as the
  109.          * best should get a bonus, which in this case is the rounding difference from
  110.          * this calculation. In reality that will mean the bonus will be pretty low.
  111.          * Nevertheless, the best station should always get the most cargo regardless
  112.          * of rounding issues. */
  113.         uint cargo_st3 = amount * best_rating3 / (best_rating1 + best_rating2 + best_rating3);
  114.         assert(cargo_st3 <= (amount - cargo_st3));
  115.  
  116.         uint remaining = amount - cargo_st3;
  117.         uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2);
  118.         assert(cargo_st2 <= (remaining - cargo_st2));
  119.  
  120.         uint cargo_st1 = remaining - cargo_st2;
  121.         assert(amount == cargo_st1 + cargo_st2 + cargo_st3);
  122.  
  123.         /* And then send the cargo to the stations! */
  124.         uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id);
  125.         moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id);
  126.         return moved + UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id);
  127.     }
  128.  
  129.     if (st5 == NULL) {
  130.         /* Four stations around, the best four (highest rating) are in st1, st2, st3 and st4 */
  131.         assert(st1 != NULL);
  132.         assert(st2 != NULL);
  133.         assert(st3 != NULL);
  134.         assert(st4 != NULL);
  135.         assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0);
  136.  
  137.         /* Then determine the amount the worst stations get. We do it this way as the
  138.          * best should get a bonus, which in this case is the rounding difference from
  139.          * this calculation. In reality that will mean the bonus will be pretty low.
  140.          * Nevertheless, the best station should always get the most cargo regardless
  141.          * of rounding issues. */
  142.         uint cargo_st4 = amount * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4);
  143.         assert(cargo_st4 <= (amount - cargo_st4));
  144.  
  145.         uint remaining = amount - cargo_st4;
  146.         uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3);
  147.         assert(cargo_st3 <= (remaining - cargo_st3));
  148.  
  149.         remaining -= cargo_st3;
  150.         uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2);
  151.         assert(cargo_st2 <= (remaining - cargo_st2));
  152.  
  153.         uint cargo_st1 = remaining - cargo_st2;
  154.         assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4);
  155.  
  156.         /* And then send the cargo to the stations! */
  157.         uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id);
  158.         moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id);
  159.         moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id);
  160.         return moved + UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id);
  161.     }
  162.  
  163.     if (st6 == NULL) {
  164.         /* Five stations around, the best five (highest rating) are in st1, st2, st3, st4 and st5 */
  165.         assert(st1 != NULL);
  166.         assert(st2 != NULL);
  167.         assert(st3 != NULL);
  168.         assert(st4 != NULL);
  169.         assert(st5 != NULL);
  170.         assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0 || best_rating5 != 0);
  171.  
  172.         /* Then determine the amount the worst stations get. We do it this way as the
  173.          * best should get a bonus, which in this case is the rounding difference from
  174.          * this calculation. In reality that will mean the bonus will be pretty low.
  175.          * Nevertheless, the best station should always get the most cargo regardless
  176.          * of rounding issues. */
  177.         uint cargo_st5 = amount * best_rating5 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5);
  178.         assert(cargo_st5 <= (amount - cargo_st5));
  179.  
  180.         uint remaining = amount - cargo_st5;
  181.         uint cargo_st4 = remaining * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4);
  182.         assert(cargo_st4 <= (remaining - cargo_st4));
  183.  
  184.         remaining -= cargo_st4;
  185.         uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3);
  186.         assert(cargo_st3 <= (remaining - cargo_st3));
  187.  
  188.         remaining -= cargo_st3;
  189.         uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2);
  190.         assert(cargo_st2 <= (remaining - cargo_st2));
  191.  
  192.         uint cargo_st1 = remaining - cargo_st2;
  193.         assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4 + cargo_st5);
  194.  
  195.         /* And then send the cargo to the stations! */
  196.         uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id);
  197.         moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id);
  198.         moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id);
  199.         moved += UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id);
  200.         return moved + UpdateStationWaiting(st5, type, cargo_st5, source_type, source_id);
  201.     }
  202.  
  203.     /* Six stations around, the best six (highest rating) are in st1, st2, st3, st4, st5 and st6 */
  204.     assert(st1 != NULL);
  205.     assert(st2 != NULL);
  206.     assert(st3 != NULL);
  207.     assert(st4 != NULL);
  208.     assert(st5 != NULL);
  209.     assert(st6 != NULL);
  210.     assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0 || best_rating5 != 0 || best_rating6 != 0);
  211.  
  212.     /* Then determine the amount the worst stations get. We do it this way as the
  213.      * best should get a bonus, which in this case is the rounding difference from
  214.      * this calculation. In reality that will mean the bonus will be pretty low.
  215.      * Nevertheless, the best station should always get the most cargo regardless
  216.      * of rounding issues. */
  217.     uint cargo_st6 = amount * best_rating6 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5 + best_rating6);
  218.     assert(cargo_st6 <= (amount - cargo_st6));
  219.  
  220.     uint remaining = amount - cargo_st6;
  221.     uint cargo_st5 = remaining * best_rating5 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5);
  222.     assert(cargo_st5 <= (remaining - cargo_st5));
  223.  
  224.     remaining -= cargo_st5;
  225.     uint cargo_st4 = remaining * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4);
  226.     assert(cargo_st4 <= (remaining - cargo_st4));
  227.  
  228.     remaining -= cargo_st4;
  229.     uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3);
  230.     assert(cargo_st3 <= (remaining - cargo_st3));
  231.  
  232.     remaining -= cargo_st3;
  233.     uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2);
  234.     assert(cargo_st2 <= (remaining - cargo_st2));
  235.  
  236.     uint cargo_st1 = remaining - cargo_st2;
  237.     assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4 + cargo_st5 + cargo_st6);
  238.  
  239.     /* And then send the cargo to the stations! */
  240.     uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id);
  241.     moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id);
  242.     moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id);
  243.     moved += UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id);
  244.     moved += UpdateStationWaiting(st5, type, cargo_st5, source_type, source_id);
  245.     return moved + UpdateStationWaiting(st6, type, cargo_st6, source_type, source_id);
  246. }

Version history

Revision # Author Created at
pnufelyg1 Anonymous 25 Oct 2017, 22:27:51 UTC Diff
p2pn4keww Anonymous 25 Oct 2017, 12:36:08 UTC Diff
pfsmdufv4 Anonymous 24 Oct 2017, 18:35:28 UTC Diff

Comments