139 } |
139 } |
140 } |
140 } |
141 return -1; |
141 return -1; |
142 } |
142 } |
143 |
143 |
144 static void TownAuthorityWndProc(Window *w, WindowEvent *e) |
144 struct TownAuthorityWindow : Window { |
145 { |
145 int sel_index; |
146 switch (e->event) { |
146 |
147 case WE_PAINT: { |
147 TownAuthorityWindow(const WindowDesc *desc, WindowNumber window_number) : |
148 const Town *t = GetTown(w->window_number); |
148 Window(desc, window_number), sel_index(-1) |
149 int numact; |
149 { |
150 uint buttons = GetMaskOfTownActions(&numact, _local_player, t); |
150 this->vscroll.cap = 5; |
151 |
151 |
152 SetVScrollCount(w, numact + 1); |
152 this->FindWindowPlacementAndResize(desc); |
153 |
153 } |
154 if (WP(w, def_d).data_1 != -1 && !HasBit(buttons, WP(w, def_d).data_1)) |
154 |
155 WP(w, def_d).data_1 = -1; |
155 virtual void OnPaint() |
156 |
156 { |
157 w->SetWidgetDisabledState(6, WP(w, def_d).data_1 == -1); |
157 const Town *t = GetTown(this->window_number); |
158 |
158 int numact; |
159 { |
159 uint buttons = GetMaskOfTownActions(&numact, _local_player, t); |
160 int y; |
160 |
161 const Player *p; |
161 SetVScrollCount(this, numact + 1); |
162 int r; |
162 |
|
163 if (this->sel_index != -1 && !HasBit(buttons, this->sel_index)) { |
|
164 this->sel_index = -1; |
|
165 } |
|
166 |
|
167 this->SetWidgetDisabledState(6, this->sel_index == -1); |
|
168 |
|
169 SetDParam(0, this->window_number); |
|
170 DrawWindowWidgets(this); |
|
171 |
|
172 DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING); |
|
173 |
|
174 /* Draw list of players */ |
|
175 int y = 25; |
|
176 |
|
177 const Player *p; |
|
178 FOR_ALL_PLAYERS(p) { |
|
179 if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) { |
|
180 DrawPlayerIcon(p->index, 2, y); |
|
181 |
|
182 SetDParam(0, p->index); |
|
183 SetDParam(1, p->index); |
|
184 |
|
185 int r = t->ratings[p->index]; |
163 StringID str; |
186 StringID str; |
164 |
187 (str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling |
165 SetDParam(0, w->window_number); |
188 (str++, r <= RATING_VERYPOOR) || // Very Poor |
166 DrawWindowWidgets(w); |
189 (str++, r <= RATING_POOR) || // Poor |
167 |
190 (str++, r <= RATING_MEDIOCRE) || // Mediocore |
168 DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING); |
191 (str++, r <= RATING_GOOD) || // Good |
169 |
192 (str++, r <= RATING_VERYGOOD) || // Very Good |
170 /* Draw list of players */ |
193 (str++, r <= RATING_EXCELLENT) || // Excellent |
171 y = 25; |
194 (str++, true); // Outstanding |
172 FOR_ALL_PLAYERS(p) { |
195 |
173 if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) { |
196 SetDParam(2, str); |
174 DrawPlayerIcon(p->index, 2, y); |
197 if (t->exclusivity == p->index) { // red icon for player with exclusive rights |
175 |
198 DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y); |
176 SetDParam(0, p->index); |
|
177 SetDParam(1, p->index); |
|
178 |
|
179 r = t->ratings[p->index]; |
|
180 (str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling |
|
181 (str++, r <= RATING_VERYPOOR) || // Very Poor |
|
182 (str++, r <= RATING_POOR) || // Poor |
|
183 (str++, r <= RATING_MEDIOCRE) || // Mediocore |
|
184 (str++, r <= RATING_GOOD) || // Good |
|
185 (str++, r <= RATING_VERYGOOD) || // Very Good |
|
186 (str++, r <= RATING_EXCELLENT) || // Excellent |
|
187 (str++, true); // Outstanding |
|
188 |
|
189 SetDParam(2, str); |
|
190 if (t->exclusivity == p->index) { // red icon for player with exclusive rights |
|
191 DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y); |
|
192 } |
|
193 |
|
194 DrawString(28, y, STR_2024, TC_FROMSTRING); |
|
195 y += 10; |
|
196 } |
|
197 } |
199 } |
198 } |
200 |
199 |
201 DrawString(28, y, STR_2024, TC_FROMSTRING); |
200 /* Draw actions list */ |
202 y += 10; |
201 { |
203 } |
202 int y = 107, i; |
204 } |
203 int pos = w->vscroll.pos; |
205 y = 107; |
204 |
206 int pos = this->vscroll.pos; |
205 if (--pos < 0) { |
207 |
206 DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING); |
208 if (--pos < 0) { |
207 y += 10; |
209 DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING); |
|
210 y += 10; |
|
211 } |
|
212 |
|
213 for (int i = 0; buttons; i++, buttons >>= 1) { |
|
214 if (pos <= -5) break; ///< Draw only the 5 fitting lines |
|
215 |
|
216 if ((buttons & 1) && --pos < 0) { |
|
217 DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE); |
|
218 y += 10; |
|
219 } |
|
220 } |
|
221 |
|
222 if (this->sel_index != -1) { |
|
223 SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[this->sel_index]); |
|
224 SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + this->sel_index); |
|
225 DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + this->sel_index, 313); |
|
226 } |
|
227 } |
|
228 |
|
229 virtual void OnDoubleClick(Point pt, int widget) { HandleClick(pt, widget, true); } |
|
230 virtual void OnClick(Point pt, int widget) { HandleClick(pt, widget, false); } |
|
231 |
|
232 void HandleClick(Point pt, int widget, bool double_click) |
|
233 { |
|
234 switch (widget) { |
|
235 case TWA_COMMAND_LIST: { |
|
236 const Town *t = GetTown(this->window_number); |
|
237 int y = (pt.y - 0x6B) / 10; |
|
238 |
|
239 if (!IsInsideMM(y, 0, 5)) return; |
|
240 |
|
241 y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + this->vscroll.pos - 1); |
|
242 if (y >= 0) { |
|
243 this->sel_index = y; |
|
244 this->SetDirty(); |
208 } |
245 } |
209 |
246 /* Fall through to clicking in case we are double-clicked */ |
210 for (i = 0; buttons; i++, buttons >>= 1) { |
247 if (!double_click || y < 0) break; |
211 if (pos <= -5) break; ///< Draw only the 5 fitting lines |
248 } |
212 |
249 |
213 if ((buttons & 1) && --pos < 0) { |
250 case TWA_EXECUTE: |
214 DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE); |
251 DoCommandP(GetTown(this->window_number)->xy, this->window_number, this->sel_index, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS)); |
215 y += 10; |
252 break; |
216 } |
253 } |
217 } |
254 } |
218 } |
255 |
219 |
256 virtual void OnHundredthTick() |
220 { |
257 { |
221 int i = WP(w, def_d).data_1; |
258 this->SetDirty(); |
222 |
259 } |
223 if (i != -1) { |
260 }; |
224 SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]); |
|
225 SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i); |
|
226 DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313); |
|
227 } |
|
228 } |
|
229 |
|
230 } break; |
|
231 |
|
232 case WE_DOUBLE_CLICK: |
|
233 case WE_CLICK: |
|
234 switch (e->we.click.widget) { |
|
235 case TWA_COMMAND_LIST: { |
|
236 const Town *t = GetTown(w->window_number); |
|
237 int y = (e->we.click.pt.y - 0x6B) / 10; |
|
238 |
|
239 if (!IsInsideMM(y, 0, 5)) return; |
|
240 |
|
241 y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1); |
|
242 if (y >= 0) { |
|
243 WP(w, def_d).data_1 = y; |
|
244 w->SetDirty(); |
|
245 } |
|
246 /* Fall through to clicking in case we are double-clicked */ |
|
247 if (e->event != WE_DOUBLE_CLICK || y < 0) break; |
|
248 } |
|
249 |
|
250 case TWA_EXECUTE: |
|
251 DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w, def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS)); |
|
252 break; |
|
253 } |
|
254 break; |
|
255 |
|
256 case WE_100_TICKS: |
|
257 w->SetDirty(); |
|
258 break; |
|
259 } |
|
260 } |
|
261 |
261 |
262 static const WindowDesc _town_authority_desc = { |
262 static const WindowDesc _town_authority_desc = { |
263 WDP_AUTO, WDP_AUTO, 317, 222, 317, 222, |
263 WDP_AUTO, WDP_AUTO, 317, 222, 317, 222, |
264 WC_TOWN_AUTHORITY, WC_NONE, |
264 WC_TOWN_AUTHORITY, WC_NONE, |
265 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
265 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
266 _town_authority_widgets, |
266 _town_authority_widgets, |
267 TownAuthorityWndProc |
267 NULL |
268 }; |
268 }; |
269 |
269 |
270 static void ShowTownAuthorityWindow(uint town) |
270 static void ShowTownAuthorityWindow(uint town) |
271 { |
271 { |
272 Window *w = AllocateWindowDescFront<Window>(&_town_authority_desc, town); |
272 AllocateWindowDescFront<TownAuthorityWindow>(&_town_authority_desc, town); |
273 |
|
274 if (w != NULL) { |
|
275 w->vscroll.cap = 5; |
|
276 WP(w, def_d).data_1 = -1; |
|
277 } |
|
278 } |
273 } |
279 |
274 |
280 |
275 |
281 enum TownViewWidget { |
276 enum TownViewWidget { |
282 TVW_CAPTION = 1, |
277 TVW_CAPTION = 1, |