1 /***********************************************************************
2  Freeciv - Copyright (C) 1996-2006 - Freeciv Development Team
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 /* utility */
19 #include "astring.h"
20 #include "fcintl.h"
21 #include "log.h"
22 
23 /* common */
24 #include "actions.h"
25 #include "game.h"
26 #include "movement.h"
27 #include "research.h"
28 #include "traderoutes.h"
29 #include "unitlist.h"
30 
31 /* client */
32 #include "client_main.h"
33 #include "climisc.h"
34 #include "control.h"
35 #include "text.h"
36 
37 /* client/gui-sdl2 */
38 #include "citydlg.h"
39 #include "colors.h"
40 #include "dialogs.h"
41 #include "graphics.h"
42 #include "gui_id.h"
43 #include "gui_tilespec.h"
44 #include "mapview.h"
45 #include "repodlgs.h"
46 #include "themespec.h"
47 #include "widget.h"
48 
49 #include "dialogs_g.h"
50 
51 typedef int (*act_func)(struct widget *);
52 
53 struct diplomat_dialog {
54   int actor_unit_id;
55   int target_ids[ATK_COUNT];
56   struct ADVANCED_DLG *pdialog;
57 };
58 
59 struct small_diplomat_dialog {
60   int actor_unit_id;
61   int target_id;
62   struct SMALL_DLG *pdialog;
63 };
64 
65 extern bool is_unit_move_blocked;
66 
67 void popdown_diplomat_dialog(void);
68 void popdown_incite_dialog(void);
69 void popdown_bribe_dialog(void);
70 
71 
72 static struct diplomat_dialog *pDiplomat_Dlg = NULL;
73 static bool is_more_user_input_needed = FALSE;
74 static bool did_not_decide = FALSE;
75 
76 /**************************************************************************
77   The action selection is done.
78 **************************************************************************/
act_sel_done_primary(int actor_unit_id)79 static void act_sel_done_primary(int actor_unit_id)
80 {
81   if (!is_more_user_input_needed) {
82     /* The client isn't waiting for information for any unanswered follow
83      * up questions. */
84 
85     struct unit *actor_unit;
86 
87     if ((actor_unit = game_unit_by_number(actor_unit_id))) {
88       /* The action selection dialog wasn't closed because the actor unit
89        * was lost. */
90 
91       /* The probabilities didn't just disappear, right? */
92       fc_assert_action(actor_unit->client.act_prob_cache,
93                        client_unit_init_act_prob_cache(actor_unit));
94 
95       FC_FREE(actor_unit->client.act_prob_cache);
96     }
97 
98     /* The action selection process is over, at least for now. */
99     action_selection_no_longer_in_progress(actor_unit_id);
100 
101     if (did_not_decide) {
102       /* The action selection dialog was closed but the player didn't
103        * decide what the unit should do. */
104 
105       /* Reset so the next action selection dialog does the right thing. */
106       did_not_decide = FALSE;
107     } else {
108       /* An action, or no action at all, was selected. */
109       action_decision_clear_want(actor_unit_id);
110       action_selection_next_in_focus(actor_unit_id);
111     }
112   }
113 }
114 
115 /**************************************************************************
116   A follow up question about the selected action is done.
117 **************************************************************************/
act_sel_done_secondary(int actor_unit_id)118 static void act_sel_done_secondary(int actor_unit_id)
119 {
120   /* Stop blocking. */
121   is_more_user_input_needed = FALSE;
122   act_sel_done_primary(actor_unit_id);
123 }
124 
125 /**************************************************************************
126   Let the non shared client code know that the action selection process
127   no longer is in progress for the specified unit.
128 
129   This allows the client to clean up any client specific assumptions.
130 **************************************************************************/
action_selection_no_longer_in_progress_gui_specific(int actor_id)131 void action_selection_no_longer_in_progress_gui_specific(int actor_id)
132 {
133   /* Stop assuming the answer to a follow up question will arrive. */
134   is_more_user_input_needed = FALSE;
135 }
136 
137 /* ====================================================================== */
138 /* ============================ CARAVAN DIALOG ========================== */
139 /* ====================================================================== */
140 
141 /****************************************************************
142   User selected that caravan should enter marketplace.
143 *****************************************************************/
caravan_marketplace_callback(struct widget * pWidget)144 static int caravan_marketplace_callback(struct widget *pWidget)
145 {
146   if (PRESSED_EVENT(Main.event)) {
147     if (NULL != game_city_by_number(
148           pDiplomat_Dlg->target_ids[ATK_CITY])
149         && NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)) {
150       request_do_action(ACTION_MARKETPLACE,
151                         pDiplomat_Dlg->actor_unit_id,
152                         pDiplomat_Dlg->target_ids[ATK_CITY],
153                         0);
154     }
155 
156     popdown_diplomat_dialog();
157   }
158 
159   return -1;
160 }
161 
162 /****************************************************************
163   User selected that caravan should establish traderoute.
164 *****************************************************************/
caravan_establish_trade_callback(struct widget * pWidget)165 static int caravan_establish_trade_callback(struct widget *pWidget)
166 {
167   if (PRESSED_EVENT(Main.event)) {
168     if (NULL != game_city_by_number(
169           pDiplomat_Dlg->target_ids[ATK_CITY])
170         && NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)) {
171       request_do_action(ACTION_TRADE_ROUTE,
172                         pDiplomat_Dlg->actor_unit_id,
173                         pDiplomat_Dlg->target_ids[ATK_CITY],
174                         0);
175     }
176 
177     popdown_diplomat_dialog();
178   }
179 
180   return -1;
181 }
182 
183 /****************************************************************
184   User selected that caravan should help in wonder building.
185 *****************************************************************/
caravan_help_build_wonder_callback(struct widget * pWidget)186 static int caravan_help_build_wonder_callback(struct widget *pWidget)
187 {
188   if (PRESSED_EVENT(Main.event)) {
189     if (NULL != game_city_by_number(
190           pDiplomat_Dlg->target_ids[ATK_CITY])
191         && NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)) {
192       request_do_action(ACTION_HELP_WONDER,
193                         pDiplomat_Dlg->actor_unit_id,
194                         pDiplomat_Dlg->target_ids[ATK_CITY],
195                         0);
196     }
197 
198     popdown_diplomat_dialog();
199   }
200 
201   return -1;
202 }
203 
204 /* ====================================================================== */
205 /* ============================ DIPLOMAT DIALOG ========================= */
206 /* ====================================================================== */
207 
208 /****************************************************************
209   User interacted with diplomat dialog.
210 *****************************************************************/
diplomat_dlg_window_callback(struct widget * pWindow)211 static int diplomat_dlg_window_callback(struct widget *pWindow)
212 {
213   if (PRESSED_EVENT(Main.event)) {
214     move_window_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow);
215   }
216 
217   return -1;
218 }
219 
220 /****************************************************************
221   User clicked "Establish Embassy"
222 *****************************************************************/
diplomat_embassy_callback(struct widget * pWidget)223 static int diplomat_embassy_callback(struct widget *pWidget)
224 {
225   if (PRESSED_EVENT(Main.event)) {
226     if (NULL != game_city_by_number(
227           pDiplomat_Dlg->target_ids[ATK_CITY])
228         && NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)) {
229       request_do_action(ACTION_ESTABLISH_EMBASSY,
230                         pDiplomat_Dlg->actor_unit_id,
231                         pDiplomat_Dlg->target_ids[ATK_CITY],
232                         0);
233     }
234 
235     popdown_diplomat_dialog();
236   }
237 
238   return -1;
239 }
240 
241 /****************************************************************
242   User clicked "Investigate City"
243 *****************************************************************/
diplomat_investigate_callback(struct widget * pWidget)244 static int diplomat_investigate_callback(struct widget *pWidget)
245 {
246   if (PRESSED_EVENT(Main.event)) {
247     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
248         && NULL != game_city_by_number(
249           pDiplomat_Dlg->target_ids[ATK_CITY])) {
250       request_do_action(ACTION_SPY_INVESTIGATE_CITY,
251                         pDiplomat_Dlg->actor_unit_id,
252                         pDiplomat_Dlg->target_ids[ATK_CITY],
253                         0);
254     }
255 
256     /* FIXME: Wait for the city display in stead? */
257     popdown_diplomat_dialog();
258   }
259 
260   return -1;
261 }
262 
263 /****************************************************************
264   User clicked "Poison City"
265 *****************************************************************/
spy_poison_callback(struct widget * pWidget)266 static int spy_poison_callback(struct widget *pWidget)
267 {
268   if (PRESSED_EVENT(Main.event)) {
269     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
270         && NULL != game_city_by_number(
271           pDiplomat_Dlg->target_ids[ATK_CITY])) {
272       request_do_action(ACTION_SPY_POISON, pDiplomat_Dlg->actor_unit_id,
273                         pDiplomat_Dlg->target_ids[ATK_CITY],
274                         0);
275     }
276 
277     popdown_diplomat_dialog();
278   }
279 
280   return -1;
281 }
282 
283 /********************************************************************
284   User clicked "Steal Gold"
285 ********************************************************************/
spy_steal_gold_callback(struct widget * pWidget)286 static int spy_steal_gold_callback(struct widget *pWidget)
287 {
288   if (PRESSED_EVENT(Main.event)) {
289     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
290         && NULL != game_city_by_number(
291           pDiplomat_Dlg->target_ids[ATK_CITY])) {
292       request_do_action(ACTION_SPY_STEAL_GOLD,
293                         pDiplomat_Dlg->actor_unit_id,
294                         pDiplomat_Dlg->target_ids[ATK_CITY],
295                         0);
296     }
297 
298     popdown_diplomat_dialog();
299   }
300 
301   return -1;
302 }
303 
304 /****************************************************************
305  Requests up-to-date list of improvements, the return of
306  which will trigger the popup_sabotage_dialog() function.
307 *****************************************************************/
spy_sabotage_request(struct widget * pWidget)308 static int spy_sabotage_request(struct widget *pWidget)
309 {
310   if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
311       && NULL != game_city_by_number(
312               pDiplomat_Dlg->target_ids[ATK_CITY])) {
313     request_action_details(ACTION_SPY_TARGETED_SABOTAGE_CITY,
314                            pDiplomat_Dlg->actor_unit_id,
315                            pDiplomat_Dlg->target_ids[ATK_CITY]);
316     is_more_user_input_needed = TRUE;
317     popdown_diplomat_dialog();
318   } else {
319     popdown_diplomat_dialog();
320   }
321 
322   return -1;
323 }
324 
325 /****************************************************************
326   User clicked "Sabotage City" for diplomat (not spy)
327 *****************************************************************/
diplomat_sabotage_callback(struct widget * pWidget)328 static int diplomat_sabotage_callback(struct widget *pWidget)
329 {
330   if (PRESSED_EVENT(Main.event)) {
331     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
332         && NULL != game_city_by_number(
333                 pDiplomat_Dlg->target_ids[ATK_CITY])) {
334       request_do_action(ACTION_SPY_SABOTAGE_CITY,
335                         pDiplomat_Dlg->actor_unit_id,
336                         pDiplomat_Dlg->target_ids[ATK_CITY],
337                         B_LAST + 1);
338     }
339 
340     popdown_diplomat_dialog();
341   }
342 
343   return -1;
344 }
345 
346 /* --------------------------------------------------------- */
347 
348 /****************************************************************
349   User interacted with spy's steal dialog window.
350 *****************************************************************/
spy_steal_dlg_window_callback(struct widget * pWindow)351 static int spy_steal_dlg_window_callback(struct widget *pWindow)
352 {
353   if (PRESSED_EVENT(Main.event)) {
354     move_window_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow);
355   }
356 
357   return -1;
358 }
359 
360 /****************************************************************
361   Exit spy's steal or sabotage dialog.
362 *****************************************************************/
exit_spy_tgt_dlg_callback(struct widget * pWidget)363 static int exit_spy_tgt_dlg_callback(struct widget *pWidget)
364 {
365   if (PRESSED_EVENT(Main.event)) {
366     int actor_id = pDiplomat_Dlg->actor_unit_id;
367 
368     fc_assert(is_more_user_input_needed);
369     popdown_diplomat_dialog();
370     act_sel_done_secondary(actor_id);
371   }
372 
373   return -1;
374 }
375 
376 /****************************************************************
377   User selected which tech spy steals.
378 *****************************************************************/
spy_steal_callback(struct widget * pWidget)379 static int spy_steal_callback(struct widget *pWidget)
380 {
381   if (PRESSED_EVENT(Main.event)) {
382     int steal_advance = MAX_ID - pWidget->ID;
383     int actor_id = pDiplomat_Dlg->actor_unit_id;
384 
385     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
386         && NULL != game_city_by_number(
387                 pDiplomat_Dlg->target_ids[ATK_CITY])) {
388       if (steal_advance == A_UNSET) {
389         /* This is the untargeted version. */
390         request_do_action(ACTION_SPY_STEAL_TECH,
391                           pDiplomat_Dlg->actor_unit_id,
392                           pDiplomat_Dlg->target_ids[ATK_CITY],
393                           steal_advance);
394       } else {
395         /* This is the targeted version. */
396         request_do_action(ACTION_SPY_TARGETED_STEAL_TECH,
397                           pDiplomat_Dlg->actor_unit_id,
398                           pDiplomat_Dlg->target_ids[ATK_CITY],
399                           steal_advance);
400       }
401     }
402 
403     fc_assert(is_more_user_input_needed);
404     popdown_diplomat_dialog();
405     act_sel_done_secondary(actor_id);
406   }
407 
408   return -1;
409 }
410 
411 /**************************************************************************
412   Popup spy tech stealing dialog.
413 **************************************************************************/
spy_steal_popup(struct widget * pWidget)414 static int spy_steal_popup(struct widget *pWidget)
415 {
416   const struct research *presearch, *vresearch;
417   struct city *pVcity = pWidget->data.city;
418   int id = MAX_ID - pWidget->ID;
419   struct player *pVictim = NULL;
420   struct CONTAINER *pCont;
421   struct widget *pBuf = NULL;
422   struct widget *pWindow;
423   utf8_str *pstr;
424   SDL_Surface *pSurf;
425   int max_col, max_row, col, count = 0;
426   int tech, idx;
427   SDL_Rect area;
428 
429   struct unit *actor_unit = game_unit_by_number(id);
430 
431   is_more_user_input_needed = TRUE;
432   popdown_diplomat_dialog();
433 
434   if (pVcity) {
435     pVictim = city_owner(pVcity);
436   }
437 
438   fc_assert_ret_val_msg(!pDiplomat_Dlg, 1, "Diplomat dialog already open");
439 
440   if (!pVictim) {
441     act_sel_done_secondary(id);
442     return 1;
443   }
444 
445   count = 0;
446   presearch = research_get(client_player());
447   vresearch = research_get(pVictim);
448   advance_index_iterate(A_FIRST, i) {
449     if (research_invention_gettable(presearch, i,
450                                     game.info.tech_steal_allow_holes)
451         && TECH_KNOWN == research_invention_state(vresearch, i)
452         && TECH_KNOWN != research_invention_state(presearch, i)) {
453       count++;
454     }
455   } advance_index_iterate_end;
456 
457   if (!count) {
458     /* if there is no known tech to steal then
459      * send steal order at Spy's Discretion */
460     int target_id = pVcity->id;
461 
462     request_do_action(ACTION_SPY_STEAL_TECH,
463                       id, target_id, A_UNSET);
464 
465     act_sel_done_secondary(id);
466 
467     return -1;
468   }
469 
470   pCont = fc_calloc(1, sizeof(struct CONTAINER));
471   pCont->id0 = pVcity->id;
472   pCont->id1 = id;/* spy id */
473 
474   pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog));
475   pDiplomat_Dlg->actor_unit_id = id;
476   pDiplomat_Dlg->target_ids[ATK_CITY] = pVcity->id;
477   pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG));
478 
479   pstr = create_utf8_from_char(_("Select Advance to Steal"), adj_font(12));
480   pstr->style |= TTF_STYLE_BOLD;
481 
482   pWindow = create_window_skeleton(NULL, pstr, 0);
483 
484   pWindow->action = spy_steal_dlg_window_callback;
485   set_wstate(pWindow , FC_WS_NORMAL);
486 
487   add_to_gui_list(ID_DIPLOMAT_DLG_WINDOW, pWindow);
488   pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow;
489 
490   area = pWindow->area;
491   area.w = MAX(area.w, adj_size(8));
492 
493   /* ------------------ */
494   /* exit button */
495   pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
496                           WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
497   pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
498                                            adj_font(12));
499   area.w += pBuf->size.w + adj_size(10);
500   pBuf->action = exit_spy_tgt_dlg_callback;
501   set_wstate(pBuf, FC_WS_NORMAL);
502   pBuf->key = SDLK_ESCAPE;
503 
504   add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf);
505   /* ------------------------- */
506 
507   if (action_prob_possible(
508         actor_unit->client.act_prob_cache[ACTION_SPY_STEAL_TECH])) {
509      /* count + at Spy's Discretion */
510     count++;
511   }
512 
513   /* max col - 104 is steal tech widget width */
514   max_col = (main_window_width() - (pWindow->size.w - pWindow->area.w) - adj_size(2)) / adj_size(104);
515   /* max row - 204 is steal tech widget height */
516   max_row = (main_window_height() - (pWindow->size.h - pWindow->area.h)) / adj_size(204);
517 
518   /* make space on screen for scrollbar */
519   if (max_col * max_row < count) {
520     max_col--;
521   }
522 
523   if (count < max_col + 1) {
524     col = count;
525   } else {
526     if (count < max_col + adj_size(3)) {
527       col = max_col - adj_size(2);
528     } else {
529       if (count < max_col + adj_size(5)) {
530         col = max_col - 1;
531       } else {
532         col = max_col;
533       }
534     }
535   }
536 
537   pstr = create_utf8_str(NULL, 0, adj_font(10));
538   pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
539 
540   count = 0;
541   advance_index_iterate(A_FIRST, i) {
542     if (research_invention_gettable(presearch, i,
543                                     game.info.tech_steal_allow_holes)
544         && TECH_KNOWN == research_invention_state(vresearch, i)
545         && TECH_KNOWN != research_invention_state(presearch, i)) {
546       count++;
547 
548       copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(i)));
549       pSurf = create_select_tech_icon(pstr, i, FULL_MODE);
550       pBuf = create_icon2(pSurf, pWindow->dst,
551       		WF_FREE_THEME | WF_RESTORE_BACKGROUND);
552 
553       set_wstate(pBuf, FC_WS_NORMAL);
554       pBuf->action = spy_steal_callback;
555       pBuf->data.cont = pCont;
556 
557       add_to_gui_list(MAX_ID - i, pBuf);
558 
559       if (count > (col * max_row)) {
560         set_wflag(pBuf, WF_HIDDEN);
561       }
562     }
563   } advance_index_iterate_end;
564 
565   /* Get Spy tech to use for "At Spy's Discretion" -- this will have the
566    * side effect of displaying the unit's icon */
567   tech = advance_number(unit_type_get(actor_unit)->require_advance);
568 
569   if (action_prob_possible(
570         actor_unit->client.act_prob_cache[ACTION_SPY_STEAL_TECH])) {
571     struct astring str = ASTRING_INIT;
572 
573     /* TRANS: %s is a unit name, e.g., Spy */
574     astr_set(&str, _("At %s's Discretion"),
575              unit_name_translation(actor_unit));
576     copy_chars_to_utf8_str(pstr, astr_str(&str));
577     astr_free(&str);
578 
579     pSurf = create_select_tech_icon(pstr, tech, FULL_MODE);
580 
581     pBuf = create_icon2(pSurf, pWindow->dst,
582                         (WF_FREE_THEME | WF_RESTORE_BACKGROUND
583                          | WF_FREE_DATA));
584     set_wstate(pBuf, FC_WS_NORMAL);
585     pBuf->action = spy_steal_callback;
586     pBuf->data.cont = pCont;
587 
588     add_to_gui_list(MAX_ID - A_UNSET, pBuf);
589     count++;
590   }
591 
592   /* --------------------------------------------------------- */
593   FREEUTF8STR(pstr);
594   pDiplomat_Dlg->pdialog->pBeginWidgetList = pBuf;
595   pDiplomat_Dlg->pdialog->pBeginActiveWidgetList = pDiplomat_Dlg->pdialog->pBeginWidgetList;
596   pDiplomat_Dlg->pdialog->pEndActiveWidgetList = pDiplomat_Dlg->pdialog->pEndWidgetList->prev->prev;
597 
598   /* -------------------------------------------------------------- */
599 
600   idx = 0;
601   if (count > col) {
602     count = (count + (col - 1)) / col;
603     if (count > max_row) {
604       pDiplomat_Dlg->pdialog->pActiveWidgetList = pDiplomat_Dlg->pdialog->pEndActiveWidgetList;
605       count = max_row;
606       idx = create_vertical_scrollbar(pDiplomat_Dlg->pdialog, col, count, TRUE, TRUE);
607     }
608   } else {
609     count = 1;
610   }
611 
612   area.w = MAX(area.w, (col * pBuf->size.w + adj_size(2) + idx));
613   area.h = count * pBuf->size.h + adj_size(2);
614 
615   /* alloca window theme and win background buffer */
616   pSurf = theme_get_background(theme, BACKGROUND_SPYSTEALDLG);
617   if (resize_window(pWindow, pSurf, NULL,
618                     (pWindow->size.w - pWindow->area.w) + area.w,
619                     (pWindow->size.h - pWindow->area.h) + area.h)) {
620     FREESURFACE(pSurf);
621   }
622 
623   area = pWindow->area;
624 
625   widget_set_position(pWindow,
626                       (main_window_width() - pWindow->size.w) / 2,
627                       (main_window_height() - pWindow->size.h) / 2);
628 
629   /* exit button */
630   pBuf = pWindow->prev;
631   pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
632   pBuf->size.y = pWindow->size.y + adj_size(2);
633 
634   setup_vertical_widgets_position(col, area.x + 1,
635 		  area.y, 0, 0,
636 		  pDiplomat_Dlg->pdialog->pBeginActiveWidgetList,
637   		  pDiplomat_Dlg->pdialog->pEndActiveWidgetList);
638 
639   if (pDiplomat_Dlg->pdialog->pScroll) {
640     setup_vertical_scrollbar_area(pDiplomat_Dlg->pdialog->pScroll,
641 	area.x + area.w, area.y,
642     	area.h, TRUE);
643   }
644 
645   redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, FALSE);
646   widget_mark_dirty(pWindow);
647 
648   return -1;
649 }
650 
651 /****************************************************************
652   Technology stealing dialog, diplomat (not spy) version
653 *****************************************************************/
diplomat_steal_callback(struct widget * pWidget)654 static int diplomat_steal_callback(struct widget *pWidget)
655 {
656   if (PRESSED_EVENT(Main.event)) {
657     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
658         && NULL != game_city_by_number(
659                 pDiplomat_Dlg->target_ids[ATK_CITY])) {
660       request_do_action(ACTION_SPY_STEAL_TECH,
661                         pDiplomat_Dlg->actor_unit_id,
662                         pDiplomat_Dlg->target_ids[ATK_CITY],
663                         A_UNSET);
664     }
665 
666     popdown_diplomat_dialog();
667   }
668 
669   return -1;
670 }
671 
672 /****************************************************************
673 ...  Ask the server how much the revolt is going to cost us
674 *****************************************************************/
diplomat_incite_callback(struct widget * pWidget)675 static int diplomat_incite_callback(struct widget *pWidget)
676 {
677   if (PRESSED_EVENT(Main.event)) {
678     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
679         && NULL != game_city_by_number(
680                 pDiplomat_Dlg->target_ids[ATK_CITY])) {
681       request_action_details(ACTION_SPY_INCITE_CITY,
682                              pDiplomat_Dlg->actor_unit_id,
683                              pDiplomat_Dlg->target_ids[ATK_CITY]);
684       is_more_user_input_needed = TRUE;
685       popdown_diplomat_dialog();
686     } else {
687       popdown_diplomat_dialog();
688     }
689   }
690 
691   return -1;
692 }
693 
694 /********************************************************************
695   Callback from action selection dialog for "keep moving".
696   (This should only occur when entering a tile with an allied city
697   or an allied unit.)
698 *********************************************************************/
act_sel_keep_moving_callback(struct widget * pWidget)699 static int act_sel_keep_moving_callback(struct widget *pWidget)
700 {
701   if (PRESSED_EVENT(Main.event)) {
702     struct unit *punit;
703 
704     if ((punit = game_unit_by_number(pDiplomat_Dlg->actor_unit_id))
705         && !same_pos(unit_tile(punit), pWidget->data.tile)) {
706       request_unit_non_action_move(punit, pWidget->data.tile);
707     }
708 
709     popdown_diplomat_dialog();
710   }
711 
712   return -1;
713 }
714 
715 /********************************************************************
716   Delay selection of what action to take.
717 *********************************************************************/
act_sel_wait_callback(struct widget * pWidget)718 static int act_sel_wait_callback(struct widget *pWidget)
719 {
720   if (PRESSED_EVENT(Main.event)) {
721     key_unit_wait();
722 
723     /* The dialog was popped down when key_unit_wait() resulted in
724      * action_selection_close() being called. */
725   }
726 
727   return -1;
728 }
729 
730 /****************************************************************
731 ...  Ask the server how much the bribe is
732 *****************************************************************/
diplomat_bribe_callback(struct widget * pWidget)733 static int diplomat_bribe_callback(struct widget *pWidget)
734 {
735   if (PRESSED_EVENT(Main.event)) {
736     if (NULL != game_unit_by_number(pDiplomat_Dlg->actor_unit_id)
737         && NULL !=
738          game_unit_by_number(pDiplomat_Dlg->target_ids[ATK_UNIT])) {
739       request_action_details(ACTION_SPY_BRIBE_UNIT,
740                              pDiplomat_Dlg->actor_unit_id,
741                              pDiplomat_Dlg->target_ids[ATK_UNIT]);
742       is_more_user_input_needed = TRUE;
743       popdown_diplomat_dialog();
744     } else {
745       popdown_diplomat_dialog();
746     }
747   }
748 
749   return -1;
750 }
751 
752 /****************************************************************
753   User clicked "Sabotage Unit"
754 *****************************************************************/
spy_sabotage_unit_callback(struct widget * pWidget)755 static int spy_sabotage_unit_callback(struct widget *pWidget)
756 {
757   if (PRESSED_EVENT(Main.event)) {
758     int diplomat_id = MAX_ID - pWidget->ID;
759     int target_id = pWidget->data.unit->id;
760 
761     popdown_diplomat_dialog();
762     request_do_action(ACTION_SPY_SABOTAGE_UNIT,
763                       diplomat_id, target_id, 0);
764   }
765 
766   return -1;
767 }
768 
769 /****************************************************************
770   Close diplomat dialog.
771 *****************************************************************/
diplomat_close_callback(struct widget * pWidget)772 static int diplomat_close_callback(struct widget *pWidget)
773 {
774   if (PRESSED_EVENT(Main.event)) {
775     popdown_diplomat_dialog();
776   }
777 
778   return -1;
779 }
780 
781 /**************************************************************************
782   Popdown a dialog giving a diplomatic unit some options when moving into
783   the target tile.
784 **************************************************************************/
popdown_diplomat_dialog(void)785 void popdown_diplomat_dialog(void)
786 {
787   if (pDiplomat_Dlg) {
788     act_sel_done_primary(pDiplomat_Dlg->actor_unit_id);
789 
790     is_unit_move_blocked = FALSE;
791     popdown_window_group_dialog(pDiplomat_Dlg->pdialog->pBeginWidgetList,
792 				pDiplomat_Dlg->pdialog->pEndWidgetList);
793     FC_FREE(pDiplomat_Dlg->pdialog->pScroll);
794     FC_FREE(pDiplomat_Dlg->pdialog);
795     FC_FREE(pDiplomat_Dlg);
796     queue_flush();
797   }
798 }
799 
800 /* Mapping from an action to the function to call when its button is
801  * pushed. */
802 static const act_func af_map[ACTION_COUNT] = {
803   /* Unit acting against a city target. */
804   [ACTION_ESTABLISH_EMBASSY] = diplomat_embassy_callback,
805   [ACTION_SPY_INVESTIGATE_CITY] = diplomat_investigate_callback,
806   [ACTION_SPY_POISON] = spy_poison_callback,
807   [ACTION_SPY_STEAL_GOLD] = spy_steal_gold_callback,
808   [ACTION_SPY_SABOTAGE_CITY] = diplomat_sabotage_callback,
809   [ACTION_SPY_TARGETED_SABOTAGE_CITY] = spy_sabotage_request,
810   [ACTION_SPY_STEAL_TECH] = diplomat_steal_callback,
811   [ACTION_SPY_TARGETED_STEAL_TECH] = spy_steal_popup,
812   [ACTION_SPY_INCITE_CITY] = diplomat_incite_callback,
813   [ACTION_TRADE_ROUTE] = caravan_establish_trade_callback,
814   [ACTION_MARKETPLACE] = caravan_marketplace_callback,
815   [ACTION_HELP_WONDER] = caravan_help_build_wonder_callback,
816 
817   /* Unit acting against a unit target. */
818   [ACTION_SPY_BRIBE_UNIT] = diplomat_bribe_callback,
819   [ACTION_SPY_SABOTAGE_UNIT] = spy_sabotage_unit_callback
820 };
821 
822 /**************************************************************************
823   Add an entry for an action in the action choice dialog.
824 **************************************************************************/
action_entry(const enum gen_action act,const struct act_prob * act_probs,struct unit * act_unit,struct city * tgt_city,struct unit * tgt_unit,struct widget * pWindow,SDL_Rect * area)825 static void action_entry(const enum gen_action act,
826                          const struct act_prob *act_probs,
827                          struct unit *act_unit,
828                          struct city *tgt_city,
829                          struct unit *tgt_unit,
830                          struct widget *pWindow,
831                          SDL_Rect *area)
832 {
833   struct widget *pBuf;
834   utf8_str *pstr;
835   const char *ui_name;
836 
837   const char *custom = get_act_sel_action_custom_text(action_by_number(act),
838                                                       act_probs[act],
839                                                       act_unit,
840                                                       tgt_city);
841 
842   if (act == ACTION_SPY_SABOTAGE_CITY
843       && action_prob_possible(
844         act_probs[ACTION_SPY_TARGETED_SABOTAGE_CITY])) {
845     /* The player can select Sabotage City from the target selection dialog
846      * of Targeted Sabotage City. */
847     return;
848   }
849 
850   if (act == ACTION_SPY_STEAL_TECH
851       && action_prob_possible(
852         act_probs[ACTION_SPY_TARGETED_STEAL_TECH])) {
853     /* The player can select Steal Tech from the target selection dialog of
854      * Targeted Steal Tech. */
855     return;
856   }
857 
858   /* Don't show disabled actions */
859   if (!action_prob_possible(act_probs[act])) {
860     return;
861   }
862 
863   ui_name = action_prepare_ui_name(act, "",
864                                    act_probs[act], custom);
865 
866   create_active_iconlabel(pBuf, pWindow->dst, pstr,
867                           ui_name, af_map[act]);
868 
869   switch(action_id_get_target_kind(act)) {
870   case ATK_CITY:
871     pBuf->data.city = tgt_city;
872     break;
873   case ATK_UNIT:
874     pBuf->data.unit = tgt_unit;
875     break;
876   case ATK_COUNT:
877     fc_assert_msg(FALSE, "Unsupported target kind");
878   }
879 
880   set_wstate(pBuf, FC_WS_NORMAL);
881 
882   add_to_gui_list(MAX_ID - act_unit->id, pBuf);
883 
884   area->w = MAX(area->w, pBuf->size.w);
885   area->h += pBuf->size.h;
886 }
887 
888 /**************************************************************************
889   Popup a dialog that allows the player to select what action a unit
890   should take.
891 **************************************************************************/
popup_action_selection(struct unit * actor_unit,struct city * target_city,struct unit * target_unit,struct tile * target_tile,const struct act_prob * act_probs)892 void popup_action_selection(struct unit *actor_unit,
893                             struct city *target_city,
894                             struct unit *target_unit,
895                             struct tile *target_tile,
896                             const struct act_prob *act_probs)
897 {
898   struct widget *pWindow = NULL, *pBuf = NULL;
899   utf8_str *pstr;
900   SDL_Rect area;
901 
902   fc_assert_ret_msg(!pDiplomat_Dlg, "Diplomat dialog already open");
903 
904   /* Could be caused by the server failing to reply to a request for more
905    * information or a bug in the client code. */
906   fc_assert_msg(!is_more_user_input_needed,
907                 "Diplomat queue problem. Is another diplomat window open?");
908 
909   /* No extra input is required as no action has been chosen yet. */
910   is_more_user_input_needed = FALSE;
911 
912   is_unit_move_blocked = TRUE;
913 
914   pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog));
915   pDiplomat_Dlg->actor_unit_id = actor_unit->id;
916   pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG));
917 
918   /* window */
919   if (target_city) {
920     struct astring title = ASTRING_INIT;
921 
922     /* TRANS: %s is a unit name, e.g., Spy */
923     astr_set(&title, _("Choose Your %s's Strategy"),
924              unit_name_translation(actor_unit));
925     pstr = create_utf8_from_char(astr_str(&title), adj_font(12));
926     astr_free(&title);
927   } else {
928     pstr = create_utf8_from_char(_("Subvert Enemy Unit"), adj_font(12));
929   }
930 
931   pstr->style |= TTF_STYLE_BOLD;
932 
933   pWindow = create_window_skeleton(NULL, pstr, 0);
934 
935   pWindow->action = diplomat_dlg_window_callback;
936   set_wstate(pWindow, FC_WS_NORMAL);
937 
938   add_to_gui_list(ID_CARAVAN_DLG_WINDOW, pWindow);
939   pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow;
940 
941   area = pWindow->area;
942   area.w = MAX(area.w, adj_size(8));
943   area.h = MAX(area.h, adj_size(2));
944 
945   if (target_city) {
946     pDiplomat_Dlg->target_ids[ATK_CITY] = target_city->id;
947   } else {
948     pDiplomat_Dlg->target_ids[ATK_CITY] = IDENTITY_NUMBER_ZERO;
949   }
950 
951   if (target_unit) {
952     pDiplomat_Dlg->target_ids[ATK_UNIT] = target_unit->id;
953   } else {
954     pDiplomat_Dlg->target_ids[ATK_UNIT] = IDENTITY_NUMBER_ZERO;
955   }
956 
957   /* ---------- */
958   /* Unit acting against a city */
959 
960   action_iterate(act) {
961     if (action_id_get_actor_kind(act) == AAK_UNIT
962         && action_id_get_target_kind(act) == ATK_CITY) {
963       action_entry(act, act_probs,
964                    actor_unit, target_city, NULL,
965                    pWindow, &area);
966     }
967   } action_iterate_end;
968 
969   /* Unit acting against another unit */
970 
971   action_iterate(act) {
972     if (action_id_get_actor_kind(act) == AAK_UNIT
973         && action_id_get_target_kind(act) == ATK_UNIT) {
974       action_entry(act, act_probs,
975                    actor_unit, NULL, target_unit,
976                    pWindow, &area);
977     }
978   } action_iterate_end;
979 
980   /* ---------- */
981   if (unit_can_move_to_tile(actor_unit, target_tile, FALSE)
982       || (is_military_unit(actor_unit) || is_attack_unit(actor_unit))
983       || (can_unit_bombard(actor_unit) && !is_ocean_tile(target_tile))
984       || (!target_city && unit_has_type_flag(actor_unit, UTYF_CAPTURER))) {
985     create_active_iconlabel(pBuf, pWindow->dst, pstr,
986                             _("Keep moving"),
987                             act_sel_keep_moving_callback);
988 
989     pBuf->data.tile = target_tile;
990 
991     set_wstate(pBuf, FC_WS_NORMAL);
992 
993     add_to_gui_list(MAX_ID - actor_unit->id, pBuf);
994 
995     area.w = MAX(area.w, pBuf->size.w);
996     area.h += pBuf->size.h;
997   }
998 
999   /* ---------- */
1000   create_active_iconlabel(pBuf, pWindow->dst, pstr,
1001                           _("Wait"), act_sel_wait_callback);
1002 
1003   pBuf->data.tile = target_tile;
1004 
1005   set_wstate(pBuf, FC_WS_NORMAL);
1006 
1007   add_to_gui_list(MAX_ID - actor_unit->id, pBuf);
1008 
1009   area.w = MAX(area.w, pBuf->size.w);
1010   area.h += pBuf->size.h;
1011 
1012   /* ---------- */
1013   create_active_iconlabel(pBuf, pWindow->dst, pstr,
1014                           _("Cancel"), diplomat_close_callback);
1015 
1016   set_wstate(pBuf , FC_WS_NORMAL);
1017   pBuf->key = SDLK_ESCAPE;
1018 
1019   add_to_gui_list(ID_LABEL , pBuf);
1020 
1021   area.w = MAX(area.w, pBuf->size.w);
1022   area.h += pBuf->size.h;
1023   /* ---------- */
1024   pDiplomat_Dlg->pdialog->pBeginWidgetList = pBuf;
1025 
1026   /* setup window size and start position */
1027 
1028   resize_window(pWindow, NULL, NULL,
1029                 (pWindow->size.w - pWindow->area.w) + area.w,
1030                 (pWindow->size.h - pWindow->area.h) + area.h);
1031 
1032   area = pWindow->area;
1033 
1034   auto_center_on_focus_unit();
1035   put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h,
1036                            unit_tile(actor_unit));
1037 
1038   /* setup widget size and start position */
1039 
1040   pBuf = pWindow->prev;
1041   setup_vertical_widgets_position(1,
1042 	area.x,
1043   	area.y + 1, area.w, 0,
1044 	pDiplomat_Dlg->pdialog->pBeginWidgetList, pBuf);
1045 
1046   /* --------------------- */
1047   /* redraw */
1048   redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, 0);
1049 
1050   widget_flush(pWindow);
1051 
1052   /* Give follow up questions access to action probabilities. */
1053   client_unit_init_act_prob_cache(actor_unit);
1054   action_iterate(act) {
1055     actor_unit->client.act_prob_cache[act] = act_probs[act];
1056   } action_iterate_end;
1057 }
1058 
1059 /**************************************************************************
1060   Returns the id of the actor unit currently handled in action selection
1061   dialog when the action selection dialog is open.
1062   Returns IDENTITY_NUMBER_ZERO if no action selection dialog is open.
1063 **************************************************************************/
action_selection_actor_unit(void)1064 int action_selection_actor_unit(void)
1065 {
1066   if (!pDiplomat_Dlg) {
1067     return IDENTITY_NUMBER_ZERO;
1068   }
1069 
1070   return pDiplomat_Dlg->actor_unit_id;
1071 }
1072 
1073 /**************************************************************************
1074   Returns id of the target city of the actions currently handled in action
1075   selection dialog when the action selection dialog is open and it has a
1076   city target. Returns IDENTITY_NUMBER_ZERO if no action selection dialog
1077   is open or no city target is present in the action selection dialog.
1078 **************************************************************************/
action_selection_target_city(void)1079 int action_selection_target_city(void)
1080 {
1081   if (!pDiplomat_Dlg) {
1082     return IDENTITY_NUMBER_ZERO;
1083   }
1084 
1085   return pDiplomat_Dlg->target_ids[ATK_CITY];
1086 }
1087 
1088 /**************************************************************************
1089   Returns id of the target unit of the actions currently handled in action
1090   selection dialog when the action selection dialog is open and it has a
1091   unit target. Returns IDENTITY_NUMBER_ZERO if no action selection dialog
1092   is open or no unit target is present in the action selection dialog.
1093 **************************************************************************/
action_selection_target_unit(void)1094 int action_selection_target_unit(void)
1095 {
1096   if (!pDiplomat_Dlg) {
1097     return IDENTITY_NUMBER_ZERO;
1098   }
1099 
1100   return pDiplomat_Dlg->target_ids[ATK_UNIT];
1101 }
1102 
1103 /**************************************************************************
1104   Updates the action selection dialog with new information.
1105 **************************************************************************/
action_selection_refresh(struct unit * actor_unit,struct city * target_city,struct unit * target_unit,struct tile * target_tile,const struct act_prob * act_probs)1106 void action_selection_refresh(struct unit *actor_unit,
1107                               struct city *target_city,
1108                               struct unit *target_unit,
1109                               struct tile *target_tile,
1110                               const struct act_prob *act_probs)
1111 {
1112   action_selection_close();
1113   popup_action_selection(actor_unit,
1114                          target_city, target_unit,
1115                          target_tile,
1116                          act_probs);
1117 }
1118 
1119 /****************************************************************
1120   Closes the action selection dialog
1121 ****************************************************************/
action_selection_close(void)1122 void action_selection_close(void)
1123 {
1124   did_not_decide = TRUE;
1125   popdown_diplomat_dialog();
1126 }
1127 
1128 /* ====================================================================== */
1129 /* ============================ SABOTAGE DIALOG ========================= */
1130 /* ====================================================================== */
1131 
1132 /****************************************************************
1133   User selected what to sabotage.
1134 ****************************************************************/
sabotage_impr_callback(struct widget * pWidget)1135 static int sabotage_impr_callback(struct widget *pWidget)
1136 {
1137   if (PRESSED_EVENT(Main.event)) {
1138     int sabotage_improvement = MAX_ID - pWidget->ID;
1139     int diplomat_target_id = pWidget->data.cont->id0;
1140     int diplomat_id = pWidget->data.cont->id1;
1141 
1142     fc_assert(is_more_user_input_needed);
1143     popdown_diplomat_dialog();
1144 
1145     if (sabotage_improvement == 1000) {
1146       sabotage_improvement = -1;
1147     }
1148 
1149     if (NULL != game_unit_by_number(diplomat_id)
1150         && NULL != game_city_by_number(diplomat_target_id)) {
1151       if (sabotage_improvement == B_LAST) {
1152         /* This is the untargeted version. */
1153         request_do_action(ACTION_SPY_SABOTAGE_CITY, diplomat_id,
1154                           diplomat_target_id, sabotage_improvement + 1);
1155       } else {
1156         /* This is the targeted version. */
1157         request_do_action(ACTION_SPY_TARGETED_SABOTAGE_CITY, diplomat_id,
1158                           diplomat_target_id, sabotage_improvement + 1);
1159       }
1160     }
1161 
1162     act_sel_done_secondary(diplomat_id);
1163   }
1164 
1165   return -1;
1166 }
1167 
1168 /*************************************************************************
1169  Pops-up the Spy sabotage dialog, upon return of list of
1170  available improvements requested by the above function.
1171 **************************************************************************/
popup_sabotage_dialog(struct unit * actor,struct city * pCity)1172 void popup_sabotage_dialog(struct unit *actor, struct city *pCity)
1173 {
1174   struct widget *pWindow = NULL, *pBuf = NULL , *pLast = NULL;
1175   struct CONTAINER *pCont;
1176   utf8_str *pstr;
1177   SDL_Rect area, area2;
1178   int n, w = 0, h, imp_h = 0, y;
1179 
1180   fc_assert_ret_msg(!pDiplomat_Dlg, "Diplomat dialog already open");
1181 
1182   /* Should be set before sending request to the server. */
1183   fc_assert(is_more_user_input_needed);
1184 
1185   if (!actor) {
1186     act_sel_done_secondary(IDENTITY_NUMBER_ZERO);
1187     return;
1188   }
1189 
1190   is_unit_move_blocked = TRUE;
1191 
1192   pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog));
1193   pDiplomat_Dlg->actor_unit_id = actor->id;
1194   pDiplomat_Dlg->target_ids[ATK_CITY] = pCity->id;
1195   pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG));
1196 
1197   pCont = fc_calloc(1, sizeof(struct CONTAINER));
1198   pCont->id0 = pCity->id;
1199   pCont->id1 = actor->id; /* spy id */
1200 
1201   pstr = create_utf8_from_char(_("Select Improvement to Sabotage") , adj_font(12));
1202   pstr->style |= TTF_STYLE_BOLD;
1203 
1204   pWindow = create_window_skeleton(NULL, pstr, 0);
1205 
1206   pWindow->action = diplomat_dlg_window_callback;
1207   set_wstate(pWindow, FC_WS_NORMAL);
1208 
1209   add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW, pWindow);
1210   pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow;
1211 
1212   area = pWindow->area;
1213   area.h = MAX(area.h, adj_size(2));
1214 
1215   /* ---------- */
1216   /* exit button */
1217   pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
1218                           WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
1219   pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
1220                                            adj_font(12));
1221   area.w += pBuf->size.w + adj_size(10);
1222   pBuf->action = exit_spy_tgt_dlg_callback;
1223   set_wstate(pBuf, FC_WS_NORMAL);
1224   pBuf->key = SDLK_ESCAPE;
1225 
1226   add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf);
1227   /* ---------- */
1228 
1229   create_active_iconlabel(pBuf, pWindow->dst, pstr,
1230                           _("City Production"), sabotage_impr_callback);
1231   pBuf->data.cont = pCont;
1232   set_wstate(pBuf, FC_WS_NORMAL);
1233   set_wflag(pBuf, WF_FREE_DATA);
1234   add_to_gui_list(MAX_ID - 1000, pBuf);
1235 
1236   area.w = MAX(area.w, pBuf->size.w);
1237   area.h += pBuf->size.h;
1238 
1239   /* separator */
1240   pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME);
1241 
1242   add_to_gui_list(ID_SEPARATOR, pBuf);
1243   area.h += pBuf->next->size.h;
1244 
1245   pDiplomat_Dlg->pdialog->pEndActiveWidgetList = pBuf;
1246 
1247   /* ------------------ */
1248   n = 0;
1249   city_built_iterate(pCity, pImprove) {
1250     if (pImprove->sabotage > 0) {
1251       create_active_iconlabel(pBuf, pWindow->dst, pstr,
1252 	      (char *) city_improvement_name_translation(pCity, pImprove),
1253 				      sabotage_impr_callback);
1254       pBuf->data.cont = pCont;
1255       set_wstate(pBuf, FC_WS_NORMAL);
1256 
1257       add_to_gui_list(MAX_ID - improvement_number(pImprove), pBuf);
1258 
1259       area.w = MAX(area.w , pBuf->size.w);
1260       imp_h += pBuf->size.h;
1261 
1262       if (n > 9) {
1263         set_wflag(pBuf, WF_HIDDEN);
1264       }
1265 
1266       n++;
1267       /* ----------- */
1268     }
1269   } city_built_iterate_end;
1270 
1271   pDiplomat_Dlg->pdialog->pBeginActiveWidgetList = pBuf;
1272 
1273   if (n > 0 && action_prob_possible(
1274         actor->client.act_prob_cache[ACTION_SPY_SABOTAGE_CITY])) {
1275     /* separator */
1276     pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME);
1277 
1278     add_to_gui_list(ID_SEPARATOR, pBuf);
1279     area.h += pBuf->next->size.h;
1280   /* ------------------ */
1281   }
1282 
1283   if (action_prob_possible(
1284         actor->client.act_prob_cache[ACTION_SPY_SABOTAGE_CITY])) {
1285     struct astring str = ASTRING_INIT;
1286 
1287     /* TRANS: %s is a unit name, e.g., Spy */
1288     astr_set(&str, _("At %s's Discretion"), unit_name_translation(actor));
1289     create_active_iconlabel(pBuf, pWindow->dst, pstr, astr_str(&str),
1290                             sabotage_impr_callback);
1291     astr_free(&str);
1292 
1293     pBuf->data.cont = pCont;
1294     set_wstate(pBuf, FC_WS_NORMAL);
1295 
1296     add_to_gui_list(MAX_ID - B_LAST, pBuf);
1297 
1298     area.w = MAX(area.w, pBuf->size.w);
1299     area.h += pBuf->size.h;
1300   }
1301 
1302   /* ----------- */
1303 
1304   pLast = pBuf;
1305   pDiplomat_Dlg->pdialog->pBeginWidgetList = pLast;
1306   pDiplomat_Dlg->pdialog->pActiveWidgetList = pDiplomat_Dlg->pdialog->pEndActiveWidgetList;
1307 
1308   /* ---------- */
1309   if (n > 10) {
1310     imp_h = 10 * pBuf->size.h;
1311 
1312     n = create_vertical_scrollbar(pDiplomat_Dlg->pdialog,
1313                                   1, 10, TRUE, TRUE);
1314     area.w += n;
1315   } else {
1316     n = 0;
1317   }
1318   /* ---------- */
1319 
1320   area.h += imp_h;
1321 
1322   resize_window(pWindow, NULL, NULL,
1323                 (pWindow->size.w - pWindow->area.w) + area.w,
1324                 (pWindow->size.h - pWindow->area.h) + area.h);
1325 
1326   area = pWindow->area;
1327 
1328   auto_center_on_focus_unit();
1329   put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h,
1330                            unit_tile(actor));
1331 
1332   w = area.w;
1333 
1334   /* exit button */
1335   pBuf = pWindow->prev;
1336   pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
1337   pBuf->size.y = pWindow->size.y + adj_size(2);
1338 
1339   /* Production sabotage */
1340   pBuf = pBuf->prev;
1341 
1342   pBuf->size.x = area.x;
1343   pBuf->size.y = y = area.y + 1;
1344   pBuf->size.w = w;
1345   h = pBuf->size.h;
1346 
1347   area2.x = adj_size(10);
1348   area2.h = adj_size(2);
1349 
1350   pBuf = pBuf->prev;
1351   while (pBuf) {
1352     if (pBuf == pDiplomat_Dlg->pdialog->pEndActiveWidgetList) {
1353       w -= n;
1354     }
1355 
1356     pBuf->size.w = w;
1357     pBuf->size.x = pBuf->next->size.x;
1358     pBuf->size.y = y = y + pBuf->next->size.h;
1359 
1360     if (pBuf->ID == ID_SEPARATOR) {
1361       FREESURFACE(pBuf->theme);
1362       pBuf->size.h = h;
1363       pBuf->theme = create_surf(w, h, SDL_SWSURFACE);
1364 
1365       area2.y = pBuf->size.h / 2 - 1;
1366       area2.w = pBuf->size.w - adj_size(20);
1367 
1368       SDL_FillRect(pBuf->theme , &area2, map_rgba(pBuf->theme->format, *get_theme_color(COLOR_THEME_SABOTAGEDLG_SEPARATOR)));
1369     }
1370 
1371     if (pBuf == pLast) {
1372       break;
1373     }
1374 
1375     if (pBuf == pDiplomat_Dlg->pdialog->pBeginActiveWidgetList) {
1376       /* Reset to end of scrolling area */
1377       y = MIN(y, pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y
1378               + 9 * pBuf->size.h);
1379       w += n;
1380     }
1381     pBuf = pBuf->prev;
1382   }
1383 
1384   if (pDiplomat_Dlg->pdialog->pScroll) {
1385     setup_vertical_scrollbar_area(pDiplomat_Dlg->pdialog->pScroll,
1386         area.x + area.w,
1387         pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y,
1388         pDiplomat_Dlg->pdialog->pBeginActiveWidgetList->prev->size.y
1389           - pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y,
1390         TRUE);
1391   }
1392 
1393   /* -------------------- */
1394   /* redraw */
1395   redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, 0);
1396 
1397   widget_flush(pWindow);
1398 }
1399 
1400 /* ====================================================================== */
1401 /* ============================== INCITE DIALOG ========================= */
1402 /* ====================================================================== */
1403 static struct small_diplomat_dialog *pIncite_Dlg = NULL;
1404 
1405 /****************************************************************
1406   User interacted with Incite Revolt dialog window.
1407 *****************************************************************/
incite_dlg_window_callback(struct widget * pWindow)1408 static int incite_dlg_window_callback(struct widget *pWindow)
1409 {
1410   if (PRESSED_EVENT(Main.event)) {
1411     move_window_group(pIncite_Dlg->pdialog->pBeginWidgetList, pWindow);
1412   }
1413 
1414   return -1;
1415 }
1416 
1417 /****************************************************************
1418   User confirmed incite
1419 *****************************************************************/
diplomat_incite_yes_callback(struct widget * pWidget)1420 static int diplomat_incite_yes_callback(struct widget *pWidget)
1421 {
1422   if (PRESSED_EVENT(Main.event)) {
1423     if (NULL != game_unit_by_number(pIncite_Dlg->actor_unit_id)
1424         && NULL != game_city_by_number(pIncite_Dlg->target_id)) {
1425       request_do_action(ACTION_SPY_INCITE_CITY, pIncite_Dlg->actor_unit_id,
1426                         pIncite_Dlg->target_id, 0);
1427     }
1428 
1429     popdown_incite_dialog();
1430   }
1431 
1432   return -1;
1433 }
1434 
1435 /****************************************************************
1436   Close incite dialog.
1437 *****************************************************************/
exit_incite_dlg_callback(struct widget * pWidget)1438 static int exit_incite_dlg_callback(struct widget *pWidget)
1439 {
1440   if (PRESSED_EVENT(Main.event)) {
1441     popdown_incite_dialog();
1442   }
1443 
1444   return -1;
1445 }
1446 
1447 /**************************************************************************
1448   Popdown a window asking a diplomatic unit if it wishes to incite the
1449   given enemy city.
1450 **************************************************************************/
popdown_incite_dialog(void)1451 void popdown_incite_dialog(void)
1452 {
1453   if (pIncite_Dlg) {
1454     act_sel_done_secondary(pIncite_Dlg->actor_unit_id);
1455 
1456     is_unit_move_blocked = FALSE;
1457     popdown_window_group_dialog(pIncite_Dlg->pdialog->pBeginWidgetList,
1458 				pIncite_Dlg->pdialog->pEndWidgetList);
1459     FC_FREE(pIncite_Dlg->pdialog);
1460     FC_FREE(pIncite_Dlg);
1461     flush_dirty();
1462   }
1463 }
1464 
1465 /**************************************************************************
1466   Popup a window asking a diplomatic unit if it wishes to incite the
1467   given enemy city.
1468 **************************************************************************/
popup_incite_dialog(struct unit * actor,struct city * pCity,int cost)1469 void popup_incite_dialog(struct unit *actor, struct city *pCity, int cost)
1470 {
1471   struct widget *pWindow = NULL, *pBuf = NULL;
1472   utf8_str *pstr;
1473   char tBuf[255], cBuf[255];
1474   bool exit = FALSE;
1475   SDL_Rect area;
1476 
1477   if (pIncite_Dlg) {
1478     return;
1479   }
1480 
1481   /* Should be set before sending request to the server. */
1482   fc_assert(is_more_user_input_needed);
1483 
1484   if (!actor || !unit_can_do_action(actor, ACTION_SPY_INCITE_CITY)) {
1485     act_sel_done_secondary(actor ? actor->id : IDENTITY_NUMBER_ZERO);
1486     return;
1487   }
1488 
1489   is_unit_move_blocked = TRUE;
1490 
1491   pIncite_Dlg = fc_calloc(1, sizeof(struct small_diplomat_dialog));
1492   pIncite_Dlg->actor_unit_id = actor->id;
1493   pIncite_Dlg->target_id = pCity->id;
1494   pIncite_Dlg->pdialog = fc_calloc(1, sizeof(struct SMALL_DLG));
1495 
1496   fc_snprintf(tBuf, ARRAY_SIZE(tBuf), PL_("Treasury contains %d gold.",
1497                                           "Treasury contains %d gold.",
1498                                           client_player()->economic.gold),
1499               client_player()->economic.gold);
1500 
1501   /* window */
1502   pstr = create_utf8_from_char(_("Incite a Revolt!"), adj_font(12));
1503 
1504   pstr->style |= TTF_STYLE_BOLD;
1505 
1506   pWindow = create_window_skeleton(NULL, pstr, 0);
1507 
1508   pWindow->action = incite_dlg_window_callback;
1509   set_wstate(pWindow, FC_WS_NORMAL);
1510 
1511   add_to_gui_list(ID_INCITE_DLG_WINDOW, pWindow);
1512   pIncite_Dlg->pdialog->pEndWidgetList = pWindow;
1513 
1514   area = pWindow->area;
1515   area.w  =MAX(area.w, adj_size(8));
1516   area.h = MAX(area.h, adj_size(2));
1517 
1518   if (INCITE_IMPOSSIBLE_COST == cost) {
1519     /* exit button */
1520     pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
1521                             WF_WIDGET_HAS_INFO_LABEL
1522                             | WF_RESTORE_BACKGROUND);
1523     pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
1524                                              adj_font(12));
1525     area.w += pBuf->size.w + adj_size(10);
1526     pBuf->action = exit_incite_dlg_callback;
1527     set_wstate(pBuf, FC_WS_NORMAL);
1528     pBuf->key = SDLK_ESCAPE;
1529 
1530     add_to_gui_list(ID_INCITE_DLG_EXIT_BUTTON, pBuf);
1531     exit = TRUE;
1532     /* --------------- */
1533 
1534     fc_snprintf(cBuf, sizeof(cBuf), _("You can't incite a revolt in %s."),
1535                 city_name_get(pCity));
1536 
1537     create_active_iconlabel(pBuf, pWindow->dst, pstr, cBuf, NULL);
1538 
1539     add_to_gui_list(ID_LABEL , pBuf);
1540 
1541     area.w = MAX(area.w , pBuf->size.w);
1542     area.h += pBuf->size.h;
1543     /*------------*/
1544     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1545                             _("City can't be incited!"), NULL);
1546 
1547     add_to_gui_list(ID_LABEL, pBuf);
1548 
1549     area.w = MAX(area.w, pBuf->size.w);
1550     area.h += pBuf->size.h;
1551 
1552   } else if (cost <= client_player()->economic.gold) {
1553     fc_snprintf(cBuf, sizeof(cBuf),
1554                 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
1555                 PL_("Incite a revolt for %d gold?\n%s",
1556                     "Incite a revolt for %d gold?\n%s", cost), cost, tBuf);
1557 
1558     create_active_iconlabel(pBuf, pWindow->dst, pstr, cBuf, NULL);
1559 
1560     add_to_gui_list(ID_LABEL, pBuf);
1561 
1562     area.w = MAX(area.w, pBuf->size.w);
1563     area.h += pBuf->size.h;
1564 
1565     /*------------*/
1566     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1567                             _("Yes") , diplomat_incite_yes_callback);
1568 
1569     pBuf->data.city = pCity;
1570     set_wstate(pBuf, FC_WS_NORMAL);
1571 
1572     add_to_gui_list(MAX_ID - actor->id, pBuf);
1573 
1574     area.w = MAX(area.w, pBuf->size.w);
1575     area.h += pBuf->size.h;
1576     /* ------- */
1577     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1578                             _("No") , exit_incite_dlg_callback);
1579 
1580     set_wstate(pBuf, FC_WS_NORMAL);
1581     pBuf->key = SDLK_ESCAPE;
1582 
1583     add_to_gui_list(ID_LABEL, pBuf);
1584 
1585     area.w = MAX(area.w, pBuf->size.w);
1586     area.h += pBuf->size.h;
1587 
1588   } else {
1589     /* exit button */
1590     pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
1591                             WF_WIDGET_HAS_INFO_LABEL
1592                             | WF_RESTORE_BACKGROUND);
1593     pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
1594                                              adj_font(12));
1595     area.w += pBuf->size.w + adj_size(10);
1596     pBuf->action = exit_incite_dlg_callback;
1597     set_wstate(pBuf, FC_WS_NORMAL);
1598     pBuf->key = SDLK_ESCAPE;
1599 
1600     add_to_gui_list(ID_INCITE_DLG_EXIT_BUTTON, pBuf);
1601     exit = TRUE;
1602     /* --------------- */
1603 
1604     fc_snprintf(cBuf, sizeof(cBuf),
1605                 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
1606                 PL_("Inciting a revolt costs %d gold.\n%s",
1607                     "Inciting a revolt costs %d gold.\n%s", cost), cost, tBuf);
1608 
1609     create_active_iconlabel(pBuf, pWindow->dst, pstr, cBuf, NULL);
1610 
1611     add_to_gui_list(ID_LABEL, pBuf);
1612 
1613     area.w = MAX(area.w, pBuf->size.w);
1614     area.h += pBuf->size.h;
1615 
1616     /*------------*/
1617     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1618                             _("Traitors Demand Too Much!"), NULL);
1619 
1620     add_to_gui_list(ID_LABEL, pBuf);
1621 
1622     area.w = MAX(area.w, pBuf->size.w);
1623     area.h += pBuf->size.h;
1624   }
1625   pIncite_Dlg->pdialog->pBeginWidgetList = pBuf;
1626 
1627   /* setup window size and start position */
1628 
1629   resize_window(pWindow, NULL, NULL,
1630                 (pWindow->size.w - pWindow->area.w) + area.w,
1631                 (pWindow->size.h - pWindow->area.h) + area.h);
1632 
1633   area = pWindow->area;
1634 
1635   auto_center_on_focus_unit();
1636   put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h,
1637                            pCity->tile);
1638 
1639   /* setup widget size and start position */
1640   pBuf = pWindow;
1641 
1642   if (exit) {
1643     /* exit button */
1644     pBuf = pBuf->prev;
1645     pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
1646     pBuf->size.y = pWindow->size.y + adj_size(2);
1647   }
1648 
1649   pBuf = pBuf->prev;
1650   setup_vertical_widgets_position(1,
1651 	area.x,
1652   	area.y + 1, area.w, 0,
1653 	pIncite_Dlg->pdialog->pBeginWidgetList, pBuf);
1654 
1655   /* --------------------- */
1656   /* redraw */
1657   redraw_group(pIncite_Dlg->pdialog->pBeginWidgetList, pWindow, 0);
1658 
1659   widget_flush(pWindow);
1660 }
1661 
1662 /* ====================================================================== */
1663 /* ============================ BRIBE DIALOG ========================== */
1664 /* ====================================================================== */
1665 static struct small_diplomat_dialog *pBribe_Dlg = NULL;
1666 
1667 /**************************************************************************
1668   User interacted with bribe dialog window.
1669 **************************************************************************/
bribe_dlg_window_callback(struct widget * pWindow)1670 static int bribe_dlg_window_callback(struct widget *pWindow)
1671 {
1672   if (PRESSED_EVENT(Main.event)) {
1673     move_window_group(pBribe_Dlg->pdialog->pBeginWidgetList, pWindow);
1674   }
1675 
1676   return -1;
1677 }
1678 
1679 /**************************************************************************
1680   User confirmed bribe.
1681 **************************************************************************/
diplomat_bribe_yes_callback(struct widget * pWidget)1682 static int diplomat_bribe_yes_callback(struct widget *pWidget)
1683 {
1684   if (PRESSED_EVENT(Main.event)) {
1685     if (NULL != game_unit_by_number(pBribe_Dlg->actor_unit_id)
1686         && NULL != game_unit_by_number(pBribe_Dlg->target_id)) {
1687       request_do_action(ACTION_SPY_BRIBE_UNIT, pBribe_Dlg->actor_unit_id,
1688                         pBribe_Dlg->target_id, 0);
1689     }
1690     popdown_bribe_dialog();
1691   }
1692 
1693   return -1;
1694 }
1695 
1696 /**************************************************************************
1697   Close bribe dialog.
1698 **************************************************************************/
exit_bribe_dlg_callback(struct widget * pWidget)1699 static int exit_bribe_dlg_callback(struct widget *pWidget)
1700 {
1701   if (PRESSED_EVENT(Main.event)) {
1702     popdown_bribe_dialog();
1703   }
1704 
1705   return -1;
1706 }
1707 
1708 /**************************************************************************
1709   Popdown a dialog asking a diplomatic unit if it wishes to bribe the
1710   given enemy unit.
1711 **************************************************************************/
popdown_bribe_dialog(void)1712 void popdown_bribe_dialog(void)
1713 {
1714   if (pBribe_Dlg) {
1715     act_sel_done_secondary(pBribe_Dlg->actor_unit_id);
1716 
1717     is_unit_move_blocked = FALSE;
1718     popdown_window_group_dialog(pBribe_Dlg->pdialog->pBeginWidgetList,
1719                                 pBribe_Dlg->pdialog->pEndWidgetList);
1720     FC_FREE(pBribe_Dlg->pdialog);
1721     FC_FREE(pBribe_Dlg);
1722     flush_dirty();
1723   }
1724 }
1725 
1726 /**************************************************************************
1727   Popup a dialog asking a diplomatic unit if it wishes to bribe the
1728   given enemy unit.
1729 **************************************************************************/
popup_bribe_dialog(struct unit * actor,struct unit * pUnit,int cost)1730 void popup_bribe_dialog(struct unit *actor, struct unit *pUnit, int cost)
1731 {
1732   struct widget *pWindow = NULL, *pBuf = NULL;
1733   utf8_str *pstr;
1734   char tBuf[255], cBuf[255];
1735   bool exit = FALSE;
1736   SDL_Rect area;
1737 
1738   if (pBribe_Dlg) {
1739     return;
1740   }
1741 
1742   /* Should be set before sending request to the server. */
1743   fc_assert(is_more_user_input_needed);
1744 
1745   if (!actor || !unit_can_do_action(actor, ACTION_SPY_BRIBE_UNIT)) {
1746     act_sel_done_secondary(actor ? actor->id : IDENTITY_NUMBER_ZERO);
1747     return;
1748   }
1749 
1750   is_unit_move_blocked = TRUE;
1751 
1752   pBribe_Dlg = fc_calloc(1, sizeof(struct small_diplomat_dialog));
1753   pBribe_Dlg->actor_unit_id = actor->id;
1754   pBribe_Dlg->target_id = pUnit->id;
1755   pBribe_Dlg->pdialog = fc_calloc(1, sizeof(struct SMALL_DLG));
1756 
1757   fc_snprintf(tBuf, ARRAY_SIZE(tBuf), PL_("Treasury contains %d gold.",
1758                                           "Treasury contains %d gold.",
1759                                           client_player()->economic.gold),
1760               client_player()->economic.gold);
1761 
1762   /* window */
1763   pstr = create_utf8_from_char(_("Bribe Enemy Unit"), adj_font(12));
1764 
1765   pstr->style |= TTF_STYLE_BOLD;
1766 
1767   pWindow = create_window_skeleton(NULL, pstr, 0);
1768 
1769   pWindow->action = bribe_dlg_window_callback;
1770   set_wstate(pWindow, FC_WS_NORMAL);
1771 
1772   add_to_gui_list(ID_BRIBE_DLG_WINDOW, pWindow);
1773   pBribe_Dlg->pdialog->pEndWidgetList = pWindow;
1774 
1775   area = pWindow->area;
1776   area.w = MAX(area.w, adj_size(8));
1777   area.h = MAX(area.h, adj_size(2));
1778 
1779   if (cost <= client_player()->economic.gold) {
1780     fc_snprintf(cBuf, sizeof(cBuf),
1781                 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
1782                 PL_("Bribe unit for %d gold?\n%s",
1783                     "Bribe unit for %d gold?\n%s", cost), cost, tBuf);
1784 
1785     create_active_iconlabel(pBuf, pWindow->dst, pstr, cBuf, NULL);
1786 
1787     add_to_gui_list(ID_LABEL, pBuf);
1788 
1789     area.w = MAX(area.w, pBuf->size.w);
1790     area.h += pBuf->size.h;
1791 
1792     /*------------*/
1793     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1794                             _("Yes"), diplomat_bribe_yes_callback);
1795     pBuf->data.unit = pUnit;
1796     set_wstate(pBuf, FC_WS_NORMAL);
1797 
1798     add_to_gui_list(MAX_ID - actor->id, pBuf);
1799 
1800     area.w = MAX(area.w, pBuf->size.w);
1801     area.h += pBuf->size.h;
1802     /* ------- */
1803     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1804                             _("No") , exit_bribe_dlg_callback);
1805 
1806     set_wstate(pBuf, FC_WS_NORMAL);
1807     pBuf->key = SDLK_ESCAPE;
1808 
1809     add_to_gui_list(ID_LABEL, pBuf);
1810 
1811     area.w = MAX(area.w, pBuf->size.w);
1812     area.h += pBuf->size.h;
1813 
1814   } else {
1815     /* exit button */
1816     pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
1817                             WF_WIDGET_HAS_INFO_LABEL
1818                             | WF_RESTORE_BACKGROUND);
1819     pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
1820                                              adj_font(12));
1821     area.w += pBuf->size.w + adj_size(10);
1822     pBuf->action = exit_bribe_dlg_callback;
1823     set_wstate(pBuf, FC_WS_NORMAL);
1824     pBuf->key = SDLK_ESCAPE;
1825 
1826     add_to_gui_list(ID_BRIBE_DLG_EXIT_BUTTON, pBuf);
1827     exit = TRUE;
1828     /* --------------- */
1829 
1830     fc_snprintf(cBuf, sizeof(cBuf),
1831                 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
1832                 PL_("Bribing the unit costs %d gold.\n%s",
1833                     "Bribing the unit costs %d gold.\n%s", cost), cost, tBuf);
1834 
1835     create_active_iconlabel(pBuf, pWindow->dst, pstr, cBuf, NULL);
1836 
1837     add_to_gui_list(ID_LABEL, pBuf);
1838 
1839     area.w = MAX(area.w, pBuf->size.w);
1840     area.h += pBuf->size.h;
1841 
1842     /*------------*/
1843     create_active_iconlabel(pBuf, pWindow->dst, pstr,
1844                             _("Traitors Demand Too Much!"), NULL);
1845 
1846     add_to_gui_list(ID_LABEL, pBuf);
1847 
1848     area.w = MAX(area.w, pBuf->size.w);
1849     area.h += pBuf->size.h;
1850   }
1851   pBribe_Dlg->pdialog->pBeginWidgetList = pBuf;
1852 
1853   /* setup window size and start position */
1854 
1855   resize_window(pWindow, NULL, NULL,
1856                 (pWindow->size.w - pWindow->area.w) + area.w,
1857                 (pWindow->size.h - pWindow->area.h) + area.h);
1858 
1859   area = pWindow->area;
1860 
1861   auto_center_on_focus_unit();
1862   put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h,
1863                            unit_tile(actor));
1864 
1865   /* setup widget size and start position */
1866   pBuf = pWindow;
1867 
1868   if (exit) {
1869     /* exit button */
1870     pBuf = pBuf->prev;
1871     pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
1872     pBuf->size.y = pWindow->size.y + adj_size(2);
1873   }
1874 
1875   pBuf = pBuf->prev;
1876   setup_vertical_widgets_position(1,
1877 	area.x,
1878   	area.y + 1, area.w, 0,
1879 	pBribe_Dlg->pdialog->pBeginWidgetList, pBuf);
1880 
1881   /* --------------------- */
1882   /* redraw */
1883   redraw_group(pBribe_Dlg->pdialog->pBeginWidgetList, pWindow, 0);
1884 
1885   widget_flush(pWindow);
1886 }
1887