92 STR_SORT_BY_RATING_MAX, |
92 STR_SORT_BY_RATING_MAX, |
93 INVALID_STRING_ID |
93 INVALID_STRING_ID |
94 }; |
94 }; |
95 |
95 |
96 static char _bufcache[64]; |
96 static char _bufcache[64]; |
97 static const Station* _last_station; |
97 static const Station *_last_station; |
98 static int _internal_sort_order; |
98 static int _internal_sort_order; |
99 |
99 |
100 static int CDECL StationNameSorter(const void *a, const void *b) |
100 static int CDECL StationNameSorter(const void *a, const void *b) |
101 { |
101 { |
102 const Station* st1 = *(const Station**)a; |
102 const Station *st1 = *(const Station**)a; |
103 const Station* st2 = *(const Station**)b; |
103 const Station *st2 = *(const Station**)b; |
104 char buf1[64]; |
104 char buf1[64]; |
105 int r; |
|
106 |
105 |
107 SetDParam(0, st1->index); |
106 SetDParam(0, st1->index); |
108 GetString(buf1, STR_STATION, lastof(buf1)); |
107 GetString(buf1, STR_STATION, lastof(buf1)); |
109 |
108 |
110 if (st2 != _last_station) { |
109 if (st2 != _last_station) { |
111 _last_station = st2; |
110 _last_station = st2; |
112 SetDParam(0, st2->index); |
111 SetDParam(0, st2->index); |
113 GetString(_bufcache, STR_STATION, lastof(_bufcache)); |
112 GetString(_bufcache, STR_STATION, lastof(_bufcache)); |
114 } |
113 } |
115 |
114 |
116 r = strcmp(buf1, _bufcache); // sort by name |
115 int r = strcmp(buf1, _bufcache); // sort by name |
117 return (_internal_sort_order & 1) ? -r : r; |
116 return (_internal_sort_order & 1) ? -r : r; |
118 } |
117 } |
119 |
118 |
120 static int CDECL StationTypeSorter(const void *a, const void *b) |
119 static int CDECL StationTypeSorter(const void *a, const void *b) |
121 { |
120 { |
122 const Station* st1 = *(const Station**)a; |
121 const Station *st1 = *(const Station**)a; |
123 const Station* st2 = *(const Station**)b; |
122 const Station *st2 = *(const Station**)b; |
124 return (_internal_sort_order & 1) ? st2->facilities - st1->facilities : st1->facilities - st2->facilities; |
123 return (_internal_sort_order & 1) ? st2->facilities - st1->facilities : st1->facilities - st2->facilities; |
125 } |
124 } |
126 |
125 |
127 static const uint32 _cargo_filter_max = ~0; |
126 static const uint32 _cargo_filter_max = UINT32_MAX; |
128 static uint32 _cargo_filter = _cargo_filter_max; |
127 static uint32 _cargo_filter = _cargo_filter_max; |
129 |
128 |
130 static int CDECL StationWaitingSorter(const void *a, const void *b) |
129 static int CDECL StationWaitingSorter(const void *a, const void *b) |
131 { |
130 { |
132 const Station* st1 = *(const Station**)a; |
131 const Station *st1 = *(const Station**)a; |
133 const Station* st2 = *(const Station**)b; |
132 const Station *st2 = *(const Station**)b; |
134 Money sum1 = 0, sum2 = 0; |
133 Money sum1 = 0, sum2 = 0; |
135 |
134 |
136 for (CargoID j = 0; j < NUM_CARGO; j++) { |
135 for (CargoID j = 0; j < NUM_CARGO; j++) { |
137 if (!HasBit(_cargo_filter, j)) continue; |
136 if (!HasBit(_cargo_filter, j)) continue; |
138 if (!st1->goods[j].cargo.Empty()) sum1 += GetTransportedGoodsIncome(st1->goods[j].cargo.Count(), 20, 50, j); |
137 if (!st1->goods[j].cargo.Empty()) sum1 += GetTransportedGoodsIncome(st1->goods[j].cargo.Count(), 20, 50, j); |
150 * @retval >0 a should come before b in the list |
149 * @retval >0 a should come before b in the list |
151 * @retval <0 b should come before a in the list |
150 * @retval <0 b should come before a in the list |
152 */ |
151 */ |
153 static int CDECL StationRatingMaxSorter(const void *a, const void *b) |
152 static int CDECL StationRatingMaxSorter(const void *a, const void *b) |
154 { |
153 { |
155 const Station* st1 = *(const Station**)a; |
154 const Station *st1 = *(const Station**)a; |
156 const Station* st2 = *(const Station**)b; |
155 const Station *st2 = *(const Station**)b; |
157 byte maxr1 = 0; |
156 byte maxr1 = 0; |
158 byte maxr2 = 0; |
157 byte maxr2 = 0; |
159 |
158 |
160 for (CargoID j = 0; j < NUM_CARGO; j++) { |
159 for (CargoID j = 0; j < NUM_CARGO; j++) { |
161 if (HasBit(st1->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr1 = max(maxr1, st1->goods[j].rating); |
160 if (HasBit(st1->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr1 = max(maxr1, st1->goods[j].rating); |
174 |
173 |
175 DECLARE_ENUM_AS_BIT_SET(StationListFlags); |
174 DECLARE_ENUM_AS_BIT_SET(StationListFlags); |
176 |
175 |
177 /** Information about station list */ |
176 /** Information about station list */ |
178 struct plstations_d { |
177 struct plstations_d { |
179 const Station** sort_list; ///< Pointer to list of stations |
178 const Station **sort_list; ///< Pointer to list of stations |
180 uint16 list_length; ///< Number of stations in list |
179 uint16 list_length; ///< Number of stations in list |
181 uint16 resort_timer; ///< Tick counter to resort the list |
180 uint16 resort_timer; ///< Tick counter to resort the list |
182 byte sort_type; ///< Sort type - name, waiting, ... |
181 byte sort_type; ///< Sort type - name, waiting, ... |
183 byte flags; ///< Flags - SL_ORDER, SL_RESORT, SL_REBUILD |
182 byte flags; ///< Flags - SL_ORDER, SL_RESORT, SL_REBUILD |
184 }; |
183 }; |
223 * @param owner player whose stations are to be in list |
222 * @param owner player whose stations are to be in list |
224 * @param facilities types of stations of interest |
223 * @param facilities types of stations of interest |
225 * @param cargo_filter bitmap of cargo types to include |
224 * @param cargo_filter bitmap of cargo types to include |
226 * @param include_empty whether we should include stations without waiting cargo |
225 * @param include_empty whether we should include stations without waiting cargo |
227 */ |
226 */ |
228 static void BuildStationsList(plstations_d* sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty) |
227 static void BuildStationsList(plstations_d *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty) |
229 { |
228 { |
230 uint n = 0; |
229 uint n = 0; |
231 const Station *st; |
230 const Station *st; |
232 |
231 |
233 if (!(sl->flags & SL_REBUILD)) return; |
232 if (!(sl->flags & SL_REBUILD)) return; |
234 |
233 |
235 /* Create array for sorting */ |
234 /* Create array for sorting */ |
236 const Station** station_sort = MallocT<const Station*>(GetMaxStationIndex() + 1); |
235 const Station **station_sort = MallocT<const Station*>(GetMaxStationIndex() + 1); |
237 |
236 |
238 DEBUG(misc, 3, "Building station list for player %d", owner); |
237 DEBUG(misc, 3, "Building station list for player %d", owner); |
239 |
238 |
240 FOR_ALL_STATIONS(st) { |
239 FOR_ALL_STATIONS(st) { |
241 if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) { |
240 if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) { |
747 * @param w pointer to window |
746 * @param w pointer to window |
748 */ |
747 */ |
749 static void DrawStationViewWindow(Window *w) |
748 static void DrawStationViewWindow(Window *w) |
750 { |
749 { |
751 StationID station_id = w->window_number; |
750 StationID station_id = w->window_number; |
752 const Station* st = GetStation(station_id); |
751 const Station *st = GetStation(station_id); |
753 int x, y; ///< coordinates used for printing waiting/accepted/rating of cargo |
|
754 int pos; ///< = w->vscroll.pos |
|
755 StringID str; |
|
756 CargoDataList cargolist; |
752 CargoDataList cargolist; |
757 uint32 transfers = 0; |
753 uint32 transfers = 0; |
758 |
754 |
759 /* count types of cargos waiting in station */ |
755 /* count types of cargos waiting in station */ |
760 for (CargoID i = 0; i < NUM_CARGO; i++) { |
756 for (CargoID i = 0; i < NUM_CARGO; i++) { |
806 |
802 |
807 SetDParam(0, st->index); |
803 SetDParam(0, st->index); |
808 SetDParam(1, st->facilities); |
804 SetDParam(1, st->facilities); |
809 DrawWindowWidgets(w); |
805 DrawWindowWidgets(w); |
810 |
806 |
811 x = 2; |
807 int x = 2; ///< coordinates used for printing waiting/accepted/rating of cargo |
812 y = 15; |
808 int y = 15; |
813 pos = w->vscroll.pos; |
809 int pos = w->vscroll.pos; ///< = w->vscroll.pos |
814 |
810 |
815 uint width = w->widget[SVW_WAITING].right - w->widget[SVW_WAITING].left - 4; |
811 uint width = w->widget[SVW_WAITING].right - w->widget[SVW_WAITING].left - 4; |
816 int maxrows = w->vscroll.cap; |
812 int maxrows = w->vscroll.cap; |
|
813 |
|
814 StringID str; |
817 |
815 |
818 if (--pos < 0) { |
816 if (--pos < 0) { |
819 str = STR_00D0_NOTHING; |
817 str = STR_00D0_NOTHING; |
820 for (CargoID i = 0; i < NUM_CARGO; i++) { |
818 for (CargoID i = 0; i < NUM_CARGO; i++) { |
821 if (!st->goods[i].cargo.Empty()) str = STR_EMPTY; |
819 if (!st->goods[i].cargo.Empty()) str = STR_EMPTY; |