Freeciv21
Develop your civilization from humble roots to a global empire
dialogs.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 #include "dialogs.h"
12 // Qt
13 #include <QApplication>
14 #include <QComboBox>
15 #include <QGroupBox>
16 #include <QHeaderView>
17 #include <QKeyEvent>
18 #include <QPainter>
19 #include <QRadioButton>
20 #include <QRandomGenerator>
21 #include <QVBoxLayout>
22 #include <QtMath>
23 // utility
24 #include "astring.h"
25 #include "fcintl.h"
26 // common
27 #include "actions.h"
28 #include "city.h"
29 #include "climisc.h"
30 #include "game.h"
31 #include "government.h"
32 #include "improvement.h"
33 #include "movement.h"
34 #include "nation.h"
35 #include "research.h"
36 #include "style.h"
37 // client
38 #include "audio/audio.h"
39 #include "chatline_common.h"
40 #include "client_main.h"
41 #include "control.h"
42 #include "fc_client.h"
43 #include "fonts.h"
44 #include "helpdlg.h"
45 #include "hudwidget.h"
46 #include "icons.h"
47 #include "packhand.h"
48 #include "page_game.h"
49 #include "qtg_cxxside.h"
50 #include "text.h"
51 #include "tileset/layer_city.h"
52 #include "tileset/tilespec.h"
53 #include "unithudselector.h"
54 #include "unitselect.h"
55 #include "views/view_map.h"
56 #include "views/view_map_common.h"
57 #include "widgets/report_widget.h"
58 
59 // Locations for non action enabler controlled buttons.
60 #define BUTTON_MOVE ACTION_COUNT
61 #define BUTTON_WAIT BUTTON_MOVE + 1
62 #define BUTTON_CANCEL BUTTON_MOVE + 2
63 #define BUTTON_COUNT BUTTON_MOVE + 3
64 
65 extern void popdown_all_spaceships_dialogs();
66 extern void popdown_players_report();
67 extern void popdown_economy_report();
68 extern void popdown_science_report();
69 extern void popdown_city_report();
70 extern void popdown_endgame_report();
71 
72 static void act_sel_keep_moving(QVariant data1, QVariant data2);
73 static void spy_request_strike_bld_list(QVariant data1, QVariant data2);
74 static void diplomat_incite(QVariant data1, QVariant data2);
75 static void diplomat_incite_escape(QVariant data1, QVariant data2);
76 static void spy_request_sabotage_list(QVariant data1, QVariant data2);
77 static void spy_request_sabotage_esc_list(QVariant data1, QVariant data2);
78 static void spy_sabotage(QVariant data1, QVariant data2);
79 static void spy_steal(QVariant data1, QVariant data2);
80 static void spy_steal_esc(QVariant data1, QVariant data2);
81 static void spy_steal_something(QVariant data1, QVariant data2);
82 static void diplomat_steal(QVariant data1, QVariant data2);
83 static void diplomat_steal_esc(QVariant data1, QVariant data2);
84 static void spy_poison(QVariant data1, QVariant data2);
85 static void spy_poison_esc(QVariant data1, QVariant data2);
86 static void spy_steal_gold(QVariant data1, QVariant data2);
87 static void spy_steal_gold_esc(QVariant data1, QVariant data2);
88 static void spy_steal_maps(QVariant data1, QVariant data2);
89 static void spy_steal_maps_esc(QVariant data1, QVariant data2);
90 static void spy_nuke_city(QVariant data1, QVariant data2);
91 static void spy_nuke_city_esc(QVariant data1, QVariant data2);
92 static void nuke_city(QVariant data1, QVariant data2);
93 static void destroy_city(QVariant data1, QVariant data2);
94 static void diplomat_embassy(QVariant data1, QVariant data2);
95 static void spy_embassy(QVariant data1, QVariant data2);
96 static void spy_sabotage_unit(QVariant data1, QVariant data2);
97 static void spy_sabotage_unit_esc(QVariant data1, QVariant data2);
98 static void spy_investigate(QVariant data1, QVariant data2);
99 static void diplomat_investigate(QVariant data1, QVariant data2);
100 static void diplomat_sabotage(QVariant data1, QVariant data2);
101 static void diplomat_sabotage_esc(QVariant data1, QVariant data2);
102 static void diplomat_bribe(QVariant data1, QVariant data2);
103 static void caravan_marketplace(QVariant data1, QVariant data2);
104 static void caravan_establish_trade(QVariant data1, QVariant data2);
105 static void caravan_help_build(QVariant data1, QVariant data2);
106 static void unit_recycle(QVariant data1, QVariant data2);
107 static void capture_units(QVariant data1, QVariant data2);
108 static void nuke_units(QVariant data1, QVariant data2);
109 static void expel_unit(QVariant data1, QVariant data2);
110 static void bombard(QVariant data1, QVariant data2);
111 static void bombard2(QVariant data1, QVariant data2);
112 static void bombard3(QVariant data1, QVariant data2);
113 static void found_city(QVariant data1, QVariant data2);
114 static void transform_terrain(QVariant data1, QVariant data2);
115 static void cultivate(QVariant data1, QVariant data2);
116 static void plant(QVariant data1, QVariant data2);
117 static void pillage(QVariant data1, QVariant data2);
118 static void clean_pollution(QVariant data1, QVariant data2);
119 static void clean_fallout(QVariant data1, QVariant data2);
120 static void road(QVariant data1, QVariant data2);
121 static void base(QVariant data1, QVariant data2);
122 static void mine(QVariant data1, QVariant data2);
123 static void irrigate(QVariant data1, QVariant data2);
124 static void nuke(QVariant data1, QVariant data2);
125 static void attack(QVariant data1, QVariant data2);
126 static void suicide_attack(QVariant data1, QVariant data2);
127 static void paradrop(QVariant data1, QVariant data2);
128 static void disembark1(QVariant data1, QVariant data2);
129 static void disembark2(QVariant data1, QVariant data2);
130 static void convert_unit(QVariant data1, QVariant data2);
131 static void fortify(QVariant data1, QVariant data2);
132 static void disband_unit(QVariant data1, QVariant data2);
133 static void join_city(QVariant data1, QVariant data2);
134 static void unit_home_city(QVariant data1, QVariant data2);
135 static void unit_upgrade(QVariant data1, QVariant data2);
136 static void airlift(QVariant data1, QVariant data2);
137 static void conquer_city(QVariant data1, QVariant data2);
138 static void conquer_city2(QVariant data1, QVariant data2);
139 static void heal_unit(QVariant data1, QVariant data2);
140 static void transport_board(QVariant data1, QVariant data2);
141 static void transport_embark(QVariant data1, QVariant data2);
142 static void transport_alight(QVariant data1, QVariant data2);
143 static void transport_unload(QVariant data1, QVariant data2);
144 static void keep_moving(QVariant data1, QVariant data2);
145 static void pillage_something(QVariant data1, QVariant data2);
146 static void user_action_1(QVariant data1, QVariant data2);
147 static void user_action_2(QVariant data1, QVariant data2);
148 static void user_action_3(QVariant data1, QVariant data2);
149 static void action_entry(choice_dialog *cd, action_id act,
150  const struct act_prob *act_probs,
151  const QString custom, QVariant data1,
152  QVariant data2);
153 
154 static bool is_showing_pillage_dialog = false;
156 static bool is_race_dialog_open = false;
157 
158 /* Information used in action selection follow up questions. Can't be
159  * stored in the action selection dialog since it is closed before the
160  * follow up question is asked. */
161 static bool is_more_user_input_needed = false;
162 
163 /* Don't remove a unit's action decision want or move on to the next actor
164  unit that wants a decision in the current unit selection. */
165 static bool did_not_decide = false;
166 
167 extern QString forced_tileset_name;
168 qdef_act *qdef_act::m_instance = nullptr;
169 
174 static const QHash<action_id, pfcn_void> af_map_init()
175 {
176  QHash<action_id, pfcn_void> action_function;
177 
178  // Unit acting against a city target.
179  action_function[ACTION_ESTABLISH_EMBASSY] = spy_embassy;
180  action_function[ACTION_ESTABLISH_EMBASSY_STAY] = diplomat_embassy;
181  action_function[ACTION_SPY_INVESTIGATE_CITY] = spy_investigate;
182  action_function[ACTION_INV_CITY_SPEND] = diplomat_investigate;
183  action_function[ACTION_SPY_POISON] = spy_poison;
184  action_function[ACTION_SPY_POISON_ESC] = spy_poison_esc;
185  action_function[ACTION_SPY_STEAL_GOLD] = spy_steal_gold;
186  action_function[ACTION_SPY_STEAL_GOLD_ESC] = spy_steal_gold_esc;
187  action_function[ACTION_SPY_SABOTAGE_CITY] = diplomat_sabotage;
188  action_function[ACTION_SPY_SABOTAGE_CITY_ESC] = diplomat_sabotage_esc;
189  action_function[ACTION_SPY_TARGETED_SABOTAGE_CITY] =
191  action_function[ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
193  action_function[ACTION_SPY_STEAL_TECH] = diplomat_steal;
194  action_function[ACTION_SPY_STEAL_TECH_ESC] = diplomat_steal_esc;
195  action_function[ACTION_SPY_TARGETED_STEAL_TECH] = spy_steal;
196  action_function[ACTION_SPY_TARGETED_STEAL_TECH_ESC] = spy_steal_esc;
197  action_function[ACTION_SPY_INCITE_CITY] = diplomat_incite;
198  action_function[ACTION_SPY_INCITE_CITY_ESC] = diplomat_incite_escape;
199  action_function[ACTION_TRADE_ROUTE] = caravan_establish_trade;
200  action_function[ACTION_MARKETPLACE] = caravan_marketplace;
201  action_function[ACTION_HELP_WONDER] = caravan_help_build;
202  action_function[ACTION_JOIN_CITY] = join_city;
203  action_function[ACTION_STEAL_MAPS] = spy_steal_maps;
204  action_function[ACTION_STEAL_MAPS_ESC] = spy_steal_maps_esc;
205  action_function[ACTION_SPY_NUKE] = spy_nuke_city;
206  action_function[ACTION_SPY_NUKE_ESC] = spy_nuke_city_esc;
207  action_function[ACTION_DESTROY_CITY] = destroy_city;
208  action_function[ACTION_RECYCLE_UNIT] = unit_recycle;
209  action_function[ACTION_HOME_CITY] = unit_home_city;
210  action_function[ACTION_UPGRADE_UNIT] = unit_upgrade;
211  action_function[ACTION_AIRLIFT] = airlift;
212  action_function[ACTION_CONQUER_CITY] = conquer_city;
213  action_function[ACTION_CONQUER_CITY2] = conquer_city2;
214  action_function[ACTION_STRIKE_BUILDING] = spy_request_strike_bld_list;
215  action_function[ACTION_NUKE_CITY] = nuke_city;
216 
217  // Unit acting against a unit target.
218  action_function[ACTION_SPY_BRIBE_UNIT] = diplomat_bribe;
219  action_function[ACTION_SPY_SABOTAGE_UNIT] = spy_sabotage_unit;
220  action_function[ACTION_SPY_SABOTAGE_UNIT_ESC] = spy_sabotage_unit_esc;
221  action_function[ACTION_EXPEL_UNIT] = expel_unit;
222  action_function[ACTION_HEAL_UNIT] = heal_unit;
223  action_function[ACTION_TRANSPORT_ALIGHT] = transport_alight;
224  action_function[ACTION_TRANSPORT_UNLOAD] = transport_unload;
225  action_function[ACTION_TRANSPORT_BOARD] = transport_board;
226  action_function[ACTION_TRANSPORT_EMBARK] = transport_embark;
227 
228  // Unit acting against all units at a tile.
229  action_function[ACTION_CAPTURE_UNITS] = capture_units;
230  action_function[ACTION_BOMBARD] = bombard;
231  action_function[ACTION_BOMBARD2] = bombard2;
232  action_function[ACTION_BOMBARD3] = bombard3;
233  action_function[ACTION_NUKE_UNITS] = nuke_units;
234 
235  // Unit acting against a tile.
236  action_function[ACTION_FOUND_CITY] = found_city;
237  action_function[ACTION_NUKE] = nuke;
238  action_function[ACTION_PARADROP] = paradrop;
239  action_function[ACTION_ATTACK] = attack;
240  action_function[ACTION_SUICIDE_ATTACK] = suicide_attack;
241  action_function[ACTION_TRANSFORM_TERRAIN] = transform_terrain;
242  action_function[ACTION_CULTIVATE] = cultivate;
243  action_function[ACTION_PLANT] = plant;
244  action_function[ACTION_PILLAGE] = pillage;
245  action_function[ACTION_CLEAN_POLLUTION] = clean_pollution;
246  action_function[ACTION_CLEAN_FALLOUT] = clean_fallout;
247  action_function[ACTION_ROAD] = road;
248  action_function[ACTION_BASE] = base;
249  action_function[ACTION_MINE] = mine;
250  action_function[ACTION_IRRIGATE] = irrigate;
251  action_function[ACTION_TRANSPORT_DISEMBARK1] = disembark1;
252  action_function[ACTION_TRANSPORT_DISEMBARK2] = disembark2;
253 
254  // Unit acting with no target except itself.
255  action_function[ACTION_DISBAND_UNIT] = disband_unit;
256  action_function[ACTION_FORTIFY] = fortify;
257  action_function[ACTION_CONVERT] = convert_unit;
258 
259  // Unit target depends on ruleset
260  action_function[ACTION_USER_ACTION1] = user_action_1;
261  action_function[ACTION_USER_ACTION2] = user_action_2;
262  action_function[ACTION_USER_ACTION3] = user_action_3;
263 
264  return action_function;
265 }
266 
267 /* Mapping from an action to the function to call when its button is
268  * pushed. */
269 static const QHash<action_id, pfcn_void> af_map = af_map_init();
270 
274 qfc_dialog::qfc_dialog(QWidget *parent)
275  : QDialog(parent, Qt::FramelessWindowHint)
276 {
277  titlebar_height = 0;
278  moving_now = false;
279  setSizeGripEnabled(true);
280  close_pix = fcIcons::instance()->getPixmap(QStringLiteral("cclose"));
281 }
282 
284 
288 void qfc_dialog::paintEvent(QPaintEvent *event)
289 {
290  Q_UNUSED(event)
291 
292  QPainter p(this);
293  QStyleOptionTitleBar tbar_opt;
294  QStyleOption win_opt;
295  QStyle *style = this->style();
296  QRect active_area = this->rect();
297  QPalette qpal;
298  QRect close_rect, text_rect;
299 
300  qpal.setColor(QPalette::Active, QPalette::ToolTipText, Qt::white);
301  tbar_opt.initFrom(this);
303  style->pixelMetric(QStyle::PM_TitleBarHeight, &tbar_opt, this) + 2;
304  QPixmap *old = close_pix;
305  close_pix = new QPixmap(close_pix->scaledToHeight(titlebar_height));
306  delete old;
307  tbar_opt.rect = QRect(0, 0, this->width(), titlebar_height);
308  text_rect =
309  QRect(0, 0, this->width() - close_pix->width(), titlebar_height);
310  close_rect = QRect(this->width() - close_pix->width(), 0, this->width(),
312  tbar_opt.titleBarState = this->windowState();
313  tbar_opt.text = tbar_opt.fontMetrics.elidedText(
314  this->windowTitle(), Qt::ElideRight, text_rect.width());
315  style->drawComplexControl(QStyle::CC_TitleBar, &tbar_opt, &p, this);
316  style->drawItemText(&p, text_rect, Qt::AlignCenter, qpal, true,
317  tbar_opt.text, QPalette::ToolTipText);
318  style->drawItemPixmap(&p, close_rect, Qt::AlignLeft,
319  close_pix->scaledToHeight(titlebar_height));
320 
321  active_area.setTopLeft(QPoint(0, titlebar_height));
322  this->setContentsMargins(0, titlebar_height, 0, 0);
323  win_opt.initFrom(this);
324  win_opt.rect = active_area;
325  style->drawPrimitive(QStyle::PE_Widget, &win_opt, &p, this);
326 }
327 
332 {
333  if (moving_now) {
334  move(event->globalPos() - point);
335  }
336 }
337 
342 {
343  if (event->pos().y() <= titlebar_height
344  && event->pos().x() <= width() - close_pix->width()) {
345  point = event->globalPos() - geometry().topLeft();
346  moving_now = true;
347  setCursor(Qt::SizeAllCursor);
348  } else if (event->pos().y() <= titlebar_height
349  && event->pos().x() > width() - close_pix->width()) {
350  close();
351  }
352 }
353 
358 {
359  Q_UNUSED(event)
360  moving_now = false;
361  setCursor(Qt::ArrowCursor);
362 }
363 
367 races_dialog::races_dialog(struct player *pplayer, QWidget *parent)
368  : qfc_dialog(parent), nations_tabs_list(nullptr)
369 {
370  int i;
371  QGridLayout *qgroupbox_layout;
372  QGroupBox *no_name;
373  QTableWidgetItem *item;
374  QHeaderView *header;
375  QString title;
376  QLabel *ns_label;
377 
378  setAttribute(Qt::WA_DeleteOnClose);
379  is_race_dialog_open = true;
380  main_layout = new QGridLayout;
381  selected_nation_tabs = new QTableWidget;
382  nation_tabs = new QTableWidget();
383  styles = new QTableWidget;
384  ok_button = new QPushButton;
385  qnation_set = new QComboBox;
386  ns_label = new QLabel;
387  tplayer = pplayer;
388 
389  selected_nation = -1;
390  selected_style = -1;
391  setWindowTitle(_("Select Nation"));
392  selected_nation_tabs->setRowCount(0);
393  selected_nation_tabs->setColumnCount(1);
394  selected_nation_tabs->setSelectionMode(QAbstractItemView::SingleSelection);
395  selected_nation_tabs->verticalHeader()->setVisible(false);
396  selected_nation_tabs->horizontalHeader()->setVisible(false);
397  selected_nation_tabs->setProperty("showGrid", "true");
398  selected_nation_tabs->setEditTriggers(QAbstractItemView::NoEditTriggers);
399  selected_nation_tabs->setShowGrid(false);
400  selected_nation_tabs->setAlternatingRowColors(true);
401 
402  nation_tabs->setRowCount(0);
403  nation_tabs->setColumnCount(1);
404  nation_tabs->setSelectionMode(QAbstractItemView::SingleSelection);
405  nation_tabs->verticalHeader()->setVisible(false);
406  nation_tabs->horizontalHeader()->setVisible(false);
407  nation_tabs->setProperty("showGrid", "true");
408  nation_tabs->setEditTriggers(QAbstractItemView::NoEditTriggers);
409  nation_tabs->setShowGrid(false);
410  ns_label->setText(_("Nation Set:"));
411  styles->setRowCount(0);
412  styles->setColumnCount(2);
413  styles->setSelectionMode(QAbstractItemView::SingleSelection);
414  styles->verticalHeader()->setVisible(false);
415  styles->horizontalHeader()->setVisible(false);
416  styles->setProperty("showGrid", "false");
417  styles->setProperty("selectionBehavior", "SelectRows");
418  styles->setEditTriggers(QAbstractItemView::NoEditTriggers);
419  styles->setShowGrid(false);
420 
421  qgroupbox_layout = new QGridLayout;
422  no_name = new QGroupBox(parent);
423  leader_name = new QComboBox(no_name);
424  is_male = new QRadioButton(no_name);
425  is_female = new QRadioButton(no_name);
426 
427  leader_name->setEditable(true);
428  qgroupbox_layout->addWidget(leader_name, 1, 0, 1, 2);
429  qgroupbox_layout->addWidget(is_male, 2, 1);
430  qgroupbox_layout->addWidget(is_female, 2, 0);
431  is_female->setText(_("Female"));
432  is_male->setText(_("Male"));
433  // Select a default fairly
434  is_male->setChecked(QRandomGenerator::global()->generate() % 2 == 0);
435  is_female->setChecked(!is_male->isChecked());
436  no_name->setLayout(qgroupbox_layout);
437 
438  description = new QTextEdit;
439  description->setReadOnly(true);
440  description->setPlainText(_("Choose nation"));
441  no_name->setTitle(_("Your leader name"));
442 
447  styles_iterate(pstyle)
448  {
449  i = basic_city_style_for_style(pstyle);
450 
451  if (i >= 0) {
452  item = new QTableWidgetItem;
453  styles->insertRow(i);
454  auto pix = tileset_layer_city(tileset)->sample_sprite(i);
455  item->setData(Qt::DecorationRole, pix);
456  item->setData(Qt::UserRole, style_number(pstyle));
457  item->setSizeHint(pix.size());
458  styles->setItem(i, 0, item);
459  item = new QTableWidgetItem;
460  item->setText(style_name_translation(pstyle));
461  styles->setItem(i, 1, item);
462  }
463  }
465 
466  header = styles->horizontalHeader();
467  header->setSectionResizeMode(QHeaderView::Stretch);
468  header->resizeSections(QHeaderView::ResizeToContents);
469  header = styles->verticalHeader();
470  header->resizeSections(QHeaderView::ResizeToContents);
471  nation_sets_iterate(pset)
472  {
474  nation_set_rule_name(pset));
475  }
477  // create nation sets
478  refresh();
479 
480  connect(styles->selectionModel(), &QItemSelectionModel::selectionChanged,
482  connect(selected_nation_tabs->selectionModel(),
483  &QItemSelectionModel::selectionChanged, this,
485  connect(leader_name, QOverload<int>::of(&QComboBox::currentIndexChanged),
487  connect(leader_name->lineEdit(), &QLineEdit::returnPressed, this,
489  connect(qnation_set, QOverload<int>::of(&QComboBox::currentIndexChanged),
491  connect(nation_tabs->selectionModel(),
492  &QItemSelectionModel::selectionChanged, this,
494 
495  ok_button = new QPushButton;
496  ok_button->setText(_("Cancel"));
497  connect(ok_button, &QAbstractButton::pressed, this,
499  main_layout->addWidget(ok_button, 8, 2, 1, 1);
500  random_button = new QPushButton;
501  random_button->setText(_("Random"));
502  connect(random_button, &QAbstractButton::pressed, this,
504  main_layout->addWidget(random_button, 8, 0, 1, 1);
505  ok_button = new QPushButton;
506  ok_button->setText(_("Ok"));
507  connect(ok_button, &QAbstractButton::pressed, this,
509  main_layout->addWidget(ok_button, 8, 3, 1, 1);
510  main_layout->addWidget(no_name, 0, 3, 2, 1);
511  if (nation_set_count() > 1) {
512  main_layout->addWidget(ns_label, 0, 0, 1, 1);
513  main_layout->addWidget(qnation_set, 0, 1, 1, 1);
514  main_layout->addWidget(nation_tabs, 1, 0, 5, 2);
515  } else {
516  main_layout->addWidget(nation_tabs, 0, 0, 6, 2);
517  }
518  main_layout->addWidget(styles, 2, 3, 4, 1);
519  main_layout->addWidget(description, 6, 0, 2, 4);
520  main_layout->addWidget(selected_nation_tabs, 0, 2, 6, 1);
521 
522  setLayout(main_layout);
523  set_index(-99);
524 
525  if (C_S_RUNNING == client_state()) {
526  title = _("Edit Nation");
527  } else if (nullptr != pplayer && pplayer == client.conn.playing) {
528  title = _("What Nation Will You Be?");
529  } else {
530  title = _("Pick Nation");
531  }
532 
534  setWindowTitle(title);
535 }
536 
541 
546 {
547  struct nation_group *group;
548  QTableWidgetItem *item;
549  QHeaderView *header;
550  int i;
551 
552  nation_tabs->clearContents();
553  nation_tabs->setRowCount(0);
554  nation_tabs->insertRow(0);
555  item = new QTableWidgetItem;
556  item->setText(_("All nations"));
557  item->setData(Qt::UserRole, -99);
558  nation_tabs->setItem(0, 0, item);
559 
560  for (i = 1; i < nation_group_count() + 1; i++) {
561  group = nation_group_by_number(i - 1);
562  if (is_nation_group_hidden(group)) {
563  continue;
564  }
565  auto count = std::count_if(
566  nations.begin(), nations.end(), [group](nation_type &n) {
567  return is_nation_playable(&n) && is_nation_pickable(&n)
568  && nation_is_in_group(&n, group);
569  });
570  if (count == 0) {
571  continue;
572  }
573  nation_tabs->insertRow(i);
574  item = new QTableWidgetItem;
575  item->setData(Qt::UserRole, i - 1);
576  item->setText(nation_group_name_translation(group));
577  nation_tabs->setItem(i, 0, item);
578  }
579  header = nation_tabs->horizontalHeader();
580  header->resizeSections(QHeaderView::Stretch);
581  header = nation_tabs->verticalHeader();
582  header->resizeSections(QHeaderView::ResizeToContents);
583  set_index(-99);
584 }
585 
590 {
591  struct option *popt;
592  struct nation_set *s;
593 
594  popt = optset_option_by_name(server_optset, "nationset");
595  if (popt) {
597  qnation_set->setCurrentIndex(nation_set_index(s));
598  qnation_set->setToolTip(_(nation_set_description(s)));
599  }
600 }
601 
605 void races_dialog::group_selected(const QItemSelection &sl,
606  const QItemSelection &ds)
607 {
608  Q_UNUSED(ds)
609  QModelIndexList indexes = sl.indexes();
610  QModelIndex index;
611 
612  if (indexes.isEmpty()) {
613  return;
614  }
615  index = indexes.at(0);
616  set_index(index.row());
617 }
618 
623 void races_dialog::set_index(int index)
624 {
625  QTableWidgetItem *item;
626  QFont f;
627  struct nation_group *group;
628  int i;
629  QHeaderView *header;
630  selected_nation_tabs->clearContents();
631  selected_nation_tabs->setRowCount(0);
632 
633  last_index = 0;
634  i = nation_tabs->currentRow();
635  if (i != -1) {
636  item = nation_tabs->item(i, 0);
637  index = item->data(Qt::UserRole).toInt();
638  }
639 
640  group = nation_group_by_number(index);
641  i = 0;
642  for (const auto &pnation : nations) {
643  if (!is_nation_playable(&pnation) || !is_nation_pickable(&pnation)) {
644  continue;
645  }
646  if (!nation_is_in_group(&pnation, group) && index != -99) {
647  continue;
648  }
649  item = new QTableWidgetItem;
650  selected_nation_tabs->insertRow(i);
651  auto s = get_nation_flag_sprite(tileset, &pnation);
652  if (pnation.player) {
653  f = item->font();
654  f.setStrikeOut(true);
655  item->setFont(f);
656  }
657  item->setData(Qt::DecorationRole, *s);
658  item->setData(Qt::UserRole, nation_index(&pnation));
659  item->setText(nation_adjective_translation(&pnation));
660  selected_nation_tabs->setItem(i, 0, item);
661  } // iterate over nations - pnation
662 
663  selected_nation_tabs->sortByColumn(0, Qt::AscendingOrder);
664  header = selected_nation_tabs->horizontalHeader();
665  header->resizeSections(QHeaderView::Stretch);
666  header = selected_nation_tabs->verticalHeader();
667  header->resizeSections(QHeaderView::ResizeToContents);
668 }
669 
673 void races_dialog::nation_selected(const QItemSelection &selected,
674  const QItemSelection &deselcted)
675 {
676  Q_UNUSED(deselcted)
677  char buf[4096];
678  QModelIndex index;
679  QVariant qvar;
680  QModelIndexList indexes = selected.indexes();
681  QString str;
682  QTableWidgetItem *item;
683  int style, ind;
684 
685  if (indexes.isEmpty()) {
686  return;
687  }
688 
689  index = indexes.at(0);
690  if (indexes.isEmpty()) {
691  return;
692  }
693  qvar = index.data(Qt::UserRole);
694  selected_nation = qvar.toInt();
695 
697  nullptr);
698  description->setPlainText(buf);
699  leader_name->clear();
700  if (client.conn.playing == tplayer) {
701  // Add username preserving gender information
702  leader_name->addItem(client.conn.playing->name, is_male->isChecked());
703  }
706  {
707  str = QString::fromUtf8(nation_leader_name(pleader));
708  leader_name->addItem(str, nation_leader_is_male(pleader));
709  }
711 
717  qvar = qvar.fromValue<int>(style);
718 
719  for (ind = 0; ind < styles->rowCount(); ind++) {
720  item = styles->item(ind, 0);
721 
722  if (item->data(Qt::UserRole) == qvar) {
723  styles->selectRow(ind);
724  }
725  }
726 }
727 
731 void races_dialog::style_selected(const QItemSelection &selected,
732  const QItemSelection &deselcted)
733 {
734  Q_UNUSED(deselcted)
735  QModelIndex index;
736  QVariant qvar;
737  QModelIndexList indexes = selected.indexes();
738 
739  if (indexes.isEmpty()) {
740  return;
741  }
742 
743  index = indexes.at(0);
744  qvar = index.data(Qt::UserRole);
745  selected_style = qvar.toInt();
746 }
747 
752 {
753  if (leader_name->itemData(index).toBool()) {
754  is_male->setChecked(true);
755  is_female->setChecked(false);
756  } else {
757  is_male->setChecked(false);
758  is_female->setChecked(true);
759  }
760 }
761 
767 {
768  QByteArray ln_bytes;
769 
770  if (selected_nation == -1) {
771  return;
772  }
773 
774  fc_assert_ret(is_male->isChecked() || is_female->isChecked());
775 
776  if (selected_style == -1) {
777  output_window_append(ftc_client, _("You must select your style."));
778  return;
779  }
780 
781  if (leader_name->currentText().length() == 0) {
782  output_window_append(ftc_client, _("You must type a legal name."));
783  return;
784  }
785 
786  if (nation_by_number(selected_nation)->player != nullptr) {
788  _("Nation has been chosen by other player"));
789  return;
790  }
791  ln_bytes = leader_name->currentText().toUtf8();
792  dsend_packet_nation_select_req(&client.conn, player_number(tplayer),
793  selected_nation, is_male->isChecked(),
794  ln_bytes.data(), selected_style);
795  close();
796  deleteLater();
797 }
798 
803 
808 {
809  if (!m_instance) {
810  m_instance = new qdef_act;
811  }
812  return m_instance;
813 }
814 
819 {
820  delete m_instance;
821  m_instance = nullptr;
822 }
823 
827 void qdef_act::vs_city_set(int i) { vs_city = i; }
828 
832 void qdef_act::vs_unit_set(int i) { vs_unit = i; }
833 
838 
843 
847 void races_dialog::cancel_pressed() { delete this; }
848 
853 {
854  dsend_packet_nation_select_req(&client.conn, player_number(tplayer), -1,
855  false, "", 0);
856  delete this;
857 }
858 
862 notify_goto::notify_goto(const char *headline, const char *lines,
863  const struct text_tag_list *tags, tile *ptile,
864  QWidget *parent)
865  : QMessageBox(parent)
866 {
867  Q_UNUSED(tags)
868  QString qlines;
869  setAttribute(Qt::WA_DeleteOnClose);
870  goto_but = this->addButton(_("Goto Location"), QMessageBox::ActionRole);
871  goto_but->setIcon(fcIcons::instance()->getIcon(QStringLiteral("go-up")));
872  inspect_but = this->addButton(_("Inspect City"), QMessageBox::ActionRole);
873  inspect_but->setIcon(fcIcons::instance()->getIcon(QStringLiteral("plus")));
874 
875  close_but = this->addButton(QMessageBox::Close);
876  gtile = ptile;
877  if (!gtile) {
878  goto_but->setVisible(false);
879  inspect_but->setVisible(false);
880  } else {
881  struct city *pcity = tile_city(gtile);
882  inspect_but->setVisible(nullptr != pcity
883  && city_owner(pcity) == client.conn.playing);
884  }
885  setWindowTitle(headline);
886  qlines = lines;
887  qlines.replace(QLatin1String("\n"), QLatin1String(" "));
888  setText(qlines);
889  connect(goto_but, &QAbstractButton::pressed, this,
891  connect(inspect_but, &QAbstractButton::pressed, this,
893  connect(close_but, &QAbstractButton::pressed, this, &QWidget::close);
894  show();
895 }
896 
901 {
903  close();
904 }
905 
910 {
911  struct city *pcity = tile_city(gtile);
912  if (pcity) {
913  real_city_dialog_popup(pcity);
914  }
915  close();
916 }
917 
922 {
923  QString rule_name;
924  QByteArray rn_bytes;
925  const char *rn;
926  struct option *poption = optset_option_by_name(server_optset, "nationset");
927 
928  rule_name = qnation_set->currentData().toString();
929  rn_bytes = rule_name.toLocal8Bit(); /* Hold QByteArray in a variable to
930  * extend its, and data() buffer's,
931  * lifetime */
932  rn = rn_bytes.data();
934  != nation_set_by_rule_name(rn)) {
935  option_str_set(poption, rn);
936  }
937 }
938 
944 void popup_notify_goto_dialog(const char *headline, const char *lines,
945  const struct text_tag_list *tags,
946  struct tile *ptile)
947 {
948  notify_goto *ask =
949  new notify_goto(headline, lines, tags, ptile, king()->central_wdg);
950  ask->show();
951 }
952 
956 void popup_connect_msg(const char *headline, const char *message)
957 {
958  QMessageBox *msg = new QMessageBox(king()->central_wdg);
959 
960  msg->setText(message);
961  msg->setStandardButtons(QMessageBox::Ok);
962  msg->setWindowTitle(headline);
963  msg->setAttribute(Qt::WA_DeleteOnClose);
964  msg->show();
965 }
966 
970 void popup_notify_dialog(const char *caption, const char *headline,
971  const char *lines)
972 {
973  /*
974  Item 1084 Information widgets open multiple times
975  See if there is already a dialog on the screen for the inputted type and
976  if so remove it. There are 2 "Traveler's Report:" captions so must
977  distinguish between the 2 by looking at the headline
978  */
979 
980  const auto list =
981  queen()->game_tab_widget->findChildren<freeciv::report_widget *>();
982  for (auto report : list) {
983  if (report->caption() == caption && report->headline() == headline) {
984  report->close();
985  }
986  }
987 
989  caption, headline, lines, queen()->mapview_wdg);
990  nd->move(queen()->mapview_wdg->find_place(nd->size()));
991  nd->show();
992 }
993 
997 void popup_races_dialog(struct player *pplayer)
998 {
999  if (!is_race_dialog_open) {
1000  race_dialog = new races_dialog(pplayer, king()->central_wdg);
1001  is_race_dialog_open = true;
1002  race_dialog->show();
1003  }
1004  race_dialog->showNormal();
1005 }
1006 
1012 {
1013  if (is_race_dialog_open) {
1014  race_dialog->close();
1015  is_race_dialog_open = false;
1016  }
1017 }
1018 
1022 void unit_select_dialog_popup(struct tile *ptile)
1023 {
1024  if (ptile != nullptr
1025  && (unit_list_size(ptile->units) > 1
1026  || (unit_list_size(ptile->units) == 1 && tile_city(ptile)))) {
1027  toggle_unit_sel_widget(ptile);
1028  }
1029 }
1030 
1035 
1040 {
1041  if (is_race_dialog_open) {
1043  }
1044 }
1045 
1049 void races_update_pickable(bool nationset_change)
1050 {
1051  Q_UNUSED(nationset_change)
1052  if (is_race_dialog_open) {
1053  race_dialog->refresh();
1054  }
1055 }
1056 
1062 {
1063  if (is_race_dialog_open) {
1064  race_dialog->refresh();
1065  }
1066 }
1067 
1072 {
1073  hud_message_box *ask;
1074  const Government_type_id government_id = government_number(government);
1075 
1077  ask = new hud_message_box(king()->central_wdg);
1078  ask->set_text_title(_("Do you want to overthrow the government?"),
1079  _("Revolution!"));
1080  ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
1081  ask->setDefaultButton(QMessageBox::Cancel);
1082  ask->button(QMessageBox::Yes)->setText(_("Yes Start a Revolution!"));
1083 
1084  ask->setAttribute(Qt::WA_DeleteOnClose);
1085  QObject::connect(ask, &hud_message_box::accepted, [=]() {
1086  struct government *government = government_by_number(government_id);
1087  if (government) {
1089  }
1090  });
1091  ask->show();
1092  } else {
1094  }
1095 }
1096 
1101  pfcn_void func_in,
1102  QVariant data1_in,
1103  QVariant data2_in)
1104  : QPushButton(title), data1(data1_in), data2(data2_in)
1105 {
1106  func = func_in;
1107 }
1108 
1113 
1119 
1125 
1129 void Choice_dialog_button::setData1(QVariant wariat) { data1 = wariat; }
1130 
1134 void Choice_dialog_button::setData2(QVariant wariat) { data2 = wariat; }
1135 
1139 choice_dialog::choice_dialog(const QString title, const QString text,
1140  QWidget *parent, void (*run_on_close_in)(int))
1141  : QWidget(parent), target_unit_button(nullptr), unit_skip(nullptr)
1142 {
1143  QLabel *l = new QLabel(text);
1144 
1145  setProperty("themed_choice", true);
1146  layout = new QVBoxLayout(this);
1147  run_on_close = run_on_close_in;
1148 
1149  layout->addWidget(l);
1150  setWindowFlags(Qt::Dialog);
1151  setWindowTitle(title);
1152  setAttribute(Qt::WA_DeleteOnClose);
1153  king()->set_diplo_dialog(this);
1154 
1156  target_id[ATK_SELF] = unit_id;
1157  target_id[ATK_CITY] = IDENTITY_NUMBER_ZERO;
1158  target_id[ATK_UNIT] = IDENTITY_NUMBER_ZERO;
1159  target_id[ATK_UNITS] = TILE_INDEX_NONE;
1160  target_id[ATK_TILE] = TILE_INDEX_NONE;
1161  sub_target_id[ASTK_BUILDING] = B_LAST;
1162  sub_target_id[ASTK_TECH] = A_UNSET;
1163  sub_target_id[ASTK_EXTRA] = EXTRA_NONE;
1164  sub_target_id[ASTK_EXTRA_NOT_THERE] = EXTRA_NONE;
1165 
1166  targeted_unit = nullptr;
1167  // No buttons are added yet.
1168  for (int i = 0; i < BUTTON_COUNT; i++) {
1169  action_button_map << nullptr;
1170  }
1171 }
1172 
1177 {
1178  buttons_list.clear();
1179  action_button_map.clear();
1180  king()->set_diplo_dialog(nullptr);
1181 
1182  if (run_on_close) {
1184  run_on_close = nullptr;
1185  }
1186 }
1187 
1192 {
1194 
1196  && unit_list_size(targeted_unit->tile->units) > 1) {
1197  QPixmap *pix;
1198  QPushButton *next, *prev;
1199  unit_skip = new QHBoxLayout;
1200  next = new QPushButton();
1201  next->setIcon(
1202  fcIcons::instance()->getIcon(QStringLiteral("city-right")));
1203  next->setIconSize(QSize(32, 32));
1204  next->setFixedSize(QSize(36, 36));
1205  prev = new QPushButton();
1206  prev->setIcon(fcIcons::instance()->getIcon(QStringLiteral("city-left")));
1207  prev->setIconSize(QSize(32, 32));
1208  prev->setFixedSize(QSize(36, 36));
1209  target_unit_button = new QPushButton;
1210  pix = new QPixmap(tileset_unit_width(tileset),
1212  pix->fill(Qt::transparent);
1213  put_unit(targeted_unit, pix, QPoint());
1214  target_unit_button->setIcon(QIcon(*pix));
1215  delete pix;
1216  target_unit_button->setIconSize(QSize(96, 96));
1217  target_unit_button->setFixedSize(QSize(100, 100));
1218  unit_skip->addStretch(100);
1219  unit_skip->addWidget(prev, Qt::AlignCenter);
1220  unit_skip->addWidget(target_unit_button, Qt::AlignCenter);
1221  unit_skip->addWidget(next, Qt::AlignCenter);
1222  layout->addLayout(unit_skip);
1223  unit_skip->addStretch(100);
1224  connect(prev, &QAbstractButton::clicked, this,
1226  connect(next, &QAbstractButton::clicked, this,
1228  }
1229 
1230  setLayout(layout);
1231 }
1232 
1236 void choice_dialog::add_item(QString title, pfcn_void func, QVariant data1,
1237  QVariant data2,
1238  QString tool_tip = QLatin1String(""),
1239  const int button_id = -1)
1240 {
1241  Choice_dialog_button *button =
1242  new Choice_dialog_button(title, func, data1, data2);
1243  int action = buttons_list.count();
1244 
1245  QObject::connect(button, &QPushButton::clicked,
1246  [=]() { execute_action(action); });
1247 
1248  buttons_list.append(button);
1249 
1250  if (!tool_tip.isEmpty()) {
1251  button->setToolTip(break_lines(tool_tip, 40));
1252  }
1253 
1254  if (0 <= button_id) {
1255  // The id is valid.
1256  action_button_map[button_id] = button;
1257  }
1258 
1259  layout->addWidget(button);
1260 }
1261 
1266 {
1267  QPoint p;
1268 
1269  p = mapFromGlobal(QCursor::pos());
1270  p.setY(p.y() - this->height());
1271  p.setX(p.x() - this->width());
1272  move(p);
1273  show();
1274 }
1275 
1279 QVBoxLayout *choice_dialog::get_layout() { return layout; }
1280 
1285 {
1286  if (id < 0) {
1287  fc_assert_msg(0 <= id, "Invalid button ID.");
1288  return nullptr;
1289  }
1290 
1291  return action_button_map[id];
1292 }
1293 
1297 bool try_default_unit_action(QVariant q1, QVariant q2)
1298 {
1299  action_id action;
1300  pfcn_void func;
1301 
1303  if (action == -1) {
1304  return false;
1305  }
1306  func = af_map[action];
1307 
1308  func(q1, q2);
1309  return true;
1310 }
1311 
1315 bool try_default_city_action(QVariant q1, QVariant q2)
1316 {
1317  action_id action;
1318  pfcn_void func;
1319 
1321  if (action == -1) {
1322  return false;
1323  }
1324  func = af_map[action];
1325  func(q1, q2);
1326  return true;
1327 }
1328 
1333 {
1334  struct tile *ptile;
1335  struct unit *new_target = nullptr;
1336  bool break_next = false;
1337  bool first = true;
1338  QPixmap *pix;
1339 
1340  if (targeted_unit == nullptr) {
1341  return;
1342  }
1343 
1344  ptile = targeted_unit->tile;
1345 
1346  unit_list_iterate(ptile->units, ptgt)
1347  {
1348  if (first) {
1349  new_target = ptgt;
1350  first = false;
1351  }
1352  if (break_next) {
1353  new_target = ptgt;
1354  break;
1355  }
1356  if (ptgt == targeted_unit) {
1357  break_next = true;
1358  }
1359  }
1361  targeted_unit = new_target;
1362  pix =
1364  pix->fill(Qt::transparent);
1365  put_unit(targeted_unit, pix, QPoint());
1366  target_unit_button->setIcon(QIcon(*pix));
1367  delete pix;
1368  switch_target();
1369 }
1370 
1375 {
1376  struct tile *ptile;
1377  struct unit *new_target = nullptr;
1378  QPixmap *pix;
1379  if (targeted_unit == nullptr) {
1380  return;
1381  }
1382 
1383  ptile = targeted_unit->tile;
1384  unit_list_iterate(ptile->units, ptgt)
1385  {
1386  if ((ptgt == targeted_unit) && new_target != nullptr) {
1387  break;
1388  }
1389  new_target = ptgt;
1390  }
1392  targeted_unit = new_target;
1393  pix =
1395  pix->fill(Qt::transparent);
1396  put_unit(targeted_unit, pix, QPoint());
1397  target_unit_button->setIcon(QIcon(*pix));
1398  delete pix;
1399  switch_target();
1400 }
1401 
1405 void choice_dialog::update_dialog(const struct act_prob *act_probs)
1406 {
1407  struct unit *actor_unit = game_unit_by_number(unit_id);
1408  if (targeted_unit == nullptr) {
1409  return;
1410  }
1411  unit_skip->setParent(nullptr);
1412  fc_assert_ret(actor_unit);
1413  action_selection_refresh(actor_unit, nullptr, targeted_unit,
1415  (sub_target_id[ASTK_EXTRA] != EXTRA_NONE
1416  ? extra_by_number(sub_target_id[ASTK_EXTRA])
1417  : nullptr),
1418  act_probs);
1419  layout->addLayout(unit_skip);
1420 }
1421 
1426 {
1427  if (targeted_unit == nullptr) {
1428  return;
1429  }
1430 
1431  unit_skip->setParent(nullptr);
1432  dsend_packet_unit_get_actions(&client.conn, unit_id, targeted_unit->id,
1435  layout->addLayout(unit_skip);
1436 }
1437 
1442 {
1444  pfcn_void func = button->getFunc();
1445 
1446  func(button->getData1(), button->getData2());
1447  close();
1448 }
1449 
1459 {
1460  // Store the data in the stack.
1461  last_buttons_stack.append(button);
1462 
1463  /* Temporary remove the button so it will end up below buttons added
1464  * before unstack_all_buttons() is called. */
1465  layout->removeWidget(button);
1466 
1467  // Synchronize the list with the layout.
1468  buttons_list.removeAll(button);
1469 }
1470 
1476 {
1477  while (!last_buttons_stack.isEmpty()) {
1478  Choice_dialog_button *button = last_buttons_stack.takeLast();
1479 
1480  // Reinsert the button below the other buttons.
1481  buttons_list.append(button);
1482  layout->addWidget(button);
1483  }
1484 }
1485 
1489 static void caravan_marketplace(QVariant data1, QVariant data2)
1490 {
1491  int actor_unit_id = data1.toInt();
1492  int target_city_id = data2.toInt();
1493 
1494  if (nullptr != game_unit_by_number(actor_unit_id)
1495  && nullptr != game_city_by_number(target_city_id)) {
1496  request_do_action(ACTION_MARKETPLACE, actor_unit_id, target_city_id, 0,
1497  "");
1498  }
1499 }
1500 
1504 static void caravan_establish_trade(QVariant data1, QVariant data2)
1505 {
1506  int actor_unit_id = data1.toInt();
1507  int target_city_id = data2.toInt();
1508 
1509  if (nullptr != game_unit_by_number(actor_unit_id)
1510  && nullptr != game_city_by_number(target_city_id)) {
1511  request_do_action(ACTION_TRADE_ROUTE, actor_unit_id, target_city_id, 0,
1512  "");
1513  }
1514 }
1515 
1519 static void caravan_help_build(QVariant data1, QVariant data2)
1520 {
1521  int caravan_id = data1.toInt();
1522  int caravan_target_id = data2.toInt();
1523 
1524  if (nullptr != game_unit_by_number(caravan_id)
1525  && nullptr != game_city_by_number(caravan_target_id)) {
1526  request_do_action(ACTION_HELP_WONDER, caravan_id, caravan_target_id, 0,
1527  "");
1528  }
1529 }
1530 
1534 static void unit_recycle(QVariant data1, QVariant data2)
1535 {
1536  int actor_id = data1.toInt();
1537  int tgt_city_id = data2.toInt();
1538 
1539  if (nullptr != game_unit_by_number(actor_id)
1540  && nullptr != game_city_by_number(tgt_city_id)) {
1541  request_do_action(ACTION_RECYCLE_UNIT, actor_id, tgt_city_id, 0, "");
1542  }
1543 }
1544 
1548 static void unit_home_city(QVariant data1, QVariant data2)
1549 {
1550  int actor_id = data1.toInt();
1551  int tgt_city_id = data2.toInt();
1552 
1553  if (nullptr != game_unit_by_number(actor_id)
1554  && nullptr != game_city_by_number(tgt_city_id)) {
1555  request_do_action(ACTION_HOME_CITY, actor_id, tgt_city_id, 0, "");
1556  }
1557 }
1558 
1562 static void unit_upgrade(QVariant data1, QVariant data2)
1563 {
1564  struct unit *punit;
1565 
1566  int actor_id = data1.toInt();
1567  int tgt_city_id = data2.toInt();
1568 
1569  if ((punit = game_unit_by_number(actor_id))
1570  && nullptr != game_city_by_number(tgt_city_id)) {
1571  popup_upgrade_dialog({punit});
1572  }
1573 }
1574 
1578 static void airlift(QVariant data1, QVariant data2)
1579 {
1580  int actor_id = data1.toInt();
1581  int tgt_city_id = data2.toInt();
1582 
1583  if (nullptr != game_unit_by_number(actor_id)
1584  && nullptr != game_city_by_number(tgt_city_id)) {
1585  request_do_action(ACTION_AIRLIFT, actor_id, tgt_city_id, 0, "");
1586  }
1587 }
1588 
1592 static void conquer_city(QVariant data1, QVariant data2)
1593 {
1594  int actor_id = data1.toInt();
1595  int tgt_city_id = data2.toInt();
1596 
1597  if (nullptr != game_unit_by_number(actor_id)
1598  && nullptr != game_city_by_number(tgt_city_id)) {
1599  request_do_action(ACTION_CONQUER_CITY, actor_id, tgt_city_id, 0, "");
1600  }
1601 }
1602 
1606 static void conquer_city2(QVariant data1, QVariant data2)
1607 {
1608  int actor_id = data1.toInt();
1609  int tgt_city_id = data2.toInt();
1610 
1611  if (nullptr != game_unit_by_number(actor_id)
1612  && nullptr != game_city_by_number(tgt_city_id)) {
1613  request_do_action(ACTION_CONQUER_CITY2, actor_id, tgt_city_id, 0, "");
1614  }
1615 }
1616 
1620 static void act_sel_wait(QVariant data1, QVariant data2) { key_unit_wait(); }
1621 
1625 static void keep_moving(QVariant data1, QVariant data2) {}
1626 
1631 {
1632  if (!government) {
1633  start_revolution();
1634  } else {
1636  }
1637 }
1638 
1643 static void diplomat_queue_handle_primary(int actor_unit_id)
1644 {
1646  /* The client isn't waiting for information for any unanswered follow
1647  * up questions. */
1648 
1649  struct unit *actor_unit;
1650 
1651  if ((actor_unit = game_unit_by_number(actor_unit_id))) {
1652  /* The action selection dialog wasn't closed because the actor unit
1653  * was lost. */
1654 
1655  // The probabilities didn't just disappear, right?
1656  fc_assert_action(actor_unit->client.act_prob_cache,
1657  client_unit_init_act_prob_cache(actor_unit));
1658 
1659  delete[] actor_unit->client.act_prob_cache;
1660  actor_unit->client.act_prob_cache = nullptr;
1661  }
1662 
1663  // The action selection process is over, at least for now.
1665 
1666  if (did_not_decide) {
1667  /* The action selection dialog was closed but the player didn't
1668  * decide what the unit should do. */
1669 
1670  // Reset so the next action selection dialog does the right thing.
1671  did_not_decide = false;
1672  } else {
1673  // An action, or no action at all, was selected.
1674  action_decision_clear_want(actor_unit_id);
1675  action_selection_next_in_focus(actor_unit_id);
1676  }
1677  }
1678 }
1679 
1684 static void diplomat_queue_handle_secondary(int actor_id)
1685 {
1686  // Stop waiting. Move on to the next queued diplomat.
1687  is_more_user_input_needed = false;
1689 }
1690 
1698 {
1699  Q_UNUSED(actor_id)
1700  // Stop assuming the answer to a follow up question will arrive.
1701  is_more_user_input_needed = false;
1702 }
1703 
1708 void popup_action_selection(struct unit *actor_unit,
1709  struct city *target_city,
1710  struct unit *target_unit,
1711  struct tile *target_tile,
1712  struct extra_type *target_extra,
1713  const struct act_prob *act_probs)
1714 {
1715  QString title, text;
1716  choice_dialog *cd;
1717  QVariant qv1, qv2;
1718  pfcn_void func;
1719  struct city *actor_homecity;
1720  action_id unit_act;
1721  action_id city_act;
1722 
1723  unit_act = qdef_act::action()->vs_unit_get();
1724  city_act = qdef_act::action()->vs_city_get();
1725 
1726  for (auto caras : qAsConst(king()->trade_gen.lines)) {
1727  if (caras.autocaravan == actor_unit) {
1728  int i;
1729  if (nullptr != game_unit_by_number(actor_unit->id)
1730  && nullptr != game_city_by_number(target_city->id)) {
1731  request_do_action(ACTION_TRADE_ROUTE, actor_unit->id,
1732  target_city->id, 0, "");
1733  client_unit_init_act_prob_cache(actor_unit);
1734  diplomat_queue_handle_primary(actor_unit->id);
1735  i = king()->trade_gen.lines.indexOf(caras);
1736  king()->trade_gen.lines.takeAt(i);
1737  return;
1738  }
1739  }
1740  }
1741  if (target_city && try_default_city_action(actor_unit->id, target_city->id)
1742  && action_prob_possible(act_probs[unit_act])) {
1743  diplomat_queue_handle_primary(actor_unit->id);
1744  return;
1745  }
1746 
1747  if (target_unit && try_default_unit_action(actor_unit->id, target_unit->id)
1748  && action_prob_possible(act_probs[city_act])) {
1749  diplomat_queue_handle_primary(actor_unit->id);
1750  return;
1751  }
1752  /* Could be caused by the server failing to reply to a request for more
1753  * information or a bug in the client code. */
1755  "Diplomat queue problem. Is another diplomat window open?");
1756 
1757  // No extra input is required as no action has been chosen yet.
1758  is_more_user_input_needed = false;
1759 
1760  actor_homecity = game_city_by_number(actor_unit->homecity);
1761 
1762  title = // TRANS: %s is a unit name, e.g., Spy
1763  QString(_("Choose Your %1's Strategy"))
1764  .arg(unit_name_translation(actor_unit));
1765 
1766  if (target_city && actor_homecity) {
1767  text =
1768  QString(_("Your %1 from %2 reaches the city of %3.\nWhat now?"))
1769  .arg(unit_name_translation(actor_unit),
1770  city_name_get(actor_homecity), city_name_get(target_city));
1771  } else if (target_city) {
1772  text = QString(_("Your %1 has arrived at %2.\nWhat is your command?"))
1773  .arg(unit_name_translation(actor_unit),
1774  city_name_get(target_city));
1775  } else if (target_unit) {
1776  // TRANS: Your Spy is ready to act against Roman Freight.
1777  text = QString(_("Your %1 is ready to act against %2 %3."))
1778  .arg(unit_name_translation(actor_unit),
1780  unit_name_translation(target_unit));
1781  } else {
1782  fc_assert_msg(target_unit || target_city || target_tile,
1783  "No target specified.");
1784  // TRANS: %s is a unit name, e.g., Diplomat, Spy
1785  text = QString(_("Your %1 is waiting for your command."))
1786  .arg(unit_name_translation(actor_unit));
1787  }
1788 
1789  cd = king()->get_diplo_dialog();
1790  if ((cd != nullptr) && cd->targeted_unit != nullptr) {
1791  cd->update_dialog(act_probs);
1792  return;
1793  }
1794  cd = new choice_dialog(title, text, queen()->game_tab_widget,
1796  qv1 = actor_unit->id;
1797 
1798  cd->unit_id = actor_unit->id;
1799 
1800  cd->target_id[ATK_SELF] = cd->unit_id;
1801 
1802  if (target_city) {
1803  cd->target_id[ATK_CITY] = target_city->id;
1804  } else {
1805  cd->target_id[ATK_CITY] = IDENTITY_NUMBER_ZERO;
1806  }
1807 
1808  if (target_unit) {
1809  cd->target_id[ATK_UNIT] = target_unit->id;
1810  } else {
1811  cd->target_id[ATK_UNIT] = IDENTITY_NUMBER_ZERO;
1812  }
1813 
1814  if (target_tile) {
1815  cd->target_id[ATK_UNITS] = tile_index(target_tile);
1816  } else {
1817  cd->target_id[ATK_UNITS] = TILE_INDEX_NONE;
1818  }
1819 
1820  if (target_tile) {
1821  cd->target_id[ATK_TILE] = tile_index(target_tile);
1822  } else {
1823  cd->target_id[ATK_TILE] = TILE_INDEX_NONE;
1824  }
1825 
1826  // No target building or target tech supplied. (Feb 2020)
1827  cd->sub_target_id[ASTK_BUILDING] = B_LAST;
1828  cd->sub_target_id[ASTK_TECH] = A_UNSET;
1829 
1830  if (target_extra) {
1831  cd->sub_target_id[ASTK_EXTRA] = extra_number(target_extra);
1832  cd->sub_target_id[ASTK_EXTRA_NOT_THERE] = extra_number(target_extra);
1833  } else {
1834  cd->sub_target_id[ASTK_EXTRA] = EXTRA_NONE;
1835  cd->sub_target_id[ASTK_EXTRA_NOT_THERE] = EXTRA_NONE;
1836  }
1837 
1838  // Unit acting against a city
1839 
1840  // Set the correct target for the following actions.
1841  qv2 = cd->target_id[ATK_CITY];
1842 
1843  action_iterate(act)
1844  {
1845  if (action_id_get_actor_kind(act) == AAK_UNIT
1846  && action_id_get_target_kind(act) == ATK_CITY) {
1847  action_entry(cd, act, act_probs,
1849  act_probs[act], actor_unit,
1850  target_city),
1851  qv1, qv2);
1852  }
1853  }
1855 
1856  // Unit acting against another unit
1857 
1858  // Set the correct target for the following actions.
1859  qv2 = cd->target_id[ATK_UNIT];
1860 
1861  action_iterate(act)
1862  {
1863  if (action_id_get_actor_kind(act) == AAK_UNIT
1864  && action_id_get_target_kind(act) == ATK_UNIT) {
1865  action_entry(cd, act, act_probs,
1867  act_probs[act], actor_unit,
1868  target_city),
1869  qv1, qv2);
1870  }
1871  }
1873 
1874  // Unit acting against all units at a tile
1875 
1876  // Set the correct target for the following actions.
1877  qv2 = cd->target_id[ATK_UNITS];
1878 
1879  action_iterate(act)
1880  {
1881  if (action_id_get_actor_kind(act) == AAK_UNIT
1882  && action_id_get_target_kind(act) == ATK_UNITS) {
1883  action_entry(cd, act, act_probs,
1885  act_probs[act], actor_unit,
1886  target_city),
1887  qv1, qv2);
1888  }
1889  }
1891 
1892  // Unit acting against a tile.
1893 
1894  // Set the correct target for the following actions.
1895  qv2 = cd->target_id[ATK_TILE];
1896 
1897  action_iterate(act)
1898  {
1899  if (action_id_get_actor_kind(act) == AAK_UNIT
1900  && action_id_get_target_kind(act) == ATK_TILE) {
1901  action_entry(cd, act, act_probs,
1903  act_probs[act], actor_unit,
1904  target_city),
1905  qv1, qv2);
1906  }
1907  }
1909 
1910  // Unit acting against itself
1911 
1912  // Set the correct target for the following actions.
1913  qv2 = cd->target_id[ATK_SELF];
1914 
1915  action_iterate(act)
1916  {
1917  if (action_id_get_actor_kind(act) == AAK_UNIT
1918  && action_id_get_target_kind(act) == ATK_SELF) {
1919  action_entry(cd, act, act_probs,
1921  act_probs[act], actor_unit,
1922  target_city),
1923  qv1, qv2);
1924  }
1925  }
1927 
1928  if (unit_can_move_to_tile(&(wld.map), actor_unit, target_tile, false,
1929  false)) {
1930  qv2 = target_tile->index;
1931 
1933  cd->add_item(QString(_("Keep moving")), func, qv1, qv2,
1934  QLatin1String(""), BUTTON_MOVE);
1935  }
1936 
1937  func = act_sel_wait;
1938  cd->add_item(QString(_("&Wait")), func, qv1, qv2, QLatin1String(""),
1939  BUTTON_WAIT);
1940 
1941  func = keep_moving;
1942  cd->add_item(QString(_("Do nothing")), func, qv1, qv2, QLatin1String(""),
1943  BUTTON_CANCEL);
1944 
1945  cd->set_layout();
1946  cd->show_me();
1947 
1948  // Give follow up questions access to action probabilities.
1949  client_unit_init_act_prob_cache(actor_unit);
1950  action_iterate(act)
1951  {
1952  actor_unit->client.act_prob_cache[act] = act_probs[act];
1953  }
1955 }
1956 
1962 {
1963  /* Don't add an action mapping here unless the non targeted version is
1964  * selectable in the targeted version's target selection dialog. */
1965  switch (static_cast<enum gen_action>(tgt_action_id)) {
1966  case ACTION_SPY_TARGETED_SABOTAGE_CITY:
1967  return ACTION_SPY_SABOTAGE_CITY;
1968  case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
1969  return ACTION_SPY_SABOTAGE_CITY_ESC;
1970  case ACTION_SPY_TARGETED_STEAL_TECH:
1971  return ACTION_SPY_STEAL_TECH;
1972  case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
1973  return ACTION_SPY_STEAL_TECH_ESC;
1974  default:
1975  // No non targeted version found.
1976  return ACTION_NONE;
1977  }
1978 }
1979 
1985 {
1986  /* Don't add an action mapping here unless the non targeted version is
1987  * selectable in the targeted version's target selection dialog. */
1988  switch (static_cast<enum gen_action>(tgt_action_id)) {
1989  case ACTION_SPY_TARGETED_SABOTAGE_CITY:
1990  return ACTION_SPY_SABOTAGE_CITY_PRODUCTION;
1991  case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
1992  return ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC;
1993  case ACTION_STRIKE_BUILDING:
1994  return ACTION_STRIKE_PRODUCTION;
1995  default:
1996  // No non targeted version found.
1997  return ACTION_NONE;
1998  }
1999 }
2000 
2004 static void action_entry(choice_dialog *cd, action_id act,
2005  const struct act_prob *act_probs,
2006  const QString custom, QVariant data1,
2007  QVariant data2)
2008 {
2009  QString title;
2010  QString tool_tip;
2011 
2012  if (!af_map.contains(act)) {
2013  /* The Qt client doesn't support ordering this action from the
2014  * action selection dialog. */
2015  return;
2016  }
2017 
2018  // Don't show disabled actions.
2019  if (!action_prob_possible(act_probs[act])) {
2020  return;
2021  }
2022 
2023  title = QString(action_prepare_ui_name(act, "&", act_probs[act], custom));
2024 
2025  tool_tip = QString(
2026  act_sel_action_tool_tip(action_by_number(act), act_probs[act]));
2027 
2028  cd->add_item(title, af_map[act], data1, data2, tool_tip, act);
2029 }
2030 
2035  const struct act_prob *act_probs,
2036  const QString custom, QVariant data1,
2037  QVariant data2)
2038 {
2039  QString title;
2040  QString tool_tip;
2041 
2042  /* An action that just became impossible has its button disabled.
2043  * An action that became possible again must be reenabled. */
2044  button->setEnabled(action_prob_possible(act_probs[act]));
2045  button->setData1(data1);
2046  button->setData2(data2);
2047  // The probability may have changed.
2048  title = QString(action_prepare_ui_name(act, "&", act_probs[act], custom));
2049 
2050  tool_tip = QString(
2051  act_sel_action_tool_tip(action_by_number(act), act_probs[act]));
2052 
2053  button->setText(title);
2054  button->setToolTip(tool_tip);
2055 }
2056 
2060 static void disband_unit(QVariant data1, QVariant data2)
2061 {
2062  int actor_id = data1.toInt();
2063  int target_id = data2.toInt();
2064 
2065  request_do_action(ACTION_DISBAND_UNIT, actor_id, target_id, 0, "");
2066 }
2067 
2071 static void fortify(QVariant data1, QVariant data2)
2072 {
2073  int actor_id = data1.toInt();
2074  int target_id = data2.toInt();
2075 
2076  if (nullptr != game_unit_by_number(actor_id)) {
2077  request_do_action(ACTION_FORTIFY, actor_id, target_id, 0, "");
2078  }
2079 }
2080 
2084 static void convert_unit(QVariant data1, QVariant data2)
2085 {
2086  int actor_id = data1.toInt();
2087  int target_id = data2.toInt();
2088 
2089  request_do_action(ACTION_CONVERT, actor_id, target_id, 0, "");
2090 }
2091 
2095 static void diplomat_bribe(QVariant data1, QVariant data2)
2096 {
2097  int diplomat_id = data1.toInt();
2098  int diplomat_target_id = data2.toInt();
2099 
2100  if (nullptr != game_unit_by_number(diplomat_id)
2101  && nullptr != game_unit_by_number(diplomat_target_id)) {
2102  /* Wait for the server's reply before moving on to the next queued
2103  * diplomat. */
2105 
2106  request_action_details(ACTION_SPY_BRIBE_UNIT, diplomat_id,
2107  diplomat_target_id);
2108  }
2109 }
2110 
2114 static void spy_sabotage_unit(QVariant data1, QVariant data2)
2115 {
2116  int diplomat_id = data1.toInt();
2117  int diplomat_target_id = data2.toInt();
2118 
2119  request_do_action(ACTION_SPY_SABOTAGE_UNIT, diplomat_id,
2120  diplomat_target_id, 0, "");
2121 }
2122 
2126 static void spy_sabotage_unit_esc(QVariant data1, QVariant data2)
2127 {
2128  int diplomat_id = data1.toInt();
2129  int diplomat_target_id = data2.toInt();
2130 
2131  request_do_action(ACTION_SPY_SABOTAGE_UNIT_ESC, diplomat_id,
2132  diplomat_target_id, 0, "");
2133 }
2134 
2138 static void heal_unit(QVariant data1, QVariant data2)
2139 {
2140  int actor_id = data1.toInt();
2141  int target_id = data2.toInt();
2142 
2143  request_do_action(ACTION_HEAL_UNIT, actor_id, target_id, 0, "");
2144 }
2145 
2149 static void transport_board(QVariant data1, QVariant data2)
2150 {
2151  int actor_id = data1.toInt();
2152  int target_id = data2.toInt();
2153 
2154  request_do_action(ACTION_TRANSPORT_BOARD, actor_id, target_id, 0, "");
2155 }
2156 
2160 static void transport_embark(QVariant data1, QVariant data2)
2161 {
2162  int actor_id = data1.toInt();
2163  int target_id = data2.toInt();
2164 
2165  request_do_action(ACTION_TRANSPORT_EMBARK, actor_id, target_id, 0, "");
2166 }
2167 
2171 static void transport_unload(QVariant data1, QVariant data2)
2172 {
2173  int actor_id = data1.toInt();
2174  int target_id = data2.toInt();
2175 
2176  request_do_action(ACTION_TRANSPORT_UNLOAD, actor_id, target_id, 0, "");
2177 }
2178 
2182 static void transport_alight(QVariant data1, QVariant data2)
2183 {
2184  int actor_id = data1.toInt();
2185  int target_id = data2.toInt();
2186 
2187  request_do_action(ACTION_TRANSPORT_ALIGHT, actor_id, target_id, 0, "");
2188 }
2189 
2190 static void do_that_action(QVariant data1, QVariant data2, enum gen_action a)
2191 {
2192  int actor_id = data1.toInt();
2193  int target_id = data2.toInt();
2194 
2195  if (nullptr != game_unit_by_number(actor_id)
2196  && nullptr != index_to_tile(&(wld.map), target_id)) {
2197  request_do_action(a, actor_id, target_id, 0, "");
2198  }
2199 }
2200 
2204 static void disembark1(QVariant data1, QVariant data2)
2205 {
2206  do_that_action(data1, data2, ACTION_TRANSPORT_DISEMBARK1);
2207 }
2208 
2212 static void disembark2(QVariant data1, QVariant data2)
2213 {
2214  do_that_action(data1, data2, ACTION_TRANSPORT_DISEMBARK2);
2215 }
2216 
2220 static void nuke_units(QVariant data1, QVariant data2)
2221 {
2222  int actor_id = data1.toInt();
2223  int target_id = data2.toInt();
2224 
2225  request_do_action(ACTION_NUKE_UNITS, actor_id, target_id, 0, "");
2226 }
2227 
2231 static void capture_units(QVariant data1, QVariant data2)
2232 {
2233  int actor_id = data1.toInt();
2234  int target_id = data2.toInt();
2235 
2236  request_do_action(ACTION_CAPTURE_UNITS, actor_id, target_id, 0, "");
2237 }
2238 
2242 static void expel_unit(QVariant data1, QVariant data2)
2243 {
2244  int actor_id = data1.toInt();
2245  int target_id = data2.toInt();
2246 
2247  request_do_action(ACTION_EXPEL_UNIT, actor_id, target_id, 0, "");
2248 }
2249 
2253 static void bombard(QVariant data1, QVariant data2)
2254 {
2255  int actor_id = data1.toInt();
2256  int target_id = data2.toInt();
2257 
2258  request_do_action(ACTION_BOMBARD, actor_id, target_id, 0, "");
2259 }
2260 
2264 static void bombard2(QVariant data1, QVariant data2)
2265 {
2266  int actor_id = data1.toInt();
2267  int target_id = data2.toInt();
2268 
2269  request_do_action(ACTION_BOMBARD2, actor_id, target_id, 0, "");
2270 }
2271 
2275 static void bombard3(QVariant data1, QVariant data2)
2276 {
2277  int actor_id = data1.toInt();
2278  int target_id = data2.toInt();
2279 
2280  request_do_action(ACTION_BOMBARD3, actor_id, target_id, 0, "");
2281 }
2282 
2286 static void found_city(QVariant data1, QVariant data2)
2287 {
2288  int actor_id = data1.toInt();
2289 
2290  dsend_packet_city_name_suggestion_req(&client.conn, actor_id);
2291 }
2292 
2296 static void transform_terrain(QVariant data1, QVariant data2)
2297 {
2298  do_that_action(data1, data2, ACTION_TRANSFORM_TERRAIN);
2299 }
2300 
2304 static void cultivate(QVariant data1, QVariant data2)
2305 {
2306  do_that_action(data1, data2, ACTION_CULTIVATE);
2307 }
2308 
2312 static void plant(QVariant data1, QVariant data2)
2313 {
2314  do_that_action(data1, data2, ACTION_PLANT);
2315 }
2316 
2320 static void pillage(QVariant data1, QVariant data2)
2321 {
2322  int actor_id = data1.toInt();
2323  int target_id = data2.toInt();
2324 
2325  if (nullptr != game_unit_by_number(actor_id)
2326  && nullptr != index_to_tile(&(wld.map), target_id)) {
2327  request_do_action(ACTION_PILLAGE, actor_id, target_id,
2328  /* FIXME: will cause problems if more than
2329  * one action selection dialog at a time
2330  * becomes supported. */
2332  }
2333 }
2334 
2338 static void clean_pollution(QVariant data1, QVariant data2)
2339 {
2340  int actor_id = data1.toInt();
2341  int target_id = data2.toInt();
2342 
2343  if (nullptr != game_unit_by_number(actor_id)
2344  && nullptr != index_to_tile(&(wld.map), target_id)) {
2345  request_do_action(ACTION_CLEAN_POLLUTION, actor_id, target_id,
2346  /* FIXME: will cause problems if more than
2347  * one action selection dialog at a time
2348  * becomes supported. */
2350  }
2351 }
2352 
2356 static void clean_fallout(QVariant data1, QVariant data2)
2357 {
2358  int actor_id = data1.toInt();
2359  int target_id = data2.toInt();
2360 
2361  if (nullptr != game_unit_by_number(actor_id)
2362  && nullptr != index_to_tile(&(wld.map), target_id)) {
2363  request_do_action(ACTION_CLEAN_FALLOUT, actor_id, target_id,
2364  /* FIXME: will cause problems if more than
2365  * one action selection dialog at a time
2366  * becomes supported. */
2368  }
2369 }
2370 
2374 static void road(QVariant data1, QVariant data2)
2375 {
2376  int actor_id = data1.toInt();
2377  int target_id = data2.toInt();
2378 
2379  if (nullptr != game_unit_by_number(actor_id)
2380  && nullptr != index_to_tile(&(wld.map), target_id)
2382  request_do_action(ACTION_ROAD, actor_id, target_id,
2383  /* FIXME: will cause problems if more than
2384  * one action selection dialog at a time
2385  * becomes supported. */
2387  }
2388 }
2389 
2393 static void base(QVariant data1, QVariant data2)
2394 {
2395  int actor_id = data1.toInt();
2396  int target_id = data2.toInt();
2397 
2398  if (nullptr != game_unit_by_number(actor_id)
2399  && nullptr != index_to_tile(&(wld.map), target_id)
2401  request_do_action(ACTION_BASE, actor_id, target_id,
2402  /* FIXME: will cause problems if more than
2403  * one action selection dialog at a time
2404  * becomes supported. */
2406  }
2407 }
2408 
2412 static void mine(QVariant data1, QVariant data2)
2413 {
2414  int actor_id = data1.toInt();
2415  int target_id = data2.toInt();
2416 
2417  if (nullptr != game_unit_by_number(actor_id)
2418  && nullptr != index_to_tile(&(wld.map), target_id)
2420  request_do_action(ACTION_MINE, actor_id, target_id,
2421  /* FIXME: will cause problems if more than
2422  * one action selection dialog at a time
2423  * becomes supported. */
2425  }
2426 }
2427 
2431 static void irrigate(QVariant data1, QVariant data2)
2432 {
2433  int actor_id = data1.toInt();
2434  int target_id = data2.toInt();
2435 
2436  if (nullptr != game_unit_by_number(actor_id)
2437  && nullptr != index_to_tile(&(wld.map), target_id)
2439  request_do_action(ACTION_IRRIGATE, actor_id, target_id,
2440  /* FIXME: will cause problems if more than
2441  * one action selection dialog at a time
2442  * becomes supported. */
2444  }
2445 }
2446 
2450 static void nuke(QVariant data1, QVariant data2)
2451 {
2452  int diplomat_id = data1.toInt();
2453  int diplomat_target_id = data2.toInt();
2454 
2455  if (nullptr != game_unit_by_number(diplomat_id)
2456  && nullptr != index_to_tile(&(wld.map), diplomat_target_id)) {
2457  request_do_action(ACTION_NUKE, diplomat_id, diplomat_target_id, 0, "");
2458  }
2459 }
2460 
2464 static void attack(QVariant data1, QVariant data2)
2465 {
2466  int diplomat_id = data1.toInt();
2467  int diplomat_target_id = data2.toInt();
2468 
2469  if (nullptr != game_unit_by_number(diplomat_id)
2470  && nullptr != index_to_tile(&(wld.map), diplomat_target_id)) {
2471  request_do_action(ACTION_ATTACK, diplomat_id, diplomat_target_id, 0, "");
2472  }
2473 }
2474 
2478 static void suicide_attack(QVariant data1, QVariant data2)
2479 {
2480  int diplomat_id = data1.toInt();
2481  int diplomat_target_id = data2.toInt();
2482 
2483  if (nullptr != game_unit_by_number(diplomat_id)
2484  && nullptr != index_to_tile(&(wld.map), diplomat_target_id)) {
2485  request_do_action(ACTION_SUICIDE_ATTACK, diplomat_id, diplomat_target_id,
2486  0, "");
2487  }
2488 }
2489 
2493 static void paradrop(QVariant data1, QVariant data2)
2494 {
2495  do_that_action(data1, data2, ACTION_PARADROP);
2496 }
2497 
2501 static void join_city(QVariant data1, QVariant data2)
2502 {
2503  int actor_id = data1.toInt();
2504  int target_id = data2.toInt();
2505 
2506  if (nullptr != game_unit_by_number(actor_id)
2507  && nullptr != game_city_by_number(target_id)) {
2508  request_do_action(ACTION_JOIN_CITY, actor_id, target_id, 0, "");
2509  }
2510 }
2511 
2515 static void spy_steal_shared(QVariant data1, QVariant data2,
2516  action_id act_id)
2517 {
2518  QString str;
2519  QVariant qv1;
2520  pfcn_void func;
2521  int diplomat_id = data1.toInt();
2522  int diplomat_target_id = data2.toInt();
2523  struct unit *actor_unit = game_unit_by_number(diplomat_id);
2524  struct city *pvcity = game_city_by_number(diplomat_target_id);
2525  struct player *pvictim = nullptr;
2526  choice_dialog *cd;
2527  QList<QVariant> actor_and_target;
2528 
2529  /* Wait for the player's reply before moving on to the next queued
2530  * diplomat. */
2532 
2533  if (pvcity) {
2534  pvictim = city_owner(pvcity);
2535  }
2536  cd = king()->get_diplo_dialog();
2537  if (cd != nullptr) {
2538  cd->close();
2539  }
2540  QString stra;
2541  cd = new choice_dialog(_("Steal"), _("Steal Technology"),
2542  queen()->game_tab_widget,
2544 
2545  // Put both actor and target city in qv1 since qv2 is taken
2546  actor_and_target.append(diplomat_id);
2547  actor_and_target.append(diplomat_target_id);
2548  actor_and_target.append(act_id);
2549  qv1 = QVariant::fromValue(actor_and_target);
2550 
2551  struct player *pplayer = client.conn.playing;
2552  if (pvictim) {
2553  const struct research *presearch = research_get(pplayer);
2554  const struct research *vresearch = research_get(pvictim);
2555 
2557  {
2558  if (research_invention_gettable(presearch, i,
2559  game.info.tech_steal_allow_holes)
2560  && research_invention_state(vresearch, i) == TECH_KNOWN
2561  && research_invention_state(presearch, i) != TECH_KNOWN) {
2563  str = QString(research_advance_name_translation(presearch, i));
2564  cd->add_item(str, func, qv1, i);
2565  }
2566  }
2568 
2569  if (actor_unit
2571  actor_unit->client
2572  .act_prob_cache[get_non_targeted_action_id(act_id)])) {
2573  stra = QString(_("At %1's Discretion"))
2574  .arg(unit_name_translation(actor_unit));
2576  cd->add_item(stra, func, qv1, A_UNSET);
2577  }
2578 
2579  cd->set_layout();
2580  cd->show_me();
2581  }
2582 }
2583 
2587 static void spy_steal(QVariant data1, QVariant data2)
2588 {
2589  spy_steal_shared(data1, data2, ACTION_SPY_TARGETED_STEAL_TECH);
2590 }
2591 
2595 static void spy_steal_esc(QVariant data1, QVariant data2)
2596 {
2597  spy_steal_shared(data1, data2, ACTION_SPY_TARGETED_STEAL_TECH_ESC);
2598 }
2599 
2603 static void spy_steal_something(QVariant data1, QVariant data2)
2604 {
2605  int diplomat_id = data1.toList().at(0).toInt();
2606  int diplomat_target_id = data1.toList().at(1).toInt();
2607  action_id act_id = data1.toList().at(2).toInt();
2608 
2609  if (nullptr != game_unit_by_number(diplomat_id)
2610  && nullptr != game_city_by_number(diplomat_target_id)) {
2611  if (data2.toInt() == A_UNSET) {
2612  // This is the untargeted version.
2613  request_do_action(get_non_targeted_action_id(act_id), diplomat_id,
2614  diplomat_target_id, data2.toInt(), "");
2615  } else {
2616  // This is the targeted version.
2617  request_do_action(act_id, diplomat_id, diplomat_target_id,
2618  data2.toInt(), "");
2619  }
2620  }
2621 }
2622 
2626 static void spy_request_strike_bld_list(QVariant data1, QVariant data2)
2627 {
2628  int actor_id = data1.toInt();
2629  int target_id = data2.toInt();
2630 
2631  if (nullptr != game_unit_by_number(actor_id)
2632  && nullptr != game_city_by_number(target_id)) {
2633  /* Wait for the server's reply before moving on to the next queued
2634  * diplomat. */
2636 
2637  request_action_details(ACTION_STRIKE_BUILDING, actor_id, target_id);
2638  }
2639 }
2640 
2644 static void spy_request_sabotage_list(QVariant data1, QVariant data2)
2645 {
2646  int diplomat_id = data1.toInt();
2647  int diplomat_target_id = data2.toInt();
2648 
2649  if (nullptr != game_unit_by_number(diplomat_id)
2650  && nullptr != game_city_by_number(diplomat_target_id)) {
2651  /* Wait for the server's reply before moving on to the next queued
2652  * diplomat. */
2654 
2655  request_action_details(ACTION_SPY_TARGETED_SABOTAGE_CITY, diplomat_id,
2656  diplomat_target_id);
2657  }
2658 }
2659 
2663 static void spy_request_sabotage_esc_list(QVariant data1, QVariant data2)
2664 {
2665  int diplomat_id = data1.toInt();
2666  int diplomat_target_id = data2.toInt();
2667 
2668  if (nullptr != game_unit_by_number(diplomat_id)
2669  && nullptr != game_city_by_number(diplomat_target_id)) {
2670  /* Wait for the server's reply before moving on to the next queued
2671  * diplomat. */
2673 
2674  request_action_details(ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC,
2675  diplomat_id, diplomat_target_id);
2676  }
2677 }
2678 
2682 static void spy_poison(QVariant data1, QVariant data2)
2683 {
2684  int diplomat_id = data1.toInt();
2685  int diplomat_target_id = data2.toInt();
2686 
2687  if (nullptr != game_unit_by_number(diplomat_id)
2688  && nullptr != game_city_by_number(diplomat_target_id)) {
2689  request_do_action(ACTION_SPY_POISON, diplomat_id, diplomat_target_id, 0,
2690  "");
2691  }
2692 }
2693 
2697 static void spy_poison_esc(QVariant data1, QVariant data2)
2698 {
2699  int diplomat_id = data1.toInt();
2700  int diplomat_target_id = data2.toInt();
2701 
2702  if (nullptr != game_unit_by_number(diplomat_id)
2703  && nullptr != game_city_by_number(diplomat_target_id)) {
2704  request_do_action(ACTION_SPY_POISON_ESC, diplomat_id, diplomat_target_id,
2705  0, "");
2706  }
2707 }
2708 
2712 static void spy_nuke_city(QVariant data1, QVariant data2)
2713 {
2714  int diplomat_id = data1.toInt();
2715  int diplomat_target_id = data2.toInt();
2716 
2717  if (nullptr != game_unit_by_number(diplomat_id)
2718  && nullptr != game_city_by_number(diplomat_target_id)) {
2719  request_do_action(ACTION_SPY_NUKE, diplomat_id, diplomat_target_id, 0,
2720  "");
2721  }
2722 }
2723 
2727 static void spy_nuke_city_esc(QVariant data1, QVariant data2)
2728 {
2729  int diplomat_id = data1.toInt();
2730  int diplomat_target_id = data2.toInt();
2731 
2732  if (nullptr != game_unit_by_number(diplomat_id)
2733  && nullptr != game_city_by_number(diplomat_target_id)) {
2734  request_do_action(ACTION_SPY_NUKE_ESC, diplomat_id, diplomat_target_id,
2735  0, "");
2736  }
2737 }
2738 
2742 static void nuke_city(QVariant data1, QVariant data2)
2743 {
2744  int actor_id = data1.toInt();
2745  int target_id = data2.toInt();
2746 
2747  if (nullptr != game_unit_by_number(actor_id)
2748  && nullptr != game_city_by_number(target_id)) {
2749  request_do_action(ACTION_NUKE_CITY, actor_id, target_id, 0, "");
2750  }
2751 }
2752 
2756 static void destroy_city(QVariant data1, QVariant data2)
2757 {
2758  int diplomat_id = data1.toInt();
2759  int diplomat_target_id = data2.toInt();
2760 
2761  if (nullptr != game_unit_by_number(diplomat_id)
2762  && nullptr != game_city_by_number(diplomat_target_id)) {
2763  request_do_action(ACTION_DESTROY_CITY, diplomat_id, diplomat_target_id,
2764  0, "");
2765  }
2766 }
2767 
2771 static void spy_steal_gold(QVariant data1, QVariant data2)
2772 {
2773  int diplomat_id = data1.toInt();
2774  int diplomat_target_id = data2.toInt();
2775 
2776  if (nullptr != game_unit_by_number(diplomat_id)
2777  && nullptr != game_city_by_number(diplomat_target_id)) {
2778  request_do_action(ACTION_SPY_STEAL_GOLD, diplomat_id, diplomat_target_id,
2779  0, "");
2780  }
2781 }
2782 
2786 static void spy_steal_gold_esc(QVariant data1, QVariant data2)
2787 {
2788  int diplomat_id = data1.toInt();
2789  int diplomat_target_id = data2.toInt();
2790 
2791  if (nullptr != game_unit_by_number(diplomat_id)
2792  && nullptr != game_city_by_number(diplomat_target_id)) {
2793  request_do_action(ACTION_SPY_STEAL_GOLD_ESC, diplomat_id,
2794  diplomat_target_id, 0, "");
2795  }
2796 }
2797 
2801 static void spy_steal_maps(QVariant data1, QVariant data2)
2802 {
2803  int diplomat_id = data1.toInt();
2804  int diplomat_target_id = data2.toInt();
2805 
2806  if (nullptr != game_unit_by_number(diplomat_id)
2807  && nullptr != game_city_by_number(diplomat_target_id)) {
2808  request_do_action(ACTION_STEAL_MAPS, diplomat_id, diplomat_target_id, 0,
2809  "");
2810  }
2811 }
2812 
2816 static void spy_steal_maps_esc(QVariant data1, QVariant data2)
2817 {
2818  int diplomat_id = data1.toInt();
2819  int diplomat_target_id = data2.toInt();
2820 
2821  if (nullptr != game_unit_by_number(diplomat_id)
2822  && nullptr != game_city_by_number(diplomat_target_id)) {
2823  request_do_action(ACTION_STEAL_MAPS_ESC, diplomat_id, diplomat_target_id,
2824  0, "");
2825  }
2826 }
2827 
2831 static void spy_embassy(QVariant data1, QVariant data2)
2832 {
2833  int diplomat_id = data1.toInt();
2834  int diplomat_target_id = data2.toInt();
2835 
2836  if (nullptr != game_unit_by_number(diplomat_id)
2837  && nullptr != game_city_by_number(diplomat_target_id)) {
2838  request_do_action(ACTION_ESTABLISH_EMBASSY, diplomat_id,
2839  diplomat_target_id, 0, "");
2840  }
2841 }
2842 
2846 static void diplomat_embassy(QVariant data1, QVariant data2)
2847 {
2848  int diplomat_id = data1.toInt();
2849  int diplomat_target_id = data2.toInt();
2850 
2851  if (nullptr != game_unit_by_number(diplomat_id)
2852  && nullptr != game_city_by_number(diplomat_target_id)) {
2853  request_do_action(ACTION_ESTABLISH_EMBASSY_STAY, diplomat_id,
2854  diplomat_target_id, 0, "");
2855  }
2856 }
2857 
2861 static void spy_investigate(QVariant data1, QVariant data2)
2862 {
2863  int diplomat_id = data1.toInt();
2864  int diplomat_target_id = data2.toInt();
2865 
2866  if (nullptr != game_city_by_number(diplomat_target_id)
2867  && nullptr != game_unit_by_number(diplomat_id)) {
2868  request_do_action(ACTION_SPY_INVESTIGATE_CITY, diplomat_id,
2869  diplomat_target_id, 0, "");
2870  }
2871 }
2872 
2876 static void diplomat_investigate(QVariant data1, QVariant data2)
2877 {
2878  int diplomat_id = data1.toInt();
2879  int diplomat_target_id = data2.toInt();
2880 
2881  if (nullptr != game_city_by_number(diplomat_target_id)
2882  && nullptr != game_unit_by_number(diplomat_id)) {
2883  request_do_action(ACTION_INV_CITY_SPEND, diplomat_id, diplomat_target_id,
2884  0, "");
2885  }
2886 }
2887 
2891 static void diplomat_sabotage(QVariant data1, QVariant data2)
2892 {
2893  int diplomat_id = data1.toInt();
2894  int diplomat_target_id = data2.toInt();
2895 
2896  if (nullptr != game_unit_by_number(diplomat_id)
2897  && nullptr != game_city_by_number(diplomat_target_id)) {
2898  request_do_action(ACTION_SPY_SABOTAGE_CITY, diplomat_id,
2899  diplomat_target_id, B_LAST + 1, "");
2900  }
2901 }
2902 
2906 static void diplomat_sabotage_esc(QVariant data1, QVariant data2)
2907 {
2908  int diplomat_id = data1.toInt();
2909  int diplomat_target_id = data2.toInt();
2910 
2911  if (nullptr != game_unit_by_number(diplomat_id)
2912  && nullptr != game_city_by_number(diplomat_target_id)) {
2913  request_do_action(ACTION_SPY_SABOTAGE_CITY_ESC, diplomat_id,
2914  diplomat_target_id, B_LAST + 1, "");
2915  }
2916 }
2917 
2921 static void diplomat_steal(QVariant data1, QVariant data2)
2922 {
2923  int diplomat_id = data1.toInt();
2924  int diplomat_target_id = data2.toInt();
2925 
2926  if (nullptr != game_unit_by_number(diplomat_id)
2927  && nullptr != game_city_by_number(diplomat_target_id)) {
2928  request_do_action(ACTION_SPY_STEAL_TECH, diplomat_id, diplomat_target_id,
2929  A_UNSET, "");
2930  }
2931 }
2932 
2936 static void diplomat_steal_esc(QVariant data1, QVariant data2)
2937 {
2938  int diplomat_id = data1.toInt();
2939  int diplomat_target_id = data2.toInt();
2940 
2941  if (nullptr != game_unit_by_number(diplomat_id)
2942  && nullptr != game_city_by_number(diplomat_target_id)) {
2943  request_do_action(ACTION_SPY_STEAL_TECH_ESC, diplomat_id,
2944  diplomat_target_id, A_UNSET, "");
2945  }
2946 }
2947 
2951 static void diplomat_incite(QVariant data1, QVariant data2)
2952 {
2953  int diplomat_id = data1.toInt();
2954  int diplomat_target_id = data2.toInt();
2955 
2956  if (nullptr != game_unit_by_number(diplomat_id)
2957  && nullptr != game_city_by_number(diplomat_target_id)) {
2958  /* Wait for the server's reply before moving on to the next queued
2959  * diplomat. */
2961 
2962  request_action_details(ACTION_SPY_INCITE_CITY, diplomat_id,
2963  diplomat_target_id);
2964  }
2965 }
2966 
2970 static void diplomat_incite_escape(QVariant data1, QVariant data2)
2971 {
2972  int diplomat_id = data1.toInt();
2973  int diplomat_target_id = data2.toInt();
2974 
2975  if (nullptr != game_unit_by_number(diplomat_id)
2976  && nullptr != game_city_by_number(diplomat_target_id)) {
2977  /* Wait for the server's reply before moving on to the next queued
2978  * diplomat. */
2980 
2981  request_action_details(ACTION_SPY_INCITE_CITY_ESC, diplomat_id,
2982  diplomat_target_id);
2983  }
2984 }
2985 
2989 static void act_sel_keep_moving(QVariant data1, QVariant data2)
2990 {
2991  struct unit *punit;
2992  struct tile *ptile;
2993  int diplomat_id = data1.toInt();
2994  int diplomat_target_id = data2.toInt();
2995 
2996  if ((punit = game_unit_by_number(diplomat_id))
2997  && (ptile = index_to_tile(&(wld.map), diplomat_target_id))
2998  && !same_pos(unit_tile(punit), ptile)) {
2999  request_unit_non_action_move(punit, ptile);
3000  }
3001 }
3002 
3007 void popup_incite_dialog(struct unit *actor, struct city *tcity, int cost,
3008  const struct action *paction)
3009 {
3010  QString buf, buf2;
3011  int diplomat_id = actor->id;
3012  int diplomat_target_id = tcity->id;
3013  const int action_id = paction->id;
3014 
3015  // Should be set before sending request to the server.
3017 
3018  buf = QString::asprintf(PL_("Treasury contains %d gold.",
3019  "Treasury contains %d gold.",
3020  client_player()->economic.gold),
3021  client_player()->economic.gold);
3022 
3023  if (INCITE_IMPOSSIBLE_COST == cost) {
3024  hud_message_box *impossible = new hud_message_box(king()->central_wdg);
3025 
3026  buf2 = QString::asprintf(_("You can't incite a revolt in %s."),
3027  city_name_get(tcity));
3028  impossible->set_text_title(buf2, QStringLiteral("!"));
3029  impossible->setStandardButtons(QMessageBox::Ok);
3030  impossible->setAttribute(Qt::WA_DeleteOnClose);
3031  impossible->show();
3032  } else if (cost <= client_player()->economic.gold) {
3033  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3034 
3035  buf2 = QString(PL_("Incite a revolt for %1 gold?\n%2",
3036  "Incite a revolt for %1 gold?\n%2", cost))
3037  .arg(QString::number(cost), buf);
3038  ask->set_text_title(buf2, _("Incite a Revolt!"));
3039  ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
3040  ask->setDefaultButton(QMessageBox::Cancel);
3041  ask->button(QMessageBox::Yes)->setText(_("Yes Incite a Revolt!"));
3042  ask->setAttribute(Qt::WA_DeleteOnClose);
3043  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3044  request_do_action(action_id, diplomat_id, diplomat_target_id, 0, "");
3045  diplomat_queue_handle_secondary(diplomat_id);
3046  });
3047  ask->show();
3048  return;
3049  } else {
3050  hud_message_box *too_much = new hud_message_box(king()->central_wdg);
3051 
3052  buf2 = QString(PL_("Inciting a revolt costs %1 gold.\n%2",
3053  "Inciting a revolt costs %1 gold.\n%2", cost))
3054  .arg(QString::number(cost), buf);
3055  too_much->set_text_title(buf2, QStringLiteral("!"));
3056  too_much->setStandardButtons(QMessageBox::Ok);
3057  too_much->setAttribute(Qt::WA_DeleteOnClose);
3058  too_much->show();
3059  }
3060 
3061  diplomat_queue_handle_secondary(diplomat_id);
3062 }
3063 
3068 void popup_bribe_dialog(struct unit *actor, struct unit *tunit, int cost,
3069  const struct action *paction)
3070 {
3071  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3072  QString buf, buf2;
3073  int diplomat_id = actor->id;
3074  int diplomat_target_id = tunit->id;
3075  const int action_id = paction->id;
3076 
3077  // Should be set before sending request to the server.
3079 
3080  buf = QString::asprintf(PL_("Treasury contains %d gold.",
3081  "Treasury contains %d gold.",
3082  client_player()->economic.gold),
3083  client_player()->economic.gold);
3084 
3085  if (cost <= client_player()->economic.gold) {
3086  buf2 = QString(PL_("Bribe unit for %1 gold?\n%2",
3087  "Bribe unit for %1 gold?\n%2", cost))
3088  .arg(QString::number(cost), buf);
3089  ask->set_text_title(buf2, _("Bribe Enemy Unit"));
3090  ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
3091  ask->setDefaultButton(QMessageBox::Cancel);
3092  ask->button(QMessageBox::Yes)->setText(_("Yes Bribe!"));
3093  ask->setAttribute(Qt::WA_DeleteOnClose);
3094  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3095  request_do_action(action_id, diplomat_id, diplomat_target_id, 0, "");
3096  diplomat_queue_handle_secondary(diplomat_id);
3097  });
3098  ask->show();
3099  return;
3100  } else {
3101  buf2 = QString(PL_("Bribing the unit costs %1 gold.\n%2",
3102  "Bribing the unit costs %1 gold.\n%2", cost))
3103  .arg(QString::number(cost), buf);
3104  ask->set_text_title(buf2, _("Traitors Demand Too Much!"));
3105  ask->setAttribute(Qt::WA_DeleteOnClose);
3106  ask->show();
3107  }
3108 
3109  diplomat_queue_handle_secondary(diplomat_id);
3110 }
3111 
3115 static void pillage_something(QVariant data1, QVariant data2)
3116 {
3117  int punit_id;
3118  int what;
3119  struct unit *punit;
3120  struct extra_type *target;
3121 
3122  what = data1.toInt();
3123  punit_id = data2.toInt();
3124  punit = game_unit_by_number(punit_id);
3125  if (punit) {
3126  target = extra_by_number(what);
3127  request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, target);
3128  }
3130 }
3131 
3135 static void user_action_unit_vs_unit(int actor_id, int target_id,
3136  action_id act_id)
3137 {
3138  if (nullptr != game_unit_by_number(actor_id)
3139  && nullptr != game_unit_by_number(target_id)) {
3140  request_do_action(act_id, actor_id, target_id, 0, "");
3141  }
3142 }
3143 
3147 static void user_action_unit_vs_city(int actor_id, int target_id,
3148  action_id act_id)
3149 {
3150  if (nullptr != game_unit_by_number(actor_id)
3151  && nullptr != game_city_by_number(target_id)) {
3152  request_do_action(act_id, actor_id, target_id, 0, "");
3153  }
3154 }
3155 
3159 static void user_action_unit_vs_tile(int actor_id, int target_id,
3160  action_id act_id)
3161 {
3162  if (nullptr != game_unit_by_number(actor_id)
3163  && nullptr != index_to_tile(&(wld.map), target_id)) {
3164  request_do_action(act_id, actor_id, target_id, 0, "");
3165  }
3166 }
3167 
3171 static void user_action_unit_vs_self(int actor_id, int target_id,
3172  action_id act_id)
3173 {
3174  if (nullptr != game_unit_by_number(actor_id)) {
3175  request_do_action(act_id, actor_id, target_id, 0, "");
3176  }
3177 }
3178 
3182 static void user_action(QVariant data1, QVariant data2, action_id act_id)
3183 {
3184  int actor_id = data1.toInt();
3185  int target_id = data2.toInt();
3186 
3187  switch (action_id_get_target_kind(act_id)) {
3188  case ATK_UNIT:
3189  user_action_unit_vs_unit(actor_id, target_id, act_id);
3190  break;
3191  case ATK_CITY:
3192  user_action_unit_vs_city(actor_id, target_id, act_id);
3193  break;
3194  case ATK_TILE:
3195  case ATK_UNITS:
3196  user_action_unit_vs_tile(actor_id, target_id, act_id);
3197  break;
3198  case ATK_SELF:
3199  user_action_unit_vs_self(actor_id, target_id, act_id);
3200  break;
3201  case ATK_COUNT:
3202  fc_assert_msg(ATK_COUNT != action_id_get_target_kind(act_id),
3203  "Bad target kind");
3204  break;
3205  }
3206 }
3207 
3211 static void user_action_1(QVariant data1, QVariant data2)
3212 {
3213  user_action(data1, data2, ACTION_USER_ACTION1);
3214 }
3215 
3219 static void user_action_2(QVariant data1, QVariant data2)
3220 {
3221  user_action(data1, data2, ACTION_USER_ACTION2);
3222 }
3223 
3227 static void user_action_3(QVariant data1, QVariant data2)
3228 {
3229  user_action(data1, data2, ACTION_USER_ACTION3);
3230 }
3231 
3235 static void spy_sabotage(QVariant data1, QVariant data2)
3236 {
3237  int diplomat_id = data1.toList().at(0).toInt();
3238  int diplomat_target_id = data1.toList().at(1).toInt();
3239  action_id act_id = data1.toList().at(2).toInt();
3240 
3241  if (nullptr != game_unit_by_number(diplomat_id)
3242  && nullptr != game_city_by_number(diplomat_target_id)) {
3243  if (data2.toInt() == B_LAST) {
3244  // This is the untargeted version.
3245  request_do_action(get_non_targeted_action_id(act_id), diplomat_id,
3246  diplomat_target_id, data2.toInt(), "");
3247  } else if (data2.toInt() == -1) {
3248  // This is the city production version.
3250  diplomat_id, diplomat_target_id, data2.toInt(), "");
3251  } else {
3252  // This is the targeted version.
3253  request_do_action(act_id, diplomat_id, diplomat_target_id,
3254  data2.toInt(), "");
3255  }
3256  }
3257 }
3258 
3263 void popup_sabotage_dialog(struct unit *actor, struct city *tcity,
3264  const struct action *paction)
3265 {
3266  QVariant qv1, qv2;
3267  int diplomat_id = actor->id;
3268  int diplomat_target_id = tcity->id;
3269  pfcn_void func;
3270  choice_dialog *cd = new choice_dialog(
3271  _("Sabotage"), _("Select Improvement to Sabotage"),
3272  queen()->game_tab_widget, diplomat_queue_handle_secondary);
3273  int nr = 0;
3274  QString stra;
3275  QList<QVariant> actor_and_target;
3276 
3277  // Should be set before sending request to the server.
3279 
3280  // Put both actor, target city and action in qv1 since qv2 is taken
3281  actor_and_target.append(diplomat_id);
3282  actor_and_target.append(diplomat_target_id);
3283  actor_and_target.append(paction->id);
3284  qv1 = QVariant::fromValue(actor_and_target);
3285 
3287  actor->client.act_prob_cache[get_production_targeted_action_id(
3288  paction->id)])) {
3289  func = spy_sabotage;
3290  cd->add_item(QString(_("City Production")), func, qv1, -1);
3291  }
3292 
3293  city_built_iterate(tcity, pimprove)
3294  {
3295  if (pimprove->sabotage > 0) {
3296  func = spy_sabotage;
3297  stra = QString(city_improvement_name_translation(tcity, pimprove));
3298  qv2 = nr;
3299  cd->add_item(stra, func, qv1, improvement_number(pimprove));
3300  nr++;
3301  }
3302  }
3304 
3306  actor->client
3307  .act_prob_cache[get_non_targeted_action_id(paction->id)])) {
3308  stra =
3309  QString(_("At %1's Discretion")).arg(unit_name_translation(actor));
3310  func = spy_sabotage;
3311  cd->add_item(stra, func, qv1, B_LAST);
3312  }
3313  cd->set_layout();
3314  cd->show_me();
3315 }
3316 
3321 void popup_pillage_dialog(struct unit *punit, bv_extras extras)
3322 {
3323  QString str;
3324  QVariant qv1, qv2;
3325  pfcn_void func;
3326  choice_dialog *cd;
3327  struct extra_type *tgt;
3328 
3330  return;
3331  }
3332  cd = new choice_dialog(_("What To Pillage"), _("Select what to pillage:"),
3333  queen()->game_tab_widget);
3334  qv2 = punit->id;
3335  while ((tgt = get_preferred_pillage(extras))) {
3336  int what;
3337 
3338  what = extra_index(tgt);
3339  BV_CLR(extras, what);
3340 
3342  str = QString(extra_name_translation(tgt));
3343  qv1 = what;
3344  cd->add_item(str, func, qv1, qv2);
3345  }
3346  cd->set_layout();
3347  cd->show_me();
3348 }
3349 
3353 disband_box::disband_box(const std::vector<unit *> &punits, QWidget *parent)
3354  : hud_message_box(parent), cpunits(punits)
3355 {
3356  QString str;
3357  QPushButton *pb;
3358 
3359  setAttribute(Qt::WA_DeleteOnClose);
3360  setModal(false);
3361 
3362  str = QString(PL_("Are you sure you want to disband that %1 unit?",
3363  "Are you sure you want to disband those %1 units?",
3364  punits.size()))
3365  .arg(punits.size());
3366  pb = addButton(_("Yes"), QMessageBox::AcceptRole);
3367  addButton(_("No"), QMessageBox::RejectRole);
3368  set_text_title(str, _("Disband units"));
3369  setDefaultButton(pb);
3370  connect(pb, &QAbstractButton::clicked, this,
3372  pb->show();
3373 }
3374 
3379 {
3380  for (const auto punit : cpunits) {
3381  if (unit_can_do_action(punit, ACTION_DISBAND_UNIT)) {
3382  request_unit_disband(punit);
3383  }
3384  }
3385 }
3386 
3390 disband_box::~disband_box() = default;
3391 
3395 void popup_disband_dialog(const std::vector<unit *> &punits)
3396 {
3397  disband_box *ask = new disband_box(punits, king()->central_wdg);
3398  ask->show();
3399 }
3400 
3406 {
3407  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3408  QString text;
3409  QString title;
3410 
3411  title = QString(_("Modpack suggests using %1 tileset."))
3412  .arg(game.control.preferred_tileset);
3413  text = QStringLiteral("It might not work with other tilesets.\n"
3414  "You are currently using tileset %1.")
3415  .arg(tileset_basename(tileset));
3416  ask->addButton(_("Keep current tileset"), QMessageBox::RejectRole);
3417  ask->addButton(_("Load tileset"), QMessageBox::AcceptRole);
3418  ask->set_text_title(text, title);
3419  ask->setAttribute(Qt::WA_DeleteOnClose);
3420 
3421  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3422  forced_tileset_name = game.control.preferred_tileset;
3423  if (!tilespec_reread(game.control.preferred_tileset, true)) {
3424  tileset_error(nullptr, LOG_ERROR,
3425  _("Can't load requested tileset %s."),
3426  game.control.preferred_tileset);
3427  }
3428  });
3429  ask->show();
3430 }
3431 
3437 {
3438  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3439  QString text;
3440  QString title;
3441 
3442  title = QString(_("Modpack suggests using %1 soundset."))
3443  .arg(game.control.preferred_soundset);
3444  text = QStringLiteral("It might not work with other tilesets.\n"
3445  "You are currently using soundset %1.")
3446  .arg(sound_set_name);
3447  ask->addButton(_("Keep current soundset"), QMessageBox::RejectRole);
3448  ask->addButton(_("Load soundset"), QMessageBox::AcceptRole);
3449  ask->set_text_title(text, title);
3450  ask->setAttribute(Qt::WA_DeleteOnClose);
3451  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3452  audio_restart(game.control.preferred_soundset, music_set_name);
3453  });
3454  ask->show();
3455 }
3456 
3462 {
3463  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3464  QString text;
3465  QString title;
3466 
3467  title = QString(_("Modpack suggests using %1 musicset."))
3468  .arg(game.control.preferred_musicset);
3469  text = QStringLiteral("It might not work with other tilesets.\n"
3470  "You are currently using musicset %1.")
3471  .arg(music_set_name);
3472  ask->addButton(_("Keep current musicset"), QMessageBox::RejectRole);
3473  ask->addButton(_("Load musicset"), QMessageBox::AcceptRole);
3474  ask->set_text_title(text, title);
3475  ask->setAttribute(Qt::WA_DeleteOnClose);
3476  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3477  audio_restart(sound_set_name, game.control.preferred_musicset);
3478  });
3479  ask->show();
3480 }
3481 
3486 bool popup_theme_suggestion_dialog(const char *theme_name)
3487 {
3488  Q_UNUSED(theme_name)
3489  return false;
3490 }
3491 
3497 {
3498  int i;
3499  QList<choice_dialog *> cd_list;
3500  QList<freeciv::report_widget *> nd_list;
3501 
3502  QApplication::alert(king()->central_wdg);
3503  cd_list = queen()->game_tab_widget->findChildren<choice_dialog *>();
3504  for (i = 0; i < cd_list.count(); i++) {
3505  cd_list[i]->close();
3506  }
3507  nd_list =
3508  queen()->game_tab_widget->findChildren<freeciv::report_widget *>();
3509  for (i = 0; i < nd_list.count(); i++) {
3510  nd_list[i]->close();
3511  }
3512 
3520  popdown_unit_sel();
3521 }
3522 
3529 {
3530  choice_dialog *cd = king()->get_diplo_dialog();
3531 
3532  if (cd != nullptr) {
3533  return cd->unit_id;
3534  } else {
3535  return IDENTITY_NUMBER_ZERO;
3536  }
3537 }
3538 
3546 {
3547  choice_dialog *cd = king()->get_diplo_dialog();
3548 
3549  if (cd != nullptr) {
3550  return cd->target_id[ATK_CITY];
3551  } else {
3552  return IDENTITY_NUMBER_ZERO;
3553  }
3554 }
3555 
3563 {
3564  choice_dialog *cd = king()->get_diplo_dialog();
3565 
3566  if (cd != nullptr) {
3567  return cd->target_id[ATK_TILE];
3568  } else {
3569  return TILE_INDEX_NONE;
3570  }
3571 }
3572 
3580 {
3581  choice_dialog *cd = king()->get_diplo_dialog();
3582 
3583  if (cd != nullptr) {
3584  return cd->sub_target_id[ASTK_EXTRA];
3585  } else {
3586  return EXTRA_NONE;
3587  }
3588 }
3589 
3597 {
3598  choice_dialog *cd = king()->get_diplo_dialog();
3599 
3600  if (cd != nullptr) {
3601  return cd->target_id[ATK_UNIT];
3602  } else {
3603  return IDENTITY_NUMBER_ZERO;
3604  }
3605 }
3606 
3610 void action_selection_refresh(struct unit *actor_unit,
3611  struct city *target_city,
3612  struct unit *target_unit,
3613  struct tile *target_tile,
3614  struct extra_type *target_extra,
3615  const struct act_prob *act_probs)
3616 {
3617  Q_UNUSED(target_extra)
3618  choice_dialog *asd;
3619  Choice_dialog_button *keep_moving_button;
3620  Choice_dialog_button *wait_button;
3621  Choice_dialog_button *cancel_button;
3622  QVariant qv1, qv2;
3623 
3624  asd = king()->get_diplo_dialog();
3625  if (asd == nullptr) {
3626  fc_assert_msg(asd != nullptr,
3627  "The action selection dialog should have been open");
3628  return;
3629  }
3630 
3631  if (actor_unit->id != action_selection_actor_unit()) {
3632  fc_assert_msg(actor_unit->id == action_selection_actor_unit(),
3633  "The action selection dialog is for another actor unit.");
3634  }
3635 
3636  // Put the actor id in qv1.
3637  qv1 = actor_unit->id;
3638 
3639  cancel_button = asd->get_identified_button(BUTTON_CANCEL);
3640  if (cancel_button != nullptr) {
3641  /* Temporary remove the Cancel button so it won't end up above
3642  * any added buttons. */
3643  asd->stack_button(cancel_button);
3644  }
3645 
3646  wait_button = asd->get_identified_button(BUTTON_WAIT);
3647  if (wait_button != nullptr) {
3648  /* Temporary remove the Wait button so it won't end up above
3649  * any added buttons. */
3650  asd->stack_button(wait_button);
3651  }
3652 
3653  keep_moving_button = asd->get_identified_button(BUTTON_MOVE);
3654  if (keep_moving_button != nullptr) {
3655  /* Temporary remove the Keep moving button so it won't end up above
3656  * any added buttons. */
3657  asd->stack_button(keep_moving_button);
3658  }
3659 
3660  action_iterate(act)
3661  {
3662  QString custom;
3663 
3664  if (action_id_get_actor_kind(act) != AAK_UNIT) {
3665  // Not relevant.
3666  continue;
3667  }
3668 
3670  action_by_number(act), act_probs[act], actor_unit, target_city);
3671 
3672  // Put the target id in qv2.
3673  switch (action_id_get_target_kind(act)) {
3674  case ATK_UNIT:
3675  if (target_unit != nullptr) {
3676  qv2 = target_unit->id;
3677  } else {
3678  fc_assert_msg(!action_prob_possible(act_probs[act])
3679  || target_unit != nullptr,
3680  "Action enabled against non existing unit!");
3681 
3682  qv2 = IDENTITY_NUMBER_ZERO;
3683  }
3684  break;
3685  case ATK_CITY:
3686  if (target_city != nullptr) {
3687  qv2 = target_city->id;
3688  } else {
3689  fc_assert_msg(!action_prob_possible(act_probs[act])
3690  || target_city != nullptr,
3691  "Action enabled against non existing city!");
3692 
3693  qv2 = IDENTITY_NUMBER_ZERO;
3694  }
3695  break;
3696  case ATK_TILE:
3697  case ATK_UNITS:
3698  if (target_tile != nullptr) {
3699  qv2 = tile_index(target_tile);
3700  } else {
3701  fc_assert_msg(!action_prob_possible(act_probs[act])
3702  || target_tile != nullptr,
3703  "Action enabled against all units on "
3704  "non existing tile!");
3705 
3706  qv2 = TILE_INDEX_NONE;
3707  }
3708  break;
3709  case ATK_SELF:
3710  qv2 = actor_unit->id;
3711  break;
3712  case ATK_COUNT:
3713  fc_assert_msg(ATK_COUNT != action_id_get_target_kind(act),
3714  "Bad target kind");
3715  continue;
3716  }
3717 
3718  if (asd->get_identified_button(act)) {
3719  // Update the existing button.
3720  action_entry_update(asd->get_identified_button(act), act, act_probs,
3721  custom, qv1, qv2);
3722  } else {
3723  // Add the button (unless its probability is 0).
3724  action_entry(asd, act, act_probs, custom, qv1, qv2);
3725  }
3726  }
3728 
3729  if (keep_moving_button != nullptr || wait_button != nullptr
3730  || cancel_button != nullptr) {
3731  /* Reinsert the "Keep moving" button below any potential
3732  * buttons recently added. */
3733  asd->unstack_all_buttons();
3734  }
3735 }
3736 
3741 {
3742  choice_dialog *cd;
3743 
3744  cd = king()->get_diplo_dialog();
3745  if (cd != nullptr) {
3746  did_not_decide = true;
3747  cd->close();
3748  }
3749 }
3750 
3754 void show_tech_gained_dialog(Tech_type_id tech) { Q_UNUSED(tech) }
3755 
3759 void popup_upgrade_dialog(const std::vector<unit *> &punits)
3760 {
3761  char buf[512];
3762  hud_message_box *ask = new hud_message_box(king()->central_wdg);
3763  QString title;
3764  QVector<int> *punit_ids;
3765 
3766  if (punits.empty()) {
3767  return;
3768  }
3769 
3770  punit_ids = new QVector<int>();
3771  for (const auto punit : punits) {
3772  punit_ids->push_back(punit->id);
3773  }
3774 
3775  if (!get_units_upgrade_info(buf, sizeof(buf), punits)) {
3776  title = _("Upgrade Unit!");
3777  ask->setStandardButtons(QMessageBox::Ok);
3778  } else {
3779  title = _("Upgrade Obsolete Units");
3780  ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
3781  ask->setDefaultButton(QMessageBox::Cancel);
3782  ask->button(QMessageBox::Yes)->setText(_("Yes Upgrade"));
3783  }
3784  ask->set_text_title(buf, title);
3785  ask->setAttribute(Qt::WA_DeleteOnClose);
3786  QObject::connect(ask, &hud_message_box::accepted, [=]() {
3787  std::unique_ptr<QVector<int>> uptr(punit_ids);
3788  QVector<int> not_ptr = *uptr;
3789  struct unit *punit;
3790 
3791  for (int id : not_ptr) {
3792  punit = game_unit_by_number(id);
3793  if (punit) {
3794  request_unit_upgrade(punit);
3795  }
3796  }
3797  });
3798  ask->show();
3799 }
3800 
3805 {
3806  opened_dialog = widget;
3807 }
3808 
3813 
3819 {
3820  // Just tell the client common code to handle this.
3821  return false;
3822 }
3823 
3827 bool request_transport(struct unit *pcargo, struct tile *ptile)
3828 {
3829  int tcount;
3830  hud_unit_loader *hul;
3831  struct unit_list *potential_transports = unit_list_new();
3832  struct unit *best_transport = transporter_for_unit_at(pcargo, ptile);
3833 
3834  unit_list_iterate(ptile->units, ptransport)
3835  {
3836  if (can_unit_transport(ptransport, pcargo)
3837  && get_transporter_occupancy(ptransport)
3838  < get_transporter_capacity(ptransport)) {
3839  unit_list_append(potential_transports, ptransport);
3840  }
3841  }
3843 
3844  tcount = unit_list_size(potential_transports);
3845 
3846  if (tcount == 0) {
3847  fc_assert(best_transport == nullptr);
3848  unit_list_destroy(potential_transports);
3849 
3850  return false; // Unit was not handled here.
3851  } else if (tcount == 1) {
3852  // There's exactly one potential transport - use it automatically
3853  fc_assert(unit_list_get(potential_transports, 0) == best_transport);
3854  request_unit_load(pcargo, unit_list_get(potential_transports, 0), ptile);
3855 
3856  unit_list_destroy(potential_transports);
3857 
3858  return true;
3859  }
3860 
3861  hul = new hud_unit_loader(pcargo, ptile);
3862  hul->show_me();
3863  unit_list_destroy(potential_transports);
3864  return true;
3865 }
3866 
3871 void popup_combat_info(int attacker_unit_id, int defender_unit_id,
3872  int attacker_hp, int defender_hp,
3873  bool make_att_veteran, bool make_def_veteran)
3874 {
3875  if (king()->qt_settings.show_battle_log) {
3876  hud_unit_combat *huc = new hud_unit_combat(
3877  attacker_unit_id, defender_unit_id, attacker_hp, defender_hp,
3878  make_att_veteran, make_def_veteran, queen()->battlelog_wdg->scale,
3879  queen()->battlelog_wdg);
3880 
3882  queen()->battlelog_wdg->show();
3883  }
3884 }
const QString action_prepare_ui_name(action_id act_id, const char *mnemonic, const struct act_prob prob, const QString &custom)
Get the UI name ready to show the action in the UI.
Definition: actions.cpp:1412
bool action_prob_possible(const struct act_prob probability)
Returns TRUE iff the given action probability belongs to an action that may be possible.
Definition: actions.cpp:5380
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
#define action_iterate_end
Definition: actions.h:383
#define action_id_get_actor_kind(act_id)
Definition: actions.h:519
#define action_iterate(_act_)
Definition: actions.h:378
#define action_id_get_target_kind(act_id)
Definition: actions.h:522
#define ACTION_NONE
Definition: actions.h:220
QString break_lines(const QString &src, int after)
Definition: astring.cpp:68
void audio_restart(const QString &soundset_name, const QString &musicset_name)
Switch soundset.
Definition: audio.cpp:343
#define BV_CLR(bv, bit)
Definition: bitvector.h:49
void output_window_append(const struct ft_color color, const char *featured_text)
Add a line of text to the output ("chatline") window, like puts() would do it in the console.
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Return the extended name of the building.
Definition: city.cpp:635
#define INCITE_IMPOSSIBLE_COST
Definition: city.h:69
#define city_built_iterate(_pcity, _p)
Definition: city.h:752
#define city_built_iterate_end
Definition: city.h:759
void real_city_dialog_popup(struct city *pcity)
Pop up (or bring to the front) a dialog for the given city.
Definition: citydlg.cpp:2247
pfcn_void func
Definition: dialogs.h:167
QVariant getData2()
Get the second piece of data to feed the function when the button is pressed.
Definition: dialogs.cpp:1124
Choice_dialog_button(const QString title, pfcn_void func_in, QVariant data1_in, QVariant data2_in)
Constructor for choice_dialog_button_data.
Definition: dialogs.cpp:1100
void setData2(QVariant wariat)
Sets the second piece of data.
Definition: dialogs.cpp:1134
void setData1(QVariant wariat)
Sets the first piece of data.
Definition: dialogs.cpp:1129
QVariant getData1()
Get the first piece of data to feed the function when the button is pressed.
Definition: dialogs.cpp:1118
pfcn_void getFunc()
Get the function to call when the button is pressed.
Definition: dialogs.cpp:1112
Definition: shared.h:24
void stack_button(Choice_dialog_button *button)
Put the button in the stack and temporarily remove it.
Definition: dialogs.cpp:1458
void prev_unit()
Focus previous target.
Definition: dialogs.cpp:1374
QVBoxLayout * layout
Definition: dialogs.h:186
struct unit * targeted_unit
Definition: dialogs.h:210
void unstack_all_buttons()
Put all the buttons in the stack back to the dialog.
Definition: dialogs.cpp:1475
Choice_dialog_button * get_identified_button(const int id)
Get the button with the given identity.
Definition: dialogs.cpp:1284
QPushButton * target_unit_button
Definition: dialogs.h:185
void set_layout()
Sets layout for choice dialog.
Definition: dialogs.cpp:1191
void update_dialog(const struct act_prob *act_probs)
Update dialog for new target (targeted_unit)
Definition: dialogs.cpp:1405
QList< Choice_dialog_button * > last_buttons_stack
Definition: dialogs.h:189
~choice_dialog() override
Destructor for choice dialog.
Definition: dialogs.cpp:1176
void next_unit()
Focus next target.
Definition: dialogs.cpp:1332
void show_me()
Shows choice dialog.
Definition: dialogs.cpp:1265
QVBoxLayout * get_layout()
Returns layout in choice dialog.
Definition: dialogs.cpp:1279
QHBoxLayout * unit_skip
Definition: dialogs.h:187
QList< Choice_dialog_button * > buttons_list
Definition: dialogs.h:188
void(* run_on_close)(int)
Definition: dialogs.h:191
choice_dialog(const QString title, const QString text, QWidget *parent=nullptr, void(*run_on_close_in)(int)=nullptr)
Constructor for choice_dialog.
Definition: dialogs.cpp:1139
int target_id[ATK_COUNT]
Definition: dialogs.h:208
void switch_target()
Switches target unit.
Definition: dialogs.cpp:1425
QList< Choice_dialog_button * > action_button_map
Definition: dialogs.h:190
int sub_target_id[ASTK_COUNT]
Definition: dialogs.h:209
void execute_action(const int action)
Run chosen action and close dialog.
Definition: dialogs.cpp:1441
void add_item(QString title, pfcn_void func, QVariant data1, QVariant data2, QString tool_tip, const int button_id)
Adds new action for choice dialog.
Definition: dialogs.cpp:1236
void disband_clicked()
Clicked Yes in disband box.
Definition: dialogs.cpp:3378
const std::vector< unit * > cpunits
Definition: dialogs.h:90
disband_box(const std::vector< unit * > &punits, QWidget *parent=0)
Disband Message box contructor.
Definition: dialogs.cpp:3353
~disband_box() override
Destructor for disband box.
QPixmap * getPixmap(const QString &id)
Returns pixmap by given name, pixmap needs to be deleted by someone else.
Definition: icons.cpp:166
static fcIcons * instance()
Returns instance of fc_icons.
Definition: icons.cpp:36
trade_generator trade_gen
Definition: fc_client.h:129
choice_dialog * opened_dialog
Definition: fc_client.h:106
choice_dialog * get_diplo_dialog()
Get current diplo dialog.
Definition: dialogs.cpp:3812
void set_diplo_dialog(choice_dialog *widget)
Set current diplo dialog.
Definition: dialogs.cpp:3804
QPixmap sample_sprite(int style_index=0) const
Returns an example of what a city might look like.
Definition: layer_city.h:46
Widget used to display the demographics, top 5 cities, and travelers' reports.
Definition: report_widget.h:20
void add_combat_info(hud_unit_combat *huc)
Adds combat information to battle log.
Definition: hudwidget.cpp:1646
void set_text_title(const QString &s1, const QString &s2)
Sets text and title and shows message box.
Definition: hudwidget.cpp:117
void show_me()
Shows unit loader, adds possible tranportsand units to table Calculates table size.
Definition: hudwidget.cpp:1182
void center_on_tile(tile *tile, bool animate=true)
Centers the view on a tile.
Definition: view_map.cpp:197
QPushButton * close_but
Definition: dialogs.h:107
notify_goto(const char *headline, const char *lines, const struct text_tag_list *tags, struct tile *ptile, QWidget *parent)
Notify goto dialog constructor.
Definition: dialogs.cpp:862
QPushButton * goto_but
Definition: dialogs.h:105
void inspect_city()
Clicked inspect city in notify goto dialog.
Definition: dialogs.cpp:909
struct tile * gtile
Definition: dialogs.h:108
QPushButton * inspect_but
Definition: dialogs.h:106
void goto_tile()
Clicked goto tile in notify goto dialog.
Definition: dialogs.cpp:900
map_view * mapview_wdg
Definition: page_game.h:81
hud_battle_log * battlelog_wdg
Definition: page_game.h:76
fc_game_tab_widget * game_tab_widget
Definition: page_game.h:72
qdef_act()
Default actions provider constructor.
Definition: dialogs.cpp:802
action_id vs_unit
Definition: dialogs.h:52
static qdef_act * action()
Returns instance of qdef_act.
Definition: dialogs.cpp:807
action_id vs_city_get()
Returns default action vs city.
Definition: dialogs.cpp:837
static qdef_act * m_instance
Definition: dialogs.h:50
static void drop()
Deletes qdef_act instance.
Definition: dialogs.cpp:818
action_id vs_city
Definition: dialogs.h:51
void vs_city_set(int i)
Sets default action vs city.
Definition: dialogs.cpp:827
void vs_unit_set(int i)
Sets default action vs unit.
Definition: dialogs.cpp:832
action_id vs_unit_get()
Returns default action vs unit.
Definition: dialogs.cpp:842
QPoint point
Definition: dialogs.h:74
void mouseReleaseEvent(QMouseEvent *event) override
Mouse release event for themed dialog.
Definition: dialogs.cpp:357
int titlebar_height
Definition: dialogs.h:73
void mouseMoveEvent(QMouseEvent *event) override
Mouse move event for themed titlebar (moves dialog with left mouse)
Definition: dialogs.cpp:331
QPixmap * close_pix
Definition: dialogs.h:76
~qfc_dialog() override
Definition: dialogs.cpp:283
qfc_dialog(QWidget *parent)
Constructor for custom dialog with themed titlebar.
Definition: dialogs.cpp:274
void mousePressEvent(QMouseEvent *event) override
Mouse press event - catches left click.
Definition: dialogs.cpp:341
void paintEvent(QPaintEvent *event) override
Paint event for themed dialog.
Definition: dialogs.cpp:288
bool moving_now
Definition: dialogs.h:75
int selected_style
Definition: dialogs.h:157
QComboBox * leader_name
Definition: dialogs.h:129
void random_pressed()
Sets random nation.
Definition: dialogs.cpp:852
void style_selected(const QItemSelection &sl, const QItemSelection &ds)
Sets selected style.
Definition: dialogs.cpp:731
int last_index
Definition: dialogs.h:159
QTableWidget * selected_nation_tabs
Definition: dialogs.h:128
QPushButton * random_button
Definition: dialogs.h:136
~races_dialog() override
Destructor for races dialog.
Definition: dialogs.cpp:540
void refresh()
Sets first index to call update of nation list.
Definition: dialogs.cpp:545
void nation_selected(const QItemSelection &sl, const QItemSelection &ds)
Sets selected nation and updates style and leaders selector.
Definition: dialogs.cpp:673
void nationset_changed(int index)
User changed nation_set.
Definition: dialogs.cpp:921
int selected_nation
Definition: dialogs.h:156
void ok_pressed()
Button accepting all selection has been pressed, closes dialog if everything is ok.
Definition: dialogs.cpp:766
void leader_selected(int index)
Sets selected leader.
Definition: dialogs.cpp:751
QPushButton * ok_button
Definition: dialogs.h:135
QTextEdit * description
Definition: dialogs.h:134
void group_selected(const QItemSelection &sl, const QItemSelection &ds)
Selected group of nation.
Definition: dialogs.cpp:605
void set_index(int index)
Sets new nations' group by current current selection, index is used only when there is no current sel...
Definition: dialogs.cpp:623
QComboBox * qnation_set
Definition: dialogs.h:130
QRadioButton * is_male
Definition: dialogs.h:131
void update_nationset_combo()
Updates nation_set combo ( usually called from option change )
Definition: dialogs.cpp:589
QTableWidget * styles
Definition: dialogs.h:133
struct player * tplayer
Definition: dialogs.h:158
races_dialog(struct player *pplayer, QWidget *parent=0)
Constructor for selecting nations.
Definition: dialogs.cpp:367
QRadioButton * is_female
Definition: dialogs.h:132
QTableWidget * nation_tabs
Definition: dialogs.h:126
QGridLayout * main_layout
Definition: dialogs.h:125
void cancel_pressed()
Button canceling all selections has been pressed.
Definition: dialogs.cpp:847
QList< qtiles > lines
enum client_states client_state()
Return current client state.
struct player * client_player()
Either controlling or observing.
struct civclient client
QString music_set_name
QString sound_set_name
@ C_S_RUNNING
Definition: client_main.h:43
void client_unit_init_act_prob_cache(struct unit *punit)
Initialize the action probability cache.
Definition: climisc.cpp:1069
char * extras
Definition: comments.cpp:34
void request_unit_non_action_move(struct unit *punit, struct tile *dest_tile)
Order a unit to move to a neighboring tile without performing an action.
Definition: control.cpp:1618
void action_selection_no_longer_in_progress(const int old_actor_id)
The action selection process is no longer in progres for the specified unit.
Definition: control.cpp:924
void key_unit_wait()
Handle user 'wait' input.
Definition: control.cpp:2937
void request_unit_load(struct unit *pcargo, struct unit *ptrans, struct tile *ptile)
Send a request to the server that the cargo be loaded into the transporter.
Definition: control.cpp:1934
void request_do_action(action_id action, int actor_id, int target_id, int sub_tgt, const char *name)
Request an actor unit to do a specific action.
Definition: control.cpp:1563
void request_unit_disband(struct unit *punit)
Send request to disband unit to server.
Definition: control.cpp:1853
void request_action_details(action_id action, int actor_id, int target_id)
Request data for follow up questions about an action the unit can perform.
Definition: control.cpp:1582
void request_new_unit_activity_targeted(struct unit *punit, enum unit_activity act, struct extra_type *tgt)
Send request for unit activity changing to server.
Definition: control.cpp:1721
void action_decision_clear_want(const int old_actor_id)
Have the server record that a decision no longer is wanted for the specified unit.
Definition: control.cpp:944
void request_unit_upgrade(struct unit *punit)
Send request to upgrade unit to server.
Definition: control.cpp:1884
void action_selection_next_in_focus(const int old_actor_id)
Move on to the next unit in focus that needs an action decision.
Definition: control.cpp:958
static void attack(QVariant data1, QVariant data2)
Action "Attack" for choice dialog.
Definition: dialogs.cpp:2464
#define BUTTON_MOVE
Definition: dialogs.cpp:60
static void action_entry_update(Choice_dialog_button *button, action_id act, const struct act_prob *act_probs, const QString custom, QVariant data1, QVariant data2)
Update an existing button.
Definition: dialogs.cpp:2034
int action_selection_target_extra(void)
Returns id of the target extra of the actions currently handled in action selection dialog when the a...
Definition: dialogs.cpp:3579
static void destroy_city(QVariant data1, QVariant data2)
Action destroy city for choice dialog.
Definition: dialogs.cpp:2756
static void spy_sabotage_unit(QVariant data1, QVariant data2)
Action sabotage unit for choice dialog.
Definition: dialogs.cpp:2114
static void pillage(QVariant data1, QVariant data2)
Action "Pillage" for choice dialog.
Definition: dialogs.cpp:2320
static void caravan_marketplace(QVariant data1, QVariant data2)
Action enter market place for choice dialog.
Definition: dialogs.cpp:1489
static void clean_pollution(QVariant data1, QVariant data2)
Action "Clean Pollution" for choice dialog.
Definition: dialogs.cpp:2338
static void spy_steal_shared(QVariant data1, QVariant data2, action_id act_id)
Action steal tech with spy for choice dialog.
Definition: dialogs.cpp:2515
static void clean_fallout(QVariant data1, QVariant data2)
Action "Clean Fallout" for choice dialog.
Definition: dialogs.cpp:2356
static void spy_sabotage(QVariant data1, QVariant data2)
Action sabotage with spy for choice dialog.
Definition: dialogs.cpp:3235
int action_selection_target_tile(void)
Returns id of the target tile of the actions currently handled in action selection dialog when the ac...
Definition: dialogs.cpp:3562
static void spy_investigate(QVariant data1, QVariant data2)
Action investigate city for choice dialog.
Definition: dialogs.cpp:2861
static void act_sel_wait(QVariant data1, QVariant data2)
Delay selection of what action to take.
Definition: dialogs.cpp:1620
static void nuke_units(QVariant data1, QVariant data2)
Action "Nuke Units" for choice dialog.
Definition: dialogs.cpp:2220
int action_selection_actor_unit(void)
Returns the id of the actor unit currently handled in action selection dialog when the action selecti...
Definition: dialogs.cpp:3528
static void capture_units(QVariant data1, QVariant data2)
Action capture units for choice dialog.
Definition: dialogs.cpp:2231
static void road(QVariant data1, QVariant data2)
Action "Build Road" for choice dialog.
Definition: dialogs.cpp:2374
static bool is_race_dialog_open
Definition: dialogs.cpp:156
bool try_default_unit_action(QVariant q1, QVariant q2)
Try to pick up default unit action.
Definition: dialogs.cpp:1297
static void fortify(QVariant data1, QVariant data2)
Action "Fortify" for choice dialog.
Definition: dialogs.cpp:2071
static void transport_board(QVariant data1, QVariant data2)
Action "Transport Board" for choice dialog.
Definition: dialogs.cpp:2149
static void spy_sabotage_unit_esc(QVariant data1, QVariant data2)
Action Sabotage Unit Escape for choice dialog.
Definition: dialogs.cpp:2126
static const QHash< action_id, pfcn_void > af_map_init()
Initialize a mapping between an action and the function to call if the action's button is pushed.
Definition: dialogs.cpp:174
bool handmade_scenario_warning()
Give a warning when user is about to edit scenario with manually set properties.
Definition: dialogs.cpp:3818
static void disband_unit(QVariant data1, QVariant data2)
Action Disband Unit for choice dialog.
Definition: dialogs.cpp:2060
static void spy_steal_gold(QVariant data1, QVariant data2)
Action steal gold for choice dialog.
Definition: dialogs.cpp:2771
void popdown_players_report()
Closes players report.
static void mine(QVariant data1, QVariant data2)
Action "Build Mine" for choice dialog.
Definition: dialogs.cpp:2412
static void user_action_2(QVariant data1, QVariant data2)
User Action 2 for choice dialog.
Definition: dialogs.cpp:3219
void popup_musicset_suggestion_dialog(void)
Ruleset (modpack) has suggested loading certain musicset.
Definition: dialogs.cpp:3461
static void spy_steal_gold_esc(QVariant data1, QVariant data2)
Action steal gold escape for choice dialog.
Definition: dialogs.cpp:2786
static void diplomat_embassy(QVariant data1, QVariant data2)
Action establish embassy for choice dialog.
Definition: dialogs.cpp:2846
void unit_select_dialog_popup(struct tile *ptile)
Popup a dialog window to select units on a particular tile.
Definition: dialogs.cpp:1022
void update_nationset_combo()
Updates nationset combobox.
Definition: dialogs.cpp:1039
static void user_action_unit_vs_city(int actor_id, int target_id, action_id act_id)
User action with target kind ATK_CITY.
Definition: dialogs.cpp:3147
void action_selection_close(void)
Closes the action selection dialog.
Definition: dialogs.cpp:3740
static void cultivate(QVariant data1, QVariant data2)
Action "Cultivate" for choice dialog.
Definition: dialogs.cpp:2304
void races_update_pickable(bool nationset_change)
The server has changed the set of selectable nations.
Definition: dialogs.cpp:1049
int action_selection_target_city(void)
Returns id of the target city of the actions currently handled in action selection dialog when the ac...
Definition: dialogs.cpp:3545
static void spy_steal_something(QVariant data1, QVariant data2)
Action steal given tech for choice dialog.
Definition: dialogs.cpp:2603
#define BUTTON_WAIT
Definition: dialogs.cpp:61
void popup_notify_goto_dialog(const char *headline, const char *lines, const struct text_tag_list *tags, struct tile *ptile)
Popup a dialog to display information about an event that has a specific location.
Definition: dialogs.cpp:944
static void spy_poison(QVariant data1, QVariant data2)
Action Poison City for choice dialog.
Definition: dialogs.cpp:2682
void show_tech_gained_dialog(Tech_type_id tech)
Player has gained a new tech.
Definition: dialogs.cpp:3754
static void base(QVariant data1, QVariant data2)
Action "Build Base" for choice dialog.
Definition: dialogs.cpp:2393
static void spy_nuke_city_esc(QVariant data1, QVariant data2)
Action suitcase nuke escape for choice dialog.
Definition: dialogs.cpp:2727
void popup_soundset_suggestion_dialog(void)
Ruleset (modpack) has suggested loading certain soundset.
Definition: dialogs.cpp:3436
void popup_races_dialog(struct player *pplayer)
Popup the nation selection dialog.
Definition: dialogs.cpp:997
static void expel_unit(QVariant data1, QVariant data2)
Action expel unit for choice dialog.
Definition: dialogs.cpp:2242
static void diplomat_sabotage(QVariant data1, QVariant data2)
Action sabotage for choice dialog.
Definition: dialogs.cpp:2891
static action_id get_non_targeted_action_id(action_id tgt_action_id)
Get the non targeted version of an action so it, if enabled, can appear in the target selection dialo...
Definition: dialogs.cpp:1961
static void caravan_help_build(QVariant data1, QVariant data2)
Action help build wonder for choice dialog.
Definition: dialogs.cpp:1519
static void bombard(QVariant data1, QVariant data2)
Action "Bombard" for choice dialog.
Definition: dialogs.cpp:2253
void popdown_races_dialog(void)
Close the nation selection dialog.
Definition: dialogs.cpp:1011
void popup_tileset_suggestion_dialog(void)
Ruleset (modpack) has suggested loading certain tileset.
Definition: dialogs.cpp:3405
static void conquer_city(QVariant data1, QVariant data2)
Action "Conquer City" for choice dialog.
Definition: dialogs.cpp:1592
#define BUTTON_COUNT
Definition: dialogs.cpp:63
void popdown_economy_report()
Closes economy report.
static void join_city(QVariant data1, QVariant data2)
Action join city for choice dialog.
Definition: dialogs.cpp:2501
void action_selection_no_longer_in_progress_gui_specific(int actor_id)
Let the non shared client code know that the action selection process no longer is in progress for th...
Definition: dialogs.cpp:1697
static void spy_request_sabotage_list(QVariant data1, QVariant data2)
Action request sabotage list for choice dialog.
Definition: dialogs.cpp:2644
static void diplomat_bribe(QVariant data1, QVariant data2)
Action bribe unit for choice dialog.
Definition: dialogs.cpp:2095
static void spy_steal(QVariant data1, QVariant data2)
Action "Targeted Steal Tech" for choice dialog.
Definition: dialogs.cpp:2587
static void airlift(QVariant data1, QVariant data2)
Action "Airlift Unit" for choice dialog.
Definition: dialogs.cpp:1578
void popup_pillage_dialog(struct unit *punit, bv_extras extras)
Popup a dialog asking the unit which improvement they would like to pillage.
Definition: dialogs.cpp:3321
void popup_sabotage_dialog(struct unit *actor, struct city *tcity, const struct action *paction)
Popup a dialog asking a diplomatic unit if it wishes to sabotage the given enemy city.
Definition: dialogs.cpp:3263
static void transport_alight(QVariant data1, QVariant data2)
Action "Transport Alight" for choice dialog.
Definition: dialogs.cpp:2182
static void plant(QVariant data1, QVariant data2)
Action "Plant" for choice dialog.
Definition: dialogs.cpp:2312
static void nuke(QVariant data1, QVariant data2)
Action "Explode Nuclear" for choice dialog.
Definition: dialogs.cpp:2450
static void disembark2(QVariant data1, QVariant data2)
Action "Transport Disembark 2" for choice dialog.
Definition: dialogs.cpp:2212
void popup_upgrade_dialog(const std::vector< unit * > &punits)
Popup dialog for upgrade units.
Definition: dialogs.cpp:3759
void popup_bribe_dialog(struct unit *actor, struct unit *tunit, int cost, const struct action *paction)
Popup a dialog asking a diplomatic unit if it wishes to bribe the given enemy unit.
Definition: dialogs.cpp:3068
static void transport_unload(QVariant data1, QVariant data2)
Action "Transport Unload" for choice dialog.
Definition: dialogs.cpp:2171
void popup_notify_dialog(const char *caption, const char *headline, const char *lines)
Popup a generic dialog to display some generic information.
Definition: dialogs.cpp:970
void action_selection_refresh(struct unit *actor_unit, struct city *target_city, struct unit *target_unit, struct tile *target_tile, struct extra_type *target_extra, const struct act_prob *act_probs)
Updates the action selection dialog with new information.
Definition: dialogs.cpp:3610
void popdown_science_report()
Closes science report.
static void diplomat_steal(QVariant data1, QVariant data2)
Action steal with diplomat for choice dialog.
Definition: dialogs.cpp:2921
static void unit_upgrade(QVariant data1, QVariant data2)
Action "Upgrade Unit" for choice dialog.
Definition: dialogs.cpp:1562
bool popup_theme_suggestion_dialog(const char *theme_name)
Tileset (modpack) has suggested loading certain theme.
Definition: dialogs.cpp:3486
static void spy_request_strike_bld_list(QVariant data1, QVariant data2)
Action request "Surgical Strike Building" list for choice dialog.
Definition: dialogs.cpp:2626
static void diplomat_incite_escape(QVariant data1, QVariant data2)
Action incite revolt and escape for choice dialog.
Definition: dialogs.cpp:2970
static void found_city(QVariant data1, QVariant data2)
Action build city for choice dialog.
Definition: dialogs.cpp:2286
static void diplomat_investigate(QVariant data1, QVariant data2)
Action Investigate City Spend Unit for choice dialog.
Definition: dialogs.cpp:2876
static void bombard3(QVariant data1, QVariant data2)
Action "Bombard 3" for choice dialog.
Definition: dialogs.cpp:2275
static void action_entry(choice_dialog *cd, action_id act, const struct act_prob *act_probs, const QString custom, QVariant data1, QVariant data2)
Show the user the action if it is enabled.
Definition: dialogs.cpp:2004
static void diplomat_incite(QVariant data1, QVariant data2)
Action incite revolt for choice dialog.
Definition: dialogs.cpp:2951
bool request_transport(struct unit *pcargo, struct tile *ptile)
Unit wants to get into some transport on given tile.
Definition: dialogs.cpp:3827
void popdown_endgame_report()
Removes endgame report.
static void diplomat_steal_esc(QVariant data1, QVariant data2)
Action "Steal Tech Escape Expected" for choice dialog.
Definition: dialogs.cpp:2936
static bool is_more_user_input_needed
Definition: dialogs.cpp:161
static void bombard2(QVariant data1, QVariant data2)
Action "Bombard 2" for choice dialog.
Definition: dialogs.cpp:2264
void popup_incite_dialog(struct unit *actor, struct city *tcity, int cost, const struct action *paction)
Popup a window asking a diplomatic unit if it wishes to incite the given enemy city.
Definition: dialogs.cpp:3007
void popdown_all_spaceships_dialogs()
Close all spaceships dialogs.
static void nuke_city(QVariant data1, QVariant data2)
Action "Nuke City" for choice dialog.
Definition: dialogs.cpp:2742
static void user_action(QVariant data1, QVariant data2, action_id act_id)
User action handler, dispatches on target kind.
Definition: dialogs.cpp:3182
void popup_connect_msg(const char *headline, const char *message)
Popup a dialog to display connection message from server.
Definition: dialogs.cpp:956
static void diplomat_sabotage_esc(QVariant data1, QVariant data2)
Action sabotage and escape for choice dialog.
Definition: dialogs.cpp:2906
static void spy_nuke_city(QVariant data1, QVariant data2)
Action suitcase nuke for choice dialog.
Definition: dialogs.cpp:2712
static void unit_recycle(QVariant data1, QVariant data2)
Action Recycle Unit for choice dialog.
Definition: dialogs.cpp:1534
void unit_select_dialog_update_real(void *unused)
Update the dialog window to select units on a particular tile.
Definition: dialogs.cpp:1034
static void user_action_unit_vs_tile(int actor_id, int target_id, action_id act_id)
User action with target kind ATK_TILE or ATK_UNITS.
Definition: dialogs.cpp:3159
static void spy_steal_esc(QVariant data1, QVariant data2)
Action "Targeted Steal Tech Escape Expected" for choice dialog.
Definition: dialogs.cpp:2595
static void paradrop(QVariant data1, QVariant data2)
Action "Paradrop Unit" for choice dialog.
Definition: dialogs.cpp:2493
static void suicide_attack(QVariant data1, QVariant data2)
Action "Suicide Attack" for choice dialog.
Definition: dialogs.cpp:2478
void races_toggles_set_sensitive(void)
In the nation selection dialog, make already-taken nations unavailable.
Definition: dialogs.cpp:1061
static action_id get_production_targeted_action_id(action_id tgt_action_id)
Get the production targeted version of an action so it, if enabled, can appear in the target selectio...
Definition: dialogs.cpp:1984
static void convert_unit(QVariant data1, QVariant data2)
Action Convert Unit for choice dialog.
Definition: dialogs.cpp:2084
static bool did_not_decide
Definition: dialogs.cpp:165
static void spy_poison_esc(QVariant data1, QVariant data2)
Action Poison City Escape for choice dialog.
Definition: dialogs.cpp:2697
void popup_action_selection(struct unit *actor_unit, struct city *target_city, struct unit *target_unit, struct tile *target_tile, struct extra_type *target_extra, const struct act_prob *act_probs)
Popup a dialog that allows the player to select what action a unit should take.
Definition: dialogs.cpp:1708
static void pillage_something(QVariant data1, QVariant data2)
Action pillage for choice dialog.
Definition: dialogs.cpp:3115
static void spy_request_sabotage_esc_list(QVariant data1, QVariant data2)
Action request sabotage (and escape) list for choice dialog.
Definition: dialogs.cpp:2663
static void act_sel_keep_moving(QVariant data1, QVariant data2)
Action keep moving with actor unit for choice dialog.
Definition: dialogs.cpp:2989
static void transform_terrain(QVariant data1, QVariant data2)
Action "Transform Terrain" for choice dialog.
Definition: dialogs.cpp:2296
void popup_combat_info(int attacker_unit_id, int defender_unit_id, int attacker_hp, int defender_hp, bool make_att_veteran, bool make_def_veteran)
Popup detailed information about battle or save information for some kind of statistics.
Definition: dialogs.cpp:3871
#define BUTTON_CANCEL
Definition: dialogs.cpp:62
static void diplomat_queue_handle_primary(int actor_unit_id)
Move the queue of diplomats that need user input forward unless the current diplomat will need more i...
Definition: dialogs.cpp:1643
static void spy_embassy(QVariant data1, QVariant data2)
Action establish embassy for choice dialog.
Definition: dialogs.cpp:2831
static races_dialog * race_dialog
Definition: dialogs.cpp:155
static void do_that_action(QVariant data1, QVariant data2, enum gen_action a)
Definition: dialogs.cpp:2190
static void user_action_unit_vs_self(int actor_id, int target_id, action_id act_id)
User action with target kind ATK_SELF.
Definition: dialogs.cpp:3171
void revolution_response(struct government *government)
Starts revolution with targeted government as target or anarchy otherwise.
Definition: dialogs.cpp:1630
static void user_action_3(QVariant data1, QVariant data2)
User Action 3 for choice dialog.
Definition: dialogs.cpp:3227
static void user_action_unit_vs_unit(int actor_id, int target_id, action_id act_id)
User action with target kind ATK_UNIT.
Definition: dialogs.cpp:3135
static void diplomat_queue_handle_secondary(int actor_id)
Move the queue of diplomats that need user input forward since the current diplomat got the extra inp...
Definition: dialogs.cpp:1684
QString forced_tileset_name
static void conquer_city2(QVariant data1, QVariant data2)
Action "Conquer City 2" for choice dialog.
Definition: dialogs.cpp:1606
int action_selection_target_unit(void)
Returns id of the target unit of the actions currently handled in action selection dialog when the ac...
Definition: dialogs.cpp:3596
static void irrigate(QVariant data1, QVariant data2)
Action "Build Irrigation" for choice dialog.
Definition: dialogs.cpp:2431
static void heal_unit(QVariant data1, QVariant data2)
Action "Heal Unit" for choice dialog.
Definition: dialogs.cpp:2138
void popdown_city_report()
Closes city report.
void popup_revolution_dialog(struct government *government)
Popup a dialog asking if the player wants to start a revolution.
Definition: dialogs.cpp:1071
static void unit_home_city(QVariant data1, QVariant data2)
Action Home City for choice dialog.
Definition: dialogs.cpp:1548
static void transport_embark(QVariant data1, QVariant data2)
Action "Transport Embark" for choice dialog.
Definition: dialogs.cpp:2160
bool try_default_city_action(QVariant q1, QVariant q2)
Try to pick up default city action.
Definition: dialogs.cpp:1315
static void keep_moving(QVariant data1, QVariant data2)
Empty action for choice dialog (just do nothing)
Definition: dialogs.cpp:1625
static void spy_steal_maps_esc(QVariant data1, QVariant data2)
Action steal maps escape for choice dialog.
Definition: dialogs.cpp:2816
static void disembark1(QVariant data1, QVariant data2)
Action "Transport Disembark" for choice dialog.
Definition: dialogs.cpp:2204
void popup_disband_dialog(const std::vector< unit * > &punits)
Pops up a dialog to confirm disband of the unit(s).
Definition: dialogs.cpp:3395
static bool is_showing_pillage_dialog
Definition: dialogs.cpp:154
static const QHash< action_id, pfcn_void > af_map
Definition: dialogs.cpp:269
static void caravan_establish_trade(QVariant data1, QVariant data2)
Action establish trade for choice dialog.
Definition: dialogs.cpp:1504
void popdown_all_game_dialogs(void)
This function is called when the client disconnects or the game is over.
Definition: dialogs.cpp:3496
static void spy_steal_maps(QVariant data1, QVariant data2)
Action steal maps for choice dialog.
Definition: dialogs.cpp:2801
static void user_action_1(QVariant data1, QVariant data2)
User Action 1 for choice dialog.
Definition: dialogs.cpp:3211
void(* pfcn_void)(QVariant, QVariant)
Definition: dialogs.h:41
enum event_type event
Definition: events.cpp:68
struct extra_type * extra_by_number(int id)
Return extras type of given id.
Definition: extras.cpp:154
int extra_number(const struct extra_type *pextra)
Return the extra id.
Definition: extras.cpp:132
const char * extra_name_translation(const struct extra_type *pextra)
Return the (translated) name of the extra type.
Definition: extras.cpp:165
#define extra_index(_e_)
Definition: extras.h:163
#define EXTRA_NONE
Definition: extras.h:72
class fc_client * king()
Return fc_client instance.
Definition: gui_main.cpp:58
int Tech_type_id
Definition: fc_types.h:294
int action_id
Definition: fc_types.h:306
int Government_type_id
Definition: fc_types.h:298
#define IDENTITY_NUMBER_ZERO
Definition: fc_types.h:76
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_client
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
Definition: game.cpp:112
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
struct government * government_by_number(const Government_type_id gov)
Return the government with the given index.
Definition: government.cpp:96
Government_type_id government_number(const struct government *pgovern)
Return the government index.
Definition: government.cpp:84
void helptext_nation(char *buf, size_t bufsz, struct nation_type *pnation, const char *user_text)
Returns nation legend and characteristics.
Definition: helpdata.cpp:4653
void popdown_help_dialog(void)
Close the help dialog.
Definition: helpdlg.cpp:75
Impr_type_id improvement_number(const struct impr_type *pimprove)
Return the improvement index.
#define B_LAST
Definition: improvement.h:33
get_token_fn_t func
Definition: inputfile.cpp:119
#define fc_assert_msg(condition, message,...)
Definition: log.h:96
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_action(condition, action)
Definition: log.h:104
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
Definition: map.cpp:887
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
Definition: map.cpp:429
bool can_unit_transport(const struct unit *transporter, const struct unit *transported)
Return true iff transporter has ability to transport transported.
Definition: movement.cpp:684
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_enemy_city)
Returns whether the unit can move from its current tile to the destination tile.
Definition: movement.cpp:531
struct nation_type * nation_by_number(const Nation_type_id nation)
Return the nation with the given index.
Definition: nation.cpp:450
struct nation_style * style_of_nation(const struct nation_type *pnation)
Returns nation's style.
Definition: nation.cpp:558
const char * nation_set_name_translation(const struct nation_set *pset)
Return the translated name of a nation set.
Definition: nation.cpp:693
const char * nation_group_name_translation(const struct nation_group *pgroup)
Return the translated name of a nation group.
Definition: nation.cpp:953
bool nation_leader_is_male(const struct nation_leader *pleader)
Return the sex of the nation leader.
Definition: nation.cpp:266
int nation_set_count()
Return the number of nation sets.
Definition: nation.cpp:577
int nation_set_index(const struct nation_set *pset)
Return the nation set index.
Definition: nation.cpp:582
bool is_nation_pickable(const struct nation_type *nation)
Return whether a nation is "pickable" – whether players can select it at game start.
Definition: nation.cpp:165
std::vector< nation_type > nations
Definition: nation.cpp:38
bool is_nation_playable(const struct nation_type *nation)
Return whether a nation is "playable"; i.e., whether a human player can choose this nation.
Definition: nation.cpp:177
int nation_group_count()
Return the number of nation groups.
Definition: nation.cpp:809
struct nation_set * nation_set_by_setting_value(const char *setting)
Returns the nation set that would be selected by the given value of the 'nationset' server setting.
Definition: nation.cpp:736
const char * nation_adjective_translation(const struct nation_type *pnation)
Return the (translated) adjective for the given nation.
Definition: nation.cpp:126
bool nation_is_in_group(const struct nation_type *pnation, const struct nation_group *pgroup)
Check if the given nation is in a given group.
Definition: nation.cpp:962
const char * nation_set_rule_name(const struct nation_set *pset)
Return the (untranslated) rule name of a nation set.
Definition: nation.cpp:682
const char * nation_adjective_for_player(const struct player *pplayer)
Return the (translated) adjective for the given nation of a player.
Definition: nation.cpp:146
struct nation_group * nation_group_by_number(int id)
Return the nation group with the given index.
Definition: nation.cpp:870
const char * nation_set_description(const struct nation_set *pset)
Return the (untranslated) user description of a nation set.
Definition: nation.cpp:703
bool is_nation_group_hidden(struct nation_group *pgroup)
Return whether this group should appear in the nation selection UI.
Definition: nation.cpp:920
Nation_type_id nation_index(const struct nation_type *pnation)
Return the nation index.
Definition: nation.cpp:464
const char * nation_leader_name(const struct nation_leader *pleader)
Return the name of the nation leader.
Definition: nation.cpp:257
const struct nation_leader_list * nation_leaders(const struct nation_type *pnation)
Returns the list the nation leader names.
Definition: nation.cpp:206
struct nation_set * nation_set_by_rule_name(const char *name)
Return the nation set that has the given (untranslated) rule name.
Definition: nation.cpp:652
#define nation_leader_list_iterate(leaderlist, pleader)
Definition: nation.h:45
#define nation_sets_iterate_end
Definition: nation.h:286
#define nation_sets_iterate(NAME_pset)
Definition: nation.h:283
#define nation_leader_list_iterate_end
Definition: nation.h:47
const struct option_set * server_optset
Definition: options.cpp:2430
const char * option_str_get(const struct option *poption)
Returns the current value of this string option.
Definition: options.cpp:553
bool option_str_set(struct option *poption, const char *str)
Sets the value of this string option.
Definition: options.cpp:586
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Returns the option corresponding of the name in this option set.
Definition: options.cpp:110
char * caption
Definition: packhand.cpp:129
char * headline
Definition: packhand.cpp:130
void set_government_choice(struct government *government)
Sets the target government.
Definition: packhand.cpp:2252
char * lines
Definition: packhand.cpp:131
void start_revolution()
Begin a revolution by telling the server to start it.
Definition: packhand.cpp:2265
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
QString research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Store the translated name of the given tech (including A_FUTURE) in 'buf'.
Definition: research.cpp:257
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Returns TRUE iff the given tech can be given to the players sharing the research immediately.
Definition: research.cpp:686
action_id id
Definition: actions.h:306
Definition: city.h:291
int id
Definition: city.h:296
struct packet_ruleset_control control
Definition: game.h:74
struct packet_game_info info
Definition: game.h:80
struct connection conn
Definition: client_main.h:89
struct player * playing
Definition: connection.h:142
Definition: climisc.h:66
Functions for handling the nations.
Definition: nation.cpp:33
The base class for options.
Definition: options.cpp:209
Definition: player.h:231
int revolution_finishes
Definition: player.h:255
char name[MAX_LEN_NAME]
Definition: player.h:233
Definition: tile.h:42
int index
Definition: tile.h:43
struct unit_list * units
Definition: tile.h:50
Definition: unit.h:134
struct unit::@76::@78 client
int id
Definition: unit.h:141
struct tile * tile
Definition: unit.h:136
int homecity
Definition: unit.h:142
struct civ_map map
Definition: world_object.h:21
int style_number(const struct nation_style *pstyle)
Return the style id.
Definition: style.cpp:54
int basic_city_style_for_style(struct nation_style *pstyle)
Return basic city style representing nation style.
Definition: style.cpp:197
const char * style_name_translation(const struct nation_style *pstyle)
Return the (translated) name of the style.
Definition: style.cpp:85
#define styles_iterate(_p)
Definition: style.h:40
#define styles_iterate_end
Definition: style.h:46
#define advance_index_iterate_end
Definition: tech.h:226
#define A_FIRST
Definition: tech.h:37
#define A_UNSET
Definition: tech.h:41
#define advance_index_iterate(_start, _index)
Definition: tech.h:221
struct extra_type * get_preferred_pillage(bv_extras extras)
Returns the highest-priority (best) extra to be pillaged from the terrain set.
Definition: terrain.cpp:439
const QString get_act_sel_action_custom_text(struct action *paction, const struct act_prob prob, const struct unit *actor_unit, const struct city *target_city)
Returns custom part of the action selection dialog button text for the specified action (given that t...
Definition: text.cpp:1274
const QString act_sel_action_tool_tip(const struct action *paction, const struct act_prob prob)
Get information about starting the action in the current situation.
Definition: text.cpp:1333
bool get_units_upgrade_info(char *buf, size_t bufsz, const std::vector< unit * > &punits)
Return text about upgrading these unit lists.
Definition: text.cpp:1132
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define TILE_INDEX_NONE
Definition: tile.h:40
int tileset_unit_width(const struct tileset *t)
Return the unit tile width of the current tileset.
Definition: tilespec.cpp:426
bool tilespec_reread(const QString &name, bool game_fully_initialized)
Read a new tilespec in from scratch.
Definition: tilespec.cpp:916
int tileset_unit_height(const struct tileset *t)
Return the unit tile height of the current tileset.
Definition: tilespec.cpp:434
const freeciv::layer_city * tileset_layer_city(const struct tileset *t)
Returns the layer_city of the tileset.
Definition: tilespec.cpp:3665
const char * tileset_basename(const struct tileset *t)
Return the name of the given tileset.
Definition: tilespec.cpp:331
const QPixmap * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Return the sprite for the nation.
Definition: tilespec.cpp:3367
int get_transporter_occupancy(const struct unit *ptrans)
Return how many units are in the transport.
Definition: unit.cpp:1647
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Find the best transporter at the given location for the unit.
Definition: unit.cpp:1789
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Return TRUE iff this unit can do the specified generalized (ruleset defined) action enabler controlle...
Definition: unit.cpp:309
int get_transporter_capacity(const struct unit *punit)
Return the number of units the transporter can hold (or 0).
Definition: unit.cpp:280
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
void toggle_unit_sel_widget(struct tile *ptile)
Shows/closes unit selection widget.
Definition: unitselect.cpp:389
void update_unit_sel()
Update unit selection widget if open.
Definition: unitselect.cpp:406
void popdown_unit_sel()
Closes unit selection widget.
Definition: unitselect.cpp:419
const char * unit_name_translation(const struct unit *punit)
Return the (translated) name of the unit.
Definition: unittype.cpp:1265
void put_unit(const struct unit *punit, QPixmap *pcanvas, const QPoint &canvas_loc)
Draw the given unit onto the canvas store at the given location.