Mercurial > hg > openttd
comparison src/station_cmd.cpp @ 7891:202a48f69a30 draft
(svn r11442) -Feature: make news messages related to the industry (production) changes better configurable; you can now disable news messages popping up for industries you are not servicing. Patch by Alberth.
author | rubidium <rubidium@openttd.org> |
---|---|
date | Thu, 15 Nov 2007 22:20:33 +0000 |
parents | dee7f1c1a1e2 |
children | ff1975ced735 |
comparison
equal
deleted
inserted
replaced
7890:b6664cba0c67 | 7891:202a48f69a30 |
---|---|
431 | 431 |
432 SetDParam(0, st->index); | 432 SetDParam(0, st->index); |
433 AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT | NF_TILE, NT_ACCEPTANCE, 0), st->xy, 0); | 433 AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT | NF_TILE, NT_ACCEPTANCE, 0), st->xy, 0); |
434 } | 434 } |
435 | 435 |
436 /** Get a list of the cargo types being produced around the tile.*/ | 436 /** |
437 * Get a list of the cargo types being produced around the tile (in a rectangle). | |
438 * @param produced: Destination array of produced cargo | |
439 * @param tile: Center of the search area | |
440 * @param w: Width of the center | |
441 * @param h: Height of the center | |
442 * @param rad: Radius of the search area | |
443 */ | |
437 void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, | 444 void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, |
438 int w, int h, int rad) | 445 int w, int h, int rad) |
439 { | 446 { |
440 memset(produced, 0, sizeof(AcceptedCargo)); | 447 memset(produced, 0, sizeof(AcceptedCargo)); |
441 | 448 |
475 } | 482 } |
476 } | 483 } |
477 } | 484 } |
478 } | 485 } |
479 | 486 |
480 /** Get a list of the cargo types that are accepted around the tile.*/ | 487 /** |
488 * Get a list of the cargo types that are accepted around the tile. | |
489 * @param accepts: Destination array of accepted cargo | |
490 * @param tile: Center of the search area | |
491 * @param w: Width of the center | |
492 * @param h: Height of the center | |
493 * @param rad: Radius of the rectangular search area | |
494 */ | |
481 void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, | 495 void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, |
482 int w, int h, int rad) | 496 int w, int h, int rad) |
483 { | 497 { |
484 memset(accepts, 0, sizeof(AcceptedCargo)); | 498 memset(accepts, 0, sizeof(AcceptedCargo)); |
485 | 499 |
2624 } | 2638 } |
2625 | 2639 |
2626 return CommandCost(); | 2640 return CommandCost(); |
2627 } | 2641 } |
2628 | 2642 |
2629 | 2643 /** |
2630 uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount) | 2644 * Find all (non-buoy) stations around an industry tile |
2631 { | 2645 * |
2632 Station* around[8]; | 2646 * @param tile: Center tile to search from |
2633 | 2647 * @param w: Width of the center |
2634 for (uint i = 0; i < lengthof(around); i++) around[i] = NULL; | 2648 * @param h: Height of the center |
2635 | 2649 * |
2636 int w_prod; //width and height of the "producer" of the cargo | 2650 * @return: Set of found stations |
2651 */ | |
2652 StationSet FindStationsAroundIndustryTile(TileIndex tile, int w, int h) | |
2653 { | |
2654 StationSet station_set; | |
2655 | |
2656 int w_prod; // width and height of the "producer" of the cargo | |
2637 int h_prod; | 2657 int h_prod; |
2638 int max_rad; | 2658 int max_rad; |
2639 if (_patches.modified_catchment) { | 2659 if (_patches.modified_catchment) { |
2640 w_prod = w; | 2660 w_prod = w; |
2641 h_prod = h; | 2661 h_prod = h; |
2654 cur_tile = TILE_MASK(cur_tile); | 2674 cur_tile = TILE_MASK(cur_tile); |
2655 if (!IsTileType(cur_tile, MP_STATION)) continue; | 2675 if (!IsTileType(cur_tile, MP_STATION)) continue; |
2656 | 2676 |
2657 Station *st = GetStationByTile(cur_tile); | 2677 Station *st = GetStationByTile(cur_tile); |
2658 | 2678 |
2659 for (uint i = 0; i != lengthof(around); i++) { | 2679 if (st->IsBuoy()) continue; // bouys don't accept cargo |
2660 if (around[i] == NULL) { | 2680 |
2661 if (!st->IsBuoy() && | 2681 |
2662 (st->town->exclusive_counter == 0 || st->town->exclusivity == st->owner) && // check exclusive transport rights | 2682 if (_patches.modified_catchment) { |
2663 st->goods[type].rating != 0 && // when you've got the lowest rating you can get, it's better not to give cargo anymore | 2683 /* min and max coordinates of the producer relative */ |
2664 (!_patches.selectgoods || st->goods[type].last_speed != 0) && // we are servicing the station (or cargo is dumped on all stations) | 2684 const int x_min_prod = max_rad + 1; |
2665 ((st->facilities & ~FACIL_BUS_STOP) != 0 || IsCargoInClass(type, CC_PASSENGERS)) && // if we have other fac. than a bus stop, or the cargo is passengers | 2685 const int x_max_prod = max_rad + w_prod; |
2666 ((st->facilities & ~FACIL_TRUCK_STOP) != 0 || !IsCargoInClass(type, CC_PASSENGERS))) { // if we have other fac. than a cargo bay or the cargo is not passengers | 2686 const int y_min_prod = max_rad + 1; |
2667 if (_patches.modified_catchment) { | 2687 const int y_max_prod = max_rad + h_prod; |
2668 /* min and max coordinates of the producer relative */ | 2688 |
2669 const int x_min_prod = max_rad + 1; | 2689 int rad = FindCatchmentRadius(st); |
2670 const int x_max_prod = max_rad + w_prod; | 2690 |
2671 const int y_min_prod = max_rad + 1; | 2691 int x_dist = min(w_cur - x_min_prod, x_max_prod - w_cur); |
2672 const int y_max_prod = max_rad + h_prod; | 2692 if (w_cur < x_min_prod) { |
2673 | 2693 x_dist = x_min_prod - w_cur; |
2674 int rad = FindCatchmentRadius(st); | 2694 } else if (w_cur > x_max_prod) { |
2675 | 2695 x_dist = w_cur - x_max_prod; |
2676 int x_dist = min(w_cur - x_min_prod, x_max_prod - w_cur); | 2696 } |
2677 if (w_cur < x_min_prod) { | 2697 |
2678 x_dist = x_min_prod - w_cur; | 2698 if (x_dist > rad) continue; |
2679 } else if (w_cur > x_max_prod) { | 2699 |
2680 x_dist = w_cur - x_max_prod; | 2700 int y_dist = min(h_cur - y_min_prod, y_max_prod - h_cur); |
2681 } | 2701 if (h_cur < y_min_prod) { |
2682 | 2702 y_dist = y_min_prod - h_cur; |
2683 int y_dist = min(h_cur - y_min_prod, y_max_prod - h_cur); | 2703 } else if (h_cur > y_max_prod) { |
2684 if (h_cur < y_min_prod) { | 2704 y_dist = h_cur - y_max_prod; |
2685 y_dist = y_min_prod - h_cur; | 2705 } |
2686 } else if (h_cur > y_max_prod) { | 2706 |
2687 y_dist = h_cur - y_max_prod; | 2707 if (y_dist > rad) continue; |
2688 } | 2708 } |
2689 | 2709 |
2690 if (x_dist > rad || y_dist > rad) break; | 2710 /* Insert the station in the set. This will fail if it has |
2691 } | 2711 * already been added. |
2692 | 2712 */ |
2693 around[i] = st; | 2713 station_set.insert(st); |
2694 } | 2714 |
2695 break; | |
2696 } else if (around[i] == st) { | |
2697 break; | |
2698 } | |
2699 } | |
2700 END_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad)) | 2715 END_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad)) |
2701 | 2716 |
2717 return station_set; | |
2718 } | |
2719 | |
2720 uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount) | |
2721 { | |
2722 Station *st1 = NULL; // Station with best rating | |
2723 Station *st2 = NULL; // Second best station | |
2724 uint best_rating1 = 0; // rating of st1 | |
2725 uint best_rating2 = 0; // rating of st2 | |
2726 | |
2727 StationSet all_stations = FindStationsAroundIndustryTile(tile, w, h); | |
2728 for (StationSet::iterator st_iter = all_stations.begin(); st_iter != all_stations.end(); ++st_iter) { | |
2729 Station *st = *st_iter; | |
2730 | |
2731 /* Is the station reserved exclusively for somebody else? */ | |
2732 if (st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) continue; | |
2733 | |
2734 if (st->goods[type].rating == 0) continue; // Lowest possible rating, better not to give cargo anymore | |
2735 | |
2736 if (_patches.selectgoods && st->goods[type].last_speed == 0) continue; // Selectively servicing stations, and not this one | |
2737 | |
2738 if (IsCargoInClass(type, CC_PASSENGERS)) { | |
2739 if (st->facilities == FACIL_TRUCK_STOP) continue; // passengers are never served by just a truck stop | |
2740 } else { | |
2741 if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop | |
2742 } | |
2743 | |
2744 /* This station can be used, add it to st1/st2 */ | |
2745 if (st1 == NULL || st->goods[type].rating >= best_rating1) { | |
2746 st2 = st1; best_rating2 = best_rating1; st1 = st; best_rating1 = st->goods[type].rating; | |
2747 } else if (st2 == NULL || st->goods[type].rating >= best_rating2) { | |
2748 st2 = st; best_rating2 = st->goods[type].rating; | |
2749 } | |
2750 } | |
2751 | |
2702 /* no stations around at all? */ | 2752 /* no stations around at all? */ |
2703 if (around[0] == NULL) return 0; | 2753 if (st1 == NULL) return 0; |
2704 | 2754 |
2705 if (around[1] == NULL) { | 2755 if (st2 == NULL) { |
2706 /* only one station around */ | 2756 /* only one station around */ |
2707 uint moved = (amount * around[0]->goods[type].rating >> 8) + 1; | 2757 uint moved = amount * best_rating1 / 256 + 1; |
2708 UpdateStationWaiting(around[0], type, moved); | 2758 UpdateStationWaiting(st1, type, moved); |
2709 return moved; | 2759 return moved; |
2710 } | 2760 } |
2711 | 2761 |
2712 /* several stations around, find the two with the highest rating */ | 2762 /* several stations around, the best two (highest rating) are in st1 and st2 */ |
2713 Station *st1 = NULL; | |
2714 Station *st2 = NULL; | |
2715 uint best_rating = 0; | |
2716 uint best_rating2 = 0; | |
2717 | |
2718 for (uint i = 0; i != lengthof(around) && around[i] != NULL; i++) { | |
2719 if (around[i]->goods[type].rating >= best_rating) { | |
2720 best_rating2 = best_rating; | |
2721 st2 = st1; | |
2722 | |
2723 best_rating = around[i]->goods[type].rating; | |
2724 st1 = around[i]; | |
2725 } else if (around[i]->goods[type].rating >= best_rating2) { | |
2726 best_rating2 = around[i]->goods[type].rating; | |
2727 st2 = around[i]; | |
2728 } | |
2729 } | |
2730 | |
2731 assert(st1 != NULL); | 2763 assert(st1 != NULL); |
2732 assert(st2 != NULL); | 2764 assert(st2 != NULL); |
2733 assert(best_rating != 0 || best_rating2 != 0); | 2765 assert(best_rating1 != 0 || best_rating2 != 0); |
2734 | 2766 |
2735 /* the 2nd highest one gets a penalty */ | 2767 /* the 2nd highest one gets a penalty */ |
2736 best_rating2 >>= 1; | 2768 best_rating2 >>= 1; |
2737 | 2769 |
2738 /* amount given to station 1 */ | 2770 /* amount given to station 1 */ |
2739 uint t = (best_rating * (amount + 1)) / (best_rating + best_rating2); | 2771 uint t = (best_rating1 * (amount + 1)) / (best_rating1 + best_rating2); |
2740 | 2772 |
2741 uint moved = 0; | 2773 uint moved = 0; |
2742 if (t != 0) { | 2774 if (t != 0) { |
2743 moved = t * best_rating / 256 + 1; | 2775 moved = t * best_rating1 / 256 + 1; |
2744 amount -= t; | 2776 amount -= t; |
2745 UpdateStationWaiting(st1, type, moved); | 2777 UpdateStationWaiting(st1, type, moved); |
2746 } | 2778 } |
2747 | 2779 |
2748 if (amount != 0) { | 2780 if (amount != 0) { |