Freeciv21
Develop your civilization from humble roots to a global empire
packhand.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2023 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <fc_config.h>
15 
16 #include <QBitArray>
17 #include <QDateTime>
18 #include <cstring>
19 
20 // utility
21 #include "bitvector.h"
22 #include "fcintl.h"
23 #include "log.h"
24 #include "rand.h"
25 #include "support.h"
26 
27 // generated
28 #include "fc_version.h"
29 
30 // common
31 #include "achievements.h"
32 #include "actions.h"
33 #include "capability.h"
34 #include "capstr.h"
35 #include "citizens.h"
36 #include "events.h"
37 #include "extras.h"
38 #include "game.h"
39 #include "government.h"
40 #include "helpdata.h" // boot_help_texts()
41 #include "idex.h"
42 #include "map.h"
43 #include "movement.h"
44 #include "multipliers.h"
45 #include "name_translation.h"
46 #include "nation.h"
47 #include "packets.h"
48 #include "packhand_gen.h"
49 #include "player.h"
50 #include "research.h"
51 #include "rgbcolor.h"
52 #include "road.h"
53 #include "spaceship.h"
54 #include "specialist.h"
55 #include "style.h"
56 #include "tile.h"
57 #include "traderoutes.h"
58 #include "unit.h"
59 #include "unitlist.h"
60 #include "workertask.h"
61 #include "worklist.h"
62 
63 /* client/include */
64 #include "citydlg_g.h"
65 #include "cityrep_g.h"
66 #include "dialogs_g.h"
67 #include "gui_main_g.h"
68 #include "mapctrl_g.h" // popup_newcity_dialog()
69 #include "mapview_g.h"
70 #include "menu_g.h"
71 #include "pages_g.h"
72 #include "ratesdlg_g.h"
73 #include "repodlgs_g.h"
74 #include "spaceshipdlg_g.h"
75 #include "voteinfo_bar_g.h"
76 
77 // client
78 #include "attribute.h"
79 #include "audio/audio.h"
80 #include "chatline_common.h"
81 #include "citydlg.h"
82 #include "citydlg_common.h"
83 #include "client_main.h"
84 #include "climap.h"
85 #include "climisc.h"
86 #include "connectdlg_common.h"
87 #include "control.h"
88 #include "editor.h"
89 #include "goto.h" // client_goto_init()
90 #include "governor.h"
91 #include "helpdlg.h"
92 #include "messagewin_common.h"
93 #include "music.h"
94 #include "options.h"
95 #include "overview_common.h"
96 #include "page_game.h"
97 #include "qtg_cxxside.h"
98 #include "tileset/tilespec.h"
99 #include "update_queue.h"
100 #include "views/view_map.h"
101 #include "views/view_map_common.h"
102 #include "views/view_nations_data.h"
103 #include "voteinfo.h"
104 
105 /* client/luascript */
106 #include "script_client.h"
107 
108 #include "packhand.h"
109 
110 /* Define this macro to get additional debug output about the transport
111  * status of the units. */
112 #undef DEBUG_TRANSPORT
113 
114 static void city_packet_common(struct city *pcity, struct tile *pcenter,
115  struct player *powner,
116  struct tile_list *worked_tiles, bool is_new,
117  bool popup, bool investigate);
118 static bool handle_unit_packet_common(struct unit *packet_unit);
119 
120 // The dumbest of cities, placeholders for unknown and unseen cities.
121 static struct {
122  struct city_list *cities;
124 } invisible = {.cities = nullptr, .placeholder = nullptr};
125 
126 static struct {
127  int len;
128  enum event_type event;
129  char *caption;
130  char *headline;
131  char *lines;
132  int parts;
133 } page_msg_report = {.parts = 0};
134 
135 extern QString forced_tileset_name;
136 
137 static int last_turn = 0;
138 
143 {
144  if (nullptr != invisible.cities) {
145  city_list_iterate(invisible.cities, pcity)
146  {
147  idex_unregister_city(&wld, pcity);
148  destroy_city_virtual(pcity);
149  }
151 
152  city_list_destroy(invisible.cities);
153  invisible.cities = nullptr;
154  }
155 
156  if (nullptr != invisible.placeholder) {
157  delete invisible.placeholder;
158  invisible.placeholder = nullptr;
159  }
160 }
161 
165 static void packhand_init()
166 {
167  packhand_free();
168 
169  invisible.cities = city_list_new();
170 
171  // Can't use player_new() here, as it will register the player.
172  invisible.placeholder = new player();
173  // Set some values to prevent bugs ...
174  sz_strlcpy(invisible.placeholder->name, ANON_PLAYER_NAME);
175  sz_strlcpy(invisible.placeholder->username, _(ANON_USER_NAME));
176  invisible.placeholder->unassigned_user = true;
177  sz_strlcpy(invisible.placeholder->ranked_username, ANON_USER_NAME);
178  invisible.placeholder->unassigned_ranked = true;
179 }
180 
189 static struct unit *unpackage_unit(const struct packet_unit_info *packet)
190 {
191  struct unit *punit =
192  unit_virtual_create(player_by_number(packet->owner), nullptr,
193  utype_by_number(packet->type), packet->veteran);
194 
195  /* Owner, veteran, and type fields are already filled in by
196  * unit_virtual_create. */
197  punit->nationality = player_by_number(packet->nationality);
198  punit->id = packet->id;
199  unit_tile_set(punit, index_to_tile(&(wld.map), packet->tile));
200  punit->facing = packet->facing;
201  punit->homecity = packet->homecity;
202  punit->name =
203  QString::fromUtf8(QByteArray(packet->name, ARRAY_SIZE(packet->name)));
204  output_type_iterate(o) { punit->upkeep[o] = packet->upkeep[o]; }
206  punit->moves_left = packet->movesleft;
207  punit->hp = packet->hp;
208  punit->activity = packet->activity;
209  punit->activity_count = packet->activity_count;
210 
211  if (packet->activity_tgt == EXTRA_NONE) {
212  punit->activity_target = nullptr;
213  } else {
214  punit->activity_target = extra_by_number(packet->activity_tgt);
215  }
216 
217  punit->changed_from = packet->changed_from;
218  punit->changed_from_count = packet->changed_from_count;
219 
220  if (packet->changed_from_tgt == EXTRA_NONE) {
221  punit->changed_from_target = nullptr;
222  } else {
223  punit->changed_from_target = extra_by_number(packet->changed_from_tgt);
224  }
225 
226  punit->ssa_controller = packet->ssa_controller;
227  punit->fuel = packet->fuel;
228  punit->goto_tile = index_to_tile(&(wld.map), packet->goto_tile);
229  punit->paradropped = packet->paradropped;
230  punit->done_moving = packet->done_moving;
231  punit->stay = packet->stay;
232 
233  /* Transporter / transporting information. */
234  punit->client.occupied = packet->occupied;
235  if (packet->transported) {
236  punit->client.transported_by = packet->transported_by;
237  } else {
238  punit->client.transported_by = -1;
239  }
240  if (packet->carrying >= 0) {
241  punit->carrying = goods_by_number(packet->carrying);
242  } else {
243  punit->carrying = nullptr;
244  }
245 
246  punit->battlegroup = packet->battlegroup;
247  punit->has_orders = packet->has_orders;
248  punit->orders.length = packet->orders_length;
249  punit->orders.index = packet->orders_index;
250  punit->orders.repeat = packet->orders_repeat;
251  punit->orders.vigilant = packet->orders_vigilant;
252  if (punit->has_orders) {
253  int i;
254 
255  for (i = 0; i < packet->orders_length; i++) {
256  // Just an assert. The client doesn't use the action data.
257  fc_assert(packet->orders[i].order != ORDER_PERFORM_ACTION
258  || action_id_exists(packet->orders[i].action));
259  }
260 
261  punit->orders.list = new unit_order[punit->orders.length]();
262  memcpy(punit->orders.list, packet->orders,
263  punit->orders.length * sizeof(*punit->orders.list));
264  }
265  punit->action_turn = packet->action_turn;
266  punit->action_timestamp = packet->action_timestamp;
267 
268  // convert from UTC time when unit can move
269  QDateTime utctime;
270  utctime.setSecsSinceEpoch(punit->action_timestamp);
271  QDateTime localtime(utctime.toLocalTime());
272  punit->action_timestamp = localtime.toSecsSinceEpoch();
273 
274  punit->action_decision_want = packet->action_decision_want;
275  punit->action_decision_tile =
276  index_to_tile(&(wld.map), packet->action_decision_tile);
277 
278  punit->client.asking_city_name = false;
279 
280  return punit;
281 }
282 
293 static struct unit *
294 unpackage_short_unit(const struct packet_unit_short_info *packet)
295 {
296  struct unit *punit =
297  unit_virtual_create(player_by_number(packet->owner), nullptr,
298  utype_by_number(packet->type), false);
299 
300  // Owner and type fields are already filled in by unit_virtual_create.
301  punit->id = packet->id;
302  unit_tile_set(punit, index_to_tile(&(wld.map), packet->tile));
303  punit->facing = packet->facing;
304  punit->nationality = nullptr;
305  punit->veteran = packet->veteran;
306  punit->hp = packet->hp;
307  punit->activity = static_cast<unit_activity>(packet->activity);
308  punit->name =
309  QString::fromUtf8(QByteArray(packet->name, ARRAY_SIZE(packet->name)));
310 
311  if (packet->activity_tgt == EXTRA_NONE) {
312  punit->activity_target = nullptr;
313  } else {
314  punit->activity_target = extra_by_number(packet->activity_tgt);
315  }
316 
317  /* Transporter / transporting information. */
318  punit->client.occupied = packet->occupied;
319  if (packet->transported) {
320  punit->client.transported_by = packet->transported_by;
321  } else {
322  punit->client.transported_by = -1;
323  }
324 
325  return punit;
326 }
327 
332 void handle_server_join_reply(bool you_can_join, const char *message,
333  const char *capability,
334  const char *challenge_file, int conn_id)
335 {
336  const char *s_capability = client.conn.capability;
337 
338  conn_set_capability(&client.conn, capability);
339 
340  if (you_can_join) {
341  struct packet_client_info client_info;
342 
343  qDebug("join game accept:%s", message);
344  client.conn.established = true;
345  client.conn.id = conn_id;
346 
347  set_server_busy(false);
348 
349  if (get_client_page() == PAGE_MAIN
350  || get_client_page() == PAGE_NETWORK) {
351  set_client_page(PAGE_START);
352  }
353 
354  client_info._obsolete = 5; // Old value for gui_type(GUI_QT)
355  client_info._obsolete2 = 0;
356  qstrncpy(client_info.distribution, FREECIV_DISTRIBUTOR,
357  sizeof(client_info.distribution));
358  send_packet_client_info(&client.conn, &client_info);
359 
360  // we could always use hack, verify we're local
361 #ifdef FREECIV_DEBUG
362  if (!hackless || is_server_running())
363 #endif // FREECIV_DEBUG
364  {
365  send_client_wants_hack(challenge_file);
366  }
367 
369  } else {
371  _("You were rejected from the game: %s"), message);
372  client.conn.id = -1; // not in range of conn_info id
373 
374  if (auto_connect) {
375  qInfo(_("You were rejected from the game: %s"), message);
376  }
377 
378  set_client_page(PAGE_MAIN);
379  }
380  if (strcmp(s_capability, our_capability) == 0) {
381  return;
382  }
383  output_window_printf(ftc_client, _("Client capability string: %s"),
385  output_window_printf(ftc_client, _("Server capability string: %s"),
386  s_capability);
387 }
388 
393 void handle_city_remove(int city_id)
394 {
395  struct city *pcity = game_city_by_number(city_id);
396  bool need_menus_update;
397 
398  fc_assert_ret_msg(nullptr != pcity, "Bad city %d.", city_id);
399 
400  need_menus_update = (nullptr != get_focus_unit_on_tile(city_tile(pcity)));
401 
402  governor::i()->add_city_remove(pcity);
404  client_remove_city(pcity);
405 
406  // Update menus if the focus unit is on the tile.
407  if (need_menus_update) {
408  menus_update();
409  }
410 }
411 
416 void handle_unit_remove(int unit_id)
417 {
418  struct unit *punit = game_unit_by_number(unit_id);
419  struct unit_list *cargos;
420  struct player *powner;
421  bool need_economy_report_update;
422 
423  if (!punit) {
424  qCritical("Server wants us to remove unit id %d, "
425  "but we don't know about this unit!",
426  unit_id);
427  return;
428  }
429 
430  // Close diplomat dialog if the diplomat is lost
431  if (action_selection_actor_unit() == punit->id) {
433  /* Open another action selection dialog if there are other actors in the
434  * current selection that want a decision. */
436  }
437 
438  need_economy_report_update = (0 < punit->upkeep[O_GOLD]);
439  powner = unit_owner(punit);
440 
441  // Unload cargo if this is a transporter.
442  cargos = unit_transport_cargo(punit);
443  if (unit_list_size(cargos) > 0) {
444  unit_list_iterate(cargos, pcargo) { unit_transport_unload(pcargo); }
446  }
447 
448  // Unload unit if it is transported.
449  if (unit_transport_get(punit)) {
450  unit_transport_unload(punit);
451  }
452  punit->client.transported_by = -1;
453 
455  client_remove_unit(punit);
456 
457  if (!client_has_player() || powner == client_player()) {
458  if (need_economy_report_update) {
460  }
462  }
463 }
464 
469 {
471 }
472 
476 void handle_team_name_info(int team_id, const char *team_name)
477 {
478  struct team_slot *tslot = team_slot_by_number(team_id);
479 
480  fc_assert_ret(nullptr != tslot);
481  team_slot_set_defined_name(tslot, team_name);
483 }
484 
491 void handle_unit_combat_info(const struct packet_unit_combat_info *packet)
492 {
493  bool show_combat = false;
494  struct unit *punit0 = game_unit_by_number(packet->attacker_unit_id);
495  struct unit *punit1 = game_unit_by_number(packet->defender_unit_id);
496 
497  if (punit0 && punit1) {
498  popup_combat_info(packet->attacker_unit_id, packet->defender_unit_id,
499  packet->attacker_hp, packet->defender_hp,
500  packet->make_att_veteran, packet->make_def_veteran);
501  if (tile_visible_mapcanvas(unit_tile(punit0))
502  && tile_visible_mapcanvas(unit_tile(punit1))) {
503  show_combat = true;
504  } else if (gui_options->auto_center_on_combat) {
505  if (unit_owner(punit0) == client.conn.playing) {
507  } else {
509  }
510  show_combat = true;
511  }
512 
513  if (show_combat) {
514  int hp0 = packet->attacker_hp, hp1 = packet->defender_hp;
515 
516  audio_play_sound(unit_type_get(punit0)->sound_fight,
517  unit_type_get(punit0)->sound_fight_alt);
518  audio_play_sound(unit_type_get(punit1)->sound_fight,
519  unit_type_get(punit1)->sound_fight_alt);
520 
522  decrease_unit_hp_smooth(punit0, hp0, punit1, hp1);
523  } else {
524  punit0->hp = hp0;
525  punit1->hp = hp1;
526 
527  set_units_in_combat(nullptr, nullptr);
528  refresh_unit_mapcanvas(punit0, unit_tile(punit0), true);
529  refresh_unit_mapcanvas(punit1, unit_tile(punit1), true);
530  }
531  }
532  if (packet->make_att_veteran && punit0) {
533  punit0->veteran++;
534  refresh_unit_mapcanvas(punit0, unit_tile(punit0), true);
535  }
536  if (packet->make_def_veteran && punit1) {
537  punit1->veteran++;
538  refresh_unit_mapcanvas(punit1, unit_tile(punit1), true);
539  }
540  }
541 }
542 
547 void handle_unit_bombard_info(int attacker_unit_id, int target_tile_id)
548 {
549  const auto attacker = game_unit_by_number(attacker_unit_id);
550  const auto tile = index_to_tile(&(wld.map), target_tile_id);
551  if (!tile) {
552  // We do not do anything with a tile that doesn't exist/is unknown.
553  return;
554  }
555 
556  /*
557  * Determine whether we should show something.
558  */
559  bool show = attacker && tile_visible_mapcanvas(unit_tile(attacker));
560  show |= tile_visible_mapcanvas(tile);
561 
563  // Only center the map if the player is involved.
564  // The attacking player is for sure involved.
565  bool involved = attacker && unit_owner(attacker) == client.conn.playing;
566 
567  // Or if the player's territory gets bombed.
568  involved |= tile->owner == client.conn.playing;
569  involved |= tile->extras_owner == client.conn.playing;
570 
571  // Or if the player's unit gets bombed.
572  unit_list_iterate(tile->units, bombed_unit)
573  {
574  if (unit_owner(bombed_unit) == client.conn.playing) {
575  involved = true;
576  break;
577  }
578  }
580 
581  // Or also the player whose city gets bombed (borders may be disabled).
582  auto city = tile_city(tile);
583  involved |= city && city->owner == client.conn.playing;
584 
585  if (involved) {
586  // Center the map
587  queen()->mapview_wdg->center_on_tile(unit_tile(attacker));
588  show = true;
589  }
590  }
591 
592  /*
593  * Play the bombing animation.
594  */
595  if (show) {
596  // Play sound
597  if (attacker) {
598  audio_play_sound(unit_type_get(attacker)->sound_fight,
599  unit_type_get(attacker)->sound_fight_alt);
600  }
601 
602  // Display it
603  set_units_in_combat(attacker, nullptr);
605  set_units_in_combat(nullptr, nullptr);
608  }
609 }
610 
617 static bool update_improvement_from_packet(struct city *pcity,
618  struct impr_type *pimprove,
619  bool have_impr)
620 {
621  if (have_impr) {
622  if (pcity->built[improvement_index(pimprove)].turn <= I_NEVER) {
623  city_add_improvement(pcity, pimprove);
624  return true;
625  }
626  } else {
627  if (pcity->built[improvement_index(pimprove)].turn > I_NEVER) {
628  city_remove_improvement(pcity, pimprove);
629  return true;
630  }
631  }
632  return false;
633 }
634 
639 void handle_city_info(const struct packet_city_info *packet)
640 {
641  struct universal product;
642  int i;
643  bool popup;
644  bool city_is_new = false;
645  bool city_has_changed_owner = false;
646  bool need_science_dialog_update = false;
647  bool need_units_dialog_update = false;
648  bool need_economy_dialog_update = false;
649  bool name_changed = false;
650  bool update_descriptions = false;
651  bool shield_stock_changed = false;
652  bool production_changed = false;
653  bool trade_routes_changed = false;
654  struct city *pcity = game_city_by_number(packet->id);
655  struct tile_list *worked_tiles = nullptr;
656  struct tile *pcenter = index_to_tile(&(wld.map), packet->tile);
657  struct tile *ptile = nullptr;
658  struct player *powner = player_by_number(packet->owner);
659 
660  fc_assert_ret_msg(nullptr != powner, "Bad player number %d.",
661  packet->owner);
662  fc_assert_ret_msg(nullptr != pcenter, "Invalid tile index %d.",
663  packet->tile);
664 
665  if (!universals_n_is_valid(
666  static_cast<universals_n>(packet->production_kind))) {
667  qCritical("handle_city_info() bad production_kind %d.",
668  packet->production_kind);
669  product.kind = VUT_NONE;
670  } else {
671  product = universal_by_number(
672  static_cast<universals_n>(packet->production_kind),
673  packet->production_value);
674  if (!universals_n_is_valid(product.kind)) {
675  qCritical("handle_city_info() "
676  "production_kind %d with bad production_value %d.",
677  packet->production_kind, packet->production_value);
678  product.kind = VUT_NONE;
679  }
680  }
681 
682  if (nullptr != pcity) {
683  ptile = city_tile(pcity);
684 
685  if (nullptr == ptile) {
686  // invisible worked city
687  city_list_remove(invisible.cities, pcity);
688  city_is_new = true;
689 
690  pcity->tile = pcenter;
691  ptile = pcenter;
692  pcity->owner = powner;
693  pcity->original = powner;
694  } else if (city_owner(pcity) != powner) {
695  /* Remember what were the worked tiles. The server won't
696  * send to us again. */
698  pworked, _index, _x, _y)
699  {
700  if (pcity == tile_worked(pworked)) {
701  if (nullptr == worked_tiles) {
702  worked_tiles = tile_list_new();
703  }
704  tile_list_append(worked_tiles, pworked);
705  }
706  }
708  client_remove_city(pcity);
709  pcity = nullptr;
710  city_has_changed_owner = true;
711  }
712  }
713 
714  if (nullptr == pcity) {
715  city_is_new = true;
716  pcity = create_city_virtual(powner, pcenter, packet->name);
717  pcity->id = packet->id;
718  idex_register_city(&wld, pcity);
719  update_descriptions = true;
720  } else if (pcity->id != packet->id) {
721  qCritical("handle_city_info() city id %d != id %d.", pcity->id,
722  packet->id);
723  return;
724  } else if (ptile != pcenter) {
725  qCritical("handle_city_info() city tile (%d, %d) != (%d, %d).",
726  TILE_XY(ptile), TILE_XY(pcenter));
727  return;
728  } else {
729  name_changed =
730  (0 != strncmp(packet->name, pcity->name, sizeof(pcity->name)));
731 
732  while (trade_route_list_size(pcity->routes) > packet->traderoute_count) {
733  struct trade_route *proute = trade_route_list_get(pcity->routes, -1);
734 
735  trade_route_list_remove(pcity->routes, proute);
736  delete proute;
737  proute = nullptr;
738  trade_routes_changed = true;
739  }
740 
741  /* Descriptions should probably be updated if the
742  * city name, production or time-to-grow changes.
743  * Note that if either the food stock or surplus
744  * have changed, the time-to-grow is likely to
745  * have changed as well. */
746  update_descriptions =
747  (gui_options->draw_city_names && name_changed)
749  && (!are_universals_equal(&pcity->production, &product)
750  || pcity->surplus[O_SHIELD] != packet->surplus[O_SHIELD]
751  || pcity->shield_stock != packet->shield_stock))
753  && (pcity->food_stock != packet->food_stock
754  || pcity->surplus[O_FOOD] != packet->surplus[O_FOOD]))
755  || (gui_options->draw_city_trade_routes && trade_routes_changed);
756  }
757 
758  pcity->client.full = true;
759  sz_strlcpy(pcity->name, packet->name);
760 
761  // check data
762  city_size_set(pcity, 0);
763  for (i = 0; i < FEELING_LAST; i++) {
764  pcity->feel[CITIZEN_HAPPY][i] = packet->ppl_happy[i];
765  pcity->feel[CITIZEN_CONTENT][i] = packet->ppl_content[i];
766  pcity->feel[CITIZEN_UNHAPPY][i] = packet->ppl_unhappy[i];
767  pcity->feel[CITIZEN_ANGRY][i] = packet->ppl_angry[i];
768  }
769  for (i = 0; i < CITIZEN_LAST; i++) {
770  city_size_add(pcity, pcity->feel[i][FEELING_FINAL]);
771  }
773  {
774  pcity->specialists[sp] = packet->specialists[sp];
775  city_size_add(pcity, pcity->specialists[sp]);
776  }
778 
779  if (city_size_get(pcity) != packet->size) {
780  qCritical("handle_city_info() "
781  "%d citizens not equal %d city size in \"%s\".",
782  city_size_get(pcity), packet->size, city_name_get(pcity));
783  city_size_set(pcity, packet->size);
784  }
785 
786  // The nationality of the citizens.
787  if (game.info.citizen_nationality) {
788  citizens_init(pcity);
789  for (i = 0; i < packet->nationalities_count; i++) {
790  citizens_nation_set(pcity, player_slot_by_number(packet->nation_id[i]),
791  packet->nation_citizens[i]);
792  }
793  fc_assert(citizens_count(pcity) == city_size_get(pcity));
794  }
795 
796  pcity->history = packet->history;
797  pcity->client.culture = packet->culture;
798  pcity->client.buy_cost = packet->buy_cost;
799 
800  pcity->city_radius_sq = packet->city_radius_sq;
801 
802  pcity->city_options = packet->city_options;
803 
804  if (pcity->surplus[O_SCIENCE] != packet->surplus[O_SCIENCE]
805  || pcity->waste[O_SCIENCE] != packet->waste[O_SCIENCE]
806  || (pcity->unhappy_penalty[O_SCIENCE]
807  != packet->unhappy_penalty[O_SCIENCE])
808  || pcity->prod[O_SCIENCE] != packet->prod[O_SCIENCE]
809  || pcity->citizen_base[O_SCIENCE] != packet->citizen_base[O_SCIENCE]
810  || pcity->usage[O_SCIENCE] != packet->usage[O_SCIENCE]) {
811  need_science_dialog_update = true;
812  }
813 
814  pcity->food_stock = packet->food_stock;
815  if (pcity->shield_stock != packet->shield_stock) {
816  shield_stock_changed = true;
817  pcity->shield_stock = packet->shield_stock;
818  }
819  pcity->pollution = packet->pollution;
820  pcity->illness_trade = packet->illness_trade;
821 
822  if (!are_universals_equal(&pcity->production, &product)) {
823  production_changed = true;
824  }
825  /* Need to consider shield stock/surplus for unit dialog as used build
826  * slots may change, affecting number of "in-progress" units. */
827  if ((city_is_new && VUT_UTYPE == product.kind)
828  || (production_changed
829  && (VUT_UTYPE == pcity->production.kind
830  || VUT_UTYPE == product.kind))
831  || pcity->surplus[O_SHIELD] != packet->surplus[O_SHIELD]
832  || shield_stock_changed) {
833  need_units_dialog_update = true;
834  }
835  pcity->production = product;
836 
838  {
839  pcity->surplus[o] = packet->surplus[o];
840  pcity->waste[o] = packet->waste[o];
841  pcity->unhappy_penalty[o] = packet->unhappy_penalty[o];
842  pcity->prod[o] = packet->prod[o];
843  pcity->citizen_base[o] = packet->citizen_base[o];
844  pcity->usage[o] = packet->usage[o];
845  }
847 
848 #ifdef DONE_BY_create_city_virtual
849  if (city_is_new) {
850  worklist_init(&pcity->worklist);
851 
852  for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
853  pcity->built[i].turn = I_NEVER;
854  }
855  }
856 #endif // DONE_BY_create_city_virtual
857 
858  worklist_copy(&pcity->worklist, &packet->worklist);
859 
860  pcity->airlift = packet->airlift;
861  pcity->did_buy = packet->did_buy;
862  pcity->bought_shields = packet->bought_shields;
863  pcity->did_sell = packet->did_sell;
864  pcity->was_happy = packet->was_happy;
865 
866  pcity->turn_founded = packet->turn_founded;
867  pcity->turn_last_built = packet->turn_last_built;
868 
869  if (!universals_n_is_valid(
870  static_cast<universals_n>(packet->changed_from_kind))) {
871  qCritical("handle_city_info() bad changed_from_kind %d.",
872  packet->changed_from_kind);
873  product.kind = VUT_NONE;
874  } else {
875  product = universal_by_number(
876  static_cast<universals_n>(packet->changed_from_kind),
877  packet->changed_from_value);
878  if (!universals_n_is_valid(product.kind)) {
879  qCritical("handle_city_info() bad changed_from_value %d.",
880  packet->changed_from_value);
881  product.kind = VUT_NONE;
882  }
883  }
884  pcity->changed_from = product;
885 
886  pcity->before_change_shields = packet->before_change_shields;
887  pcity->disbanded_shields = packet->disbanded_shields;
888  pcity->caravan_shields = packet->caravan_shields;
889  pcity->last_turns_shield_surplus = packet->last_turns_shield_surplus;
890 
891  improvement_iterate(pimprove)
892  {
893  bool have = BV_ISSET(packet->improvements, improvement_index(pimprove));
894 
895  if (have && !city_is_new
896  && pcity->built[improvement_index(pimprove)].turn <= I_NEVER) {
897  audio_play_sound(pimprove->soundtag, pimprove->soundtag_alt);
898  }
899  need_economy_dialog_update |=
900  update_improvement_from_packet(pcity, pimprove, have);
901  }
903 
904  /* We should be able to see units in the city. But for a diplomat
905  * investigating an enemy city we can't. In that case we don't update
906  * the occupied flag at all: it's already been set earlier and we'll
907  * get an update if it changes. */
909  pcity->client.occupied = (unit_list_size(pcity->tile->units) > 0);
910  }
911 
912  pcity->client.walls = packet->walls;
913  pcity->style = packet->style;
914  pcity->capital = packet->capital;
915  if (packet->capital == CAPITAL_PRIMARY) {
916  powner->primary_capital_id = pcity->id;
917  } else if (powner->primary_capital_id == pcity->id) {
918  powner->primary_capital_id = 0;
919  }
920  pcity->client.city_image = packet->city_image;
921  pcity->steal = packet->steal;
922 
923  pcity->client.happy = city_happy(pcity);
924  pcity->client.unhappy = city_unhappy(pcity);
925 
926  popup = (city_is_new && can_client_change_view()
928  || packet->diplomat_investigate;
929 
930  city_packet_common(pcity, pcenter, powner, worked_tiles, city_is_new,
931  popup, packet->diplomat_investigate);
932 
933  if (city_is_new && !city_has_changed_owner) {
934  governor::i()->add_city_new(pcity);
935  } else { // city new and changed is the same call :P
936  governor::i()->add_city_changed(pcity);
937  }
938 
939  // Update the description if necessary.
940  if (update_descriptions) {
942  }
943 
944  // Update focus unit info label if necessary.
945  if (name_changed) {
946  for (const auto pfocus_unit : get_units_in_focus()) {
947  if (pfocus_unit->homecity == pcity->id) {
949  break;
950  }
951  }
952  }
953 
954  // Update the science dialog if necessary.
955  if (need_science_dialog_update) {
957  }
958 
959  // Update the units dialog if necessary.
960  if (need_units_dialog_update) {
962  }
963 
964  // Update the economy dialog if necessary.
965  if (need_economy_dialog_update) {
967  }
968 
969  // Update the panel text (including civ population).
971 
972  // update caravan dialog
973  if ((production_changed || shield_stock_changed)
974  && action_selection_target_city() == pcity->id) {
975  dsend_packet_unit_get_actions(
977  action_selection_target_unit(), city_tile(pcity)->index,
979  }
980 
982  && (trade_routes_changed
983  || (city_is_new && 0 < city_num_trade_routes(pcity)))) {
985  }
986 }
987 
993 static void city_packet_common(struct city *pcity, struct tile *pcenter,
994  struct player *powner,
995  struct tile_list *worked_tiles, bool is_new,
996  bool popup, bool investigate)
997 {
998  if (nullptr != worked_tiles) {
999  /* We need to transfer the worked infos because the server will assume
1000  * those infos are kept in our side and won't send to us again. */
1001  tile_list_iterate(worked_tiles, pwork) { tile_set_worked(pwork, pcity); }
1003  tile_list_destroy(worked_tiles);
1004  }
1005 
1006  if (is_new) {
1007  tile_set_worked(pcenter, pcity); // is_free_worked()
1008  city_list_prepend(powner->cities, pcity);
1009 
1010  if (client_is_global_observer() || powner == client_player()) {
1012  }
1013 
1014  players_iterate(pp)
1015  {
1016  unit_list_iterate(pp->units, punit)
1017  {
1018  if (punit->homecity == pcity->id) {
1019  unit_list_prepend(pcity->units_supported, punit);
1020  }
1021  }
1023  }
1025 
1026  pcity->client.first_citizen_index = fc_rand(MAX_NUM_CITIZEN_SPRITES);
1027  } else {
1028  if (client_is_global_observer() || powner == client_player()) {
1030  }
1031  }
1032 
1033  if (can_client_change_view()) {
1034  refresh_city_mapcanvas(pcity, pcenter, false);
1035  }
1036 
1037  if (city_workers_display == pcity) {
1038  city_workers_display = nullptr;
1039  }
1040 
1041  if (investigate) {
1042  // Commit the collected supported and present units.
1043  if (pcity->client.collecting_info_units_supported != nullptr) {
1044  // We got units, let's move the unit lists.
1045  fc_assert(pcity->client.collecting_info_units_present != nullptr);
1046 
1047  unit_list_destroy(pcity->client.info_units_present);
1048  pcity->client.info_units_present =
1049  pcity->client.collecting_info_units_present;
1050  pcity->client.collecting_info_units_present = nullptr;
1051 
1052  unit_list_destroy(pcity->client.info_units_supported);
1053  pcity->client.info_units_supported =
1054  pcity->client.collecting_info_units_supported;
1055  pcity->client.collecting_info_units_supported = nullptr;
1056  } else {
1057  // We didn't get any unit, let's clear the unit lists.
1058  fc_assert(pcity->client.collecting_info_units_present == nullptr);
1059 
1060  unit_list_clear(pcity->client.info_units_supported);
1061  unit_list_clear(pcity->client.info_units_present);
1062  }
1063  }
1064 
1065  if (popup && nullptr != client.conn.playing
1067  menus_update();
1068  if (!city_dialog_is_open(pcity)) {
1069  popup_city_dialog(pcity);
1070  }
1071  }
1072 
1073  if (!is_new
1074  && (popup
1076  refresh_city_dialog(pcity);
1077  }
1078 
1079  // update menus if the focus unit is on the tile.
1080  if (get_focus_unit_on_tile(pcenter)) {
1081  menus_update();
1082  }
1083 
1084  if (is_new) {
1085  log_debug("(%d,%d) creating city %d, %s %s", TILE_XY(pcenter), pcity->id,
1087  }
1088 
1090 }
1091 
1096 void handle_traderoute_info(const struct packet_traderoute_info *packet)
1097 {
1098  struct city *pcity = game_city_by_number(packet->city);
1099  struct trade_route *proute;
1100  bool city_changed = false;
1101 
1102  if (pcity == nullptr) {
1103  return;
1104  }
1105 
1106  proute = trade_route_list_get(pcity->routes, packet->index);
1107  if (proute == nullptr) {
1108  fc_assert(trade_route_list_size(pcity->routes) == packet->index);
1109 
1110  proute = new trade_route();
1111  trade_route_list_append(pcity->routes, proute);
1112  city_changed = true;
1113  }
1114 
1115  proute->partner = packet->partner;
1116  proute->value = packet->value;
1117  proute->dir = packet->direction;
1118  proute->goods = goods_by_number(packet->goods);
1119 
1120  if (gui_options->draw_city_trade_routes && city_changed) {
1121  update_city_description(pcity);
1123  }
1124 }
1125 
1131 void handle_city_short_info(const struct packet_city_short_info *packet)
1132 {
1133  bool city_has_changed_owner = false;
1134  bool city_is_new = false;
1135  bool name_changed = false;
1136  bool update_descriptions = false;
1137  struct city *pcity = game_city_by_number(packet->id);
1138  struct tile *pcenter = index_to_tile(&(wld.map), packet->tile);
1139  struct tile *ptile = nullptr;
1140  struct tile_list *worked_tiles = nullptr;
1141  struct player *powner = player_by_number(packet->owner);
1142  int radius_sq = game.info.init_city_radius_sq;
1143 
1144  fc_assert_ret_msg(nullptr != powner, "Bad player number %d.",
1145  packet->owner);
1146  fc_assert_ret_msg(nullptr != pcenter, "Invalid tile index %d.",
1147  packet->tile);
1148 
1149  if (nullptr != pcity) {
1150  ptile = city_tile(pcity);
1151 
1152  if (nullptr == ptile) {
1153  // invisible worked city
1154  city_list_remove(invisible.cities, pcity);
1155  city_is_new = true;
1156 
1157  pcity->tile = pcenter;
1158  ptile = pcenter;
1159  pcity->owner = powner;
1160  pcity->original = powner;
1161 
1162  whole_map_iterate(&(wld.map), wtile)
1163  {
1164  if (wtile->worked == pcity) {
1165  int dist_sq = sq_map_distance(pcenter, wtile);
1166 
1167  if (dist_sq > city_map_radius_sq_get(pcity)) {
1168  city_map_radius_sq_set(pcity, dist_sq);
1169  }
1170  }
1171  }
1173  } else if (city_owner(pcity) != powner) {
1174  /* Remember what were the worked tiles. The server won't
1175  * send to us again. */
1177  pworked, _index, _x, _y)
1178  {
1179  if (pcity == tile_worked(pworked)) {
1180  if (nullptr == worked_tiles) {
1181  worked_tiles = tile_list_new();
1182  }
1183  tile_list_append(worked_tiles, pworked);
1184  }
1185  }
1187  radius_sq = city_map_radius_sq_get(pcity);
1188  client_remove_city(pcity);
1189  pcity = nullptr;
1190  city_has_changed_owner = true;
1191  }
1192  }
1193 
1194  if (nullptr == pcity) {
1195  city_is_new = true;
1196  pcity = create_city_virtual(powner, pcenter, packet->name);
1197  pcity->id = packet->id;
1198  city_map_radius_sq_set(pcity, radius_sq);
1199  idex_register_city(&wld, pcity);
1200  } else if (pcity->id != packet->id) {
1201  qCritical("handle_city_short_info() city id %d != id %d.", pcity->id,
1202  packet->id);
1203  return;
1204  } else if (city_tile(pcity) != pcenter) {
1205  qCritical("handle_city_short_info() city tile (%d, %d) != (%d, %d).",
1206  TILE_XY(city_tile(pcity)), TILE_XY(pcenter));
1207  return;
1208  } else {
1209  name_changed =
1210  (0 != strncmp(packet->name, pcity->name, sizeof(pcity->name)));
1211 
1212  // Check if city descriptions should be updated
1213  if (gui_options->draw_city_names && name_changed) {
1214  update_descriptions = true;
1215  }
1216 
1217  sz_strlcpy(pcity->name, packet->name);
1218 
1219  memset(pcity->feel, 0, sizeof(pcity->feel));
1220  memset(pcity->specialists, 0, sizeof(pcity->specialists));
1221  }
1222 
1223  pcity->client.full = false;
1224 
1225  pcity->specialists[DEFAULT_SPECIALIST] = packet->size;
1226  city_size_set(pcity, packet->size);
1227 
1228  /* We can't actually see the internals of the city, but the server tells
1229  * us this much. */
1230  if (pcity->client.occupied != packet->occupied) {
1231  pcity->client.occupied = packet->occupied;
1232  update_descriptions = true;
1233  }
1234  pcity->client.walls = packet->walls;
1235  pcity->style = packet->style;
1236  pcity->capital = packet->capital;
1237  if (packet->capital == CAPITAL_PRIMARY) {
1238  powner->primary_capital_id = pcity->id;
1239  } else if (powner->primary_capital_id == pcity->id) {
1240  powner->primary_capital_id = 0;
1241  }
1242  pcity->client.city_image = packet->city_image;
1243 
1244  pcity->client.happy = packet->happy;
1245  pcity->client.unhappy = packet->unhappy;
1246 
1247  improvement_iterate(pimprove)
1248  {
1249  /* Don't update the non-visible improvements, they could hide the
1250  * previously seen informations about the city (diplomat investigation).
1251  */
1252  if (is_improvement_visible(pimprove)) {
1253  bool have =
1254  BV_ISSET(packet->improvements, improvement_index(pimprove));
1255  update_improvement_from_packet(pcity, pimprove, have);
1256  }
1257  }
1259 
1260  city_packet_common(pcity, pcenter, powner, worked_tiles, city_is_new,
1261  false, false);
1262 
1263  if (city_is_new && !city_has_changed_owner) {
1264  governor::i()->add_city_new(pcity);
1265  } else { // its the same
1266  governor::i()->add_city_changed(pcity);
1267  }
1268 
1269  // Update the description if necessary.
1270  if (update_descriptions) {
1271  update_city_description(pcity);
1272  }
1273 }
1274 
1278 void handle_worker_task(const struct packet_worker_task *packet)
1279 {
1280  struct city *pcity = game_city_by_number(packet->city_id);
1281  struct worker_task *ptask = nullptr;
1282 
1283  if (pcity == nullptr
1284  || (pcity->owner != client.conn.playing
1285  && !client_is_global_observer())) {
1286  return;
1287  }
1288 
1289  worker_task_list_iterate(pcity->task_reqs, ptask_old)
1290  {
1291  if (tile_index(ptask_old->ptile) == packet->tile_id) {
1292  ptask = ptask_old;
1293  break;
1294  }
1295  }
1297 
1298  if (ptask == nullptr) {
1299  if (packet->activity == ACTIVITY_LAST) {
1300  return;
1301  } else {
1302  ptask = new worker_task();
1303  worker_task_list_append(pcity->task_reqs, ptask);
1304  }
1305  } else {
1306  if (packet->activity == ACTIVITY_LAST) {
1307  worker_task_list_remove(pcity->task_reqs, ptask);
1308  delete ptask;
1309  ptask = nullptr;
1310  }
1311  }
1312 
1313  if (ptask != nullptr) {
1314  ptask->ptile = index_to_tile(&(wld.map), packet->tile_id);
1315  ptask->act = packet->activity;
1316  if (packet->tgt >= 0) {
1317  ptask->tgt = extra_by_number(packet->tgt);
1318  } else {
1319  ptask->tgt = nullptr;
1320  }
1321  ptask->want = packet->want;
1322  }
1323 
1324  refresh_city_dialog(pcity);
1325 }
1326 
1330 void handle_new_year(int year, int fragments, int turn)
1331 {
1332  game.info.year = year;
1333  game.info.fragment_count = fragments;
1334  /*
1335  * The turn was increased in handle_end_turn()
1336  */
1337  fc_assert(game.info.turn == turn);
1339 
1342 
1344  menus_update();
1345 
1347 
1348 #if 0
1349  /* This information shouldn't be needed, but if it is this is the only
1350  * way we can get it. */
1351  if (nullptr != client.conn.playing) {
1352  turn_gold_difference =
1353  client.conn.playing->economic.gold - last_turn_gold_amount;
1354  last_turn_gold_amount = client.conn.playing->economic.gold;
1355  }
1356 #endif
1357 
1360 
1362  create_event(nullptr, E_TURN_BELL, ftc_client, _("Start of turn %d"),
1363  game.info.turn);
1364  }
1365 
1366  if (last_turn != turn) {
1367  start_turn();
1368  last_turn = turn;
1369  }
1370 }
1371 
1378 {
1379  /* Messagewindow will contain events happened since our own phase ended,
1380  * so player of the first phase and last phase are in equal situation. */
1381  meswin_clear_older(game.info.turn, game.info.phase);
1382 }
1383 
1388 void handle_start_phase(int phase)
1389 {
1390  if (!client_has_player() && !client_is_observer()) {
1391  // We are on detached state, let ignore this packet.
1392  return;
1393  }
1394 
1395  if (phase < 0
1396  || (game.info.phase_mode == PMT_PLAYERS_ALTERNATE
1397  && phase >= player_count())
1398  || (game.info.phase_mode == PMT_TEAMS_ALTERNATE
1399  && phase >= team_count())) {
1400  qCritical("handle_start_phase() illegal phase %d.", phase);
1401  return;
1402  }
1403 
1405 
1406  game.info.phase = phase;
1407 
1408  // Possibly replace wait cursor with something else
1409  if (phase == 0) {
1410  /* TODO: Have server set as busy also if switching phase
1411  * is taking long in a alternating phases mode. */
1412  set_server_busy(false);
1413  }
1414 
1415  if (nullptr != client.conn.playing
1416  && is_player_phase(client.conn.playing, phase)) {
1417  non_ai_unit_focus = false;
1418 
1420 
1422  user_ended_turn();
1423  }
1424 
1426 
1428  {
1429  pcity->client.colored = false;
1430  }
1432 
1434  {
1435  punit->client.colored = false;
1436  }
1438 
1440  }
1441 
1443 }
1444 
1450 {
1451  log_debug("handle_begin_turn()");
1452 
1453  /* Server is still considered busy until it handles also the beginning
1454  * of the first phase. */
1455 
1457 }
1458 
1464 {
1465  log_debug("handle_end_turn()");
1466 
1467  // Make sure wait cursor is in use
1468  set_server_busy(true);
1469 
1471 
1472  /*
1473  * The local idea of the game.info.turn is increased here since the
1474  * client will get unit updates (reset of move points for example)
1475  * between handle_end_turn() and handle_new_year(). These
1476  * unit updates will look like they did take place in the old turn
1477  * which is incorrect. If we get the authoritative information about
1478  * the game.info.turn in handle_new_year() we will check it.
1479  */
1480  game.info.turn++;
1481 }
1482 
1486 void play_sound_for_event(enum event_type type)
1487 {
1488  const char *sound_tag = get_event_tag(type);
1489 
1490  if (sound_tag) {
1491  audio_play_sound(sound_tag, nullptr);
1492  }
1493 }
1494 
1499 void handle_chat_msg(const struct packet_chat_msg *packet)
1500 {
1501  handle_event(packet->message, index_to_tile(&(wld.map), packet->tile),
1502  packet->event, packet->turn, packet->phase, packet->conn_id);
1503 }
1504 
1515 void handle_early_chat_msg(const struct packet_early_chat_msg *packet)
1516 {
1517  handle_event(packet->message, index_to_tile(&(wld.map), packet->tile),
1518  packet->event, packet->turn, packet->phase, packet->conn_id);
1519 }
1520 
1525 void handle_connect_msg(const char *message)
1526 {
1527  popup_connect_msg(_("Welcome"), message);
1528 }
1529 
1534 void handle_server_info(const char *version_label, int major_version,
1535  int minor_version, int patch_version,
1536  int emerg_version)
1537 {
1538  if (emerg_version > 0) {
1539  qDebug("Server has version %d.%d.%d.%d%s", major_version, minor_version,
1540  patch_version, emerg_version, version_label);
1541  } else {
1542  qDebug("Server has version %d.%d.%d%s", major_version, minor_version,
1543  patch_version, version_label);
1544  }
1545 }
1546 
1550 void handle_page_msg(const char *caption, const char *headline,
1551  enum event_type event, int len, int parts)
1552 {
1554  || event != E_BROADCAST_REPORT) {
1555  if (page_msg_report.parts > 0) {
1556  // Previous one was never finished
1557  delete[] page_msg_report.caption;
1558  delete[] page_msg_report.headline;
1559  delete[] page_msg_report.lines;
1560  }
1561  page_msg_report.len = len;
1562  page_msg_report.event = event;
1563  page_msg_report.caption = fc_strdup(caption);
1564  page_msg_report.headline = fc_strdup(headline);
1565  page_msg_report.parts = parts;
1566  page_msg_report.lines = new char[len + 1];
1567  page_msg_report.lines[0] = '\0';
1568 
1569  if (parts == 0) {
1570  // Empty report - handle as if last part was just received.
1571  page_msg_report.parts = 1;
1573  }
1574  }
1575 }
1576 
1580 void handle_page_msg_part(const char *lines)
1581 {
1582  if (page_msg_report.lines != nullptr) {
1583  /* We have already decided to show the message at the time we got
1584  * the header packet. */
1586  page_msg_report.parts--;
1587 
1588  if (page_msg_report.parts == 0) {
1589  // This is the final part
1591  page_msg_report.lines);
1593 
1594  delete[] page_msg_report.caption;
1595  delete[] page_msg_report.headline;
1596  delete[] page_msg_report.lines;
1597  page_msg_report.lines = nullptr;
1598  }
1599  }
1600 }
1601 
1605 void handle_unit_info(const struct packet_unit_info *packet)
1606 {
1607  struct unit *punit;
1608 
1609  punit = unpackage_unit(packet);
1610  if (handle_unit_packet_common(punit)) {
1611  punit->client.transported_by = -1;
1612  unit_virtual_destroy(punit);
1613  }
1614 }
1615 
1632 static bool handle_unit_packet_common(struct unit *packet_unit)
1633 {
1634  struct city *pcity;
1635  struct unit *punit;
1636  bool need_menus_update = false;
1637  bool need_economy_report_update = false;
1638  bool need_units_report_update = false;
1639  bool repaint_unit = false;
1640  bool repaint_city = false; // regards unit's homecity
1641  struct tile *old_tile = nullptr;
1642  bool check_focus = false; // conservative focus change
1643  bool moved = false;
1644  bool ret = false;
1645 
1646  punit = player_unit_by_number(unit_owner(packet_unit), packet_unit->id);
1647  if (!punit && game_unit_by_number(packet_unit->id)) {
1648  /* This means unit has changed owner. We deal with this here
1649  * by simply deleting the old one and creating a new one. */
1650  handle_unit_remove(packet_unit->id);
1651  }
1652 
1653  if (punit) {
1654  /* In some situations, the size of repaint units require can change;
1655  * in particular, city-builder units sometimes get a potential-city
1656  * outline, but to speed up redraws we don't repaint this whole area
1657  * unnecessarily. We need to ensure that when the footprint shrinks,
1658  * old bits aren't left behind on the canvas.
1659  * If the current (old) status of the unit is such that it gets a large
1660  * repaint, as a special case, queue a large repaint immediately, to
1661  * schedule the correct amount/location to be redrawn; but rely on the
1662  * repaint being deferred until the unit is updated, so that what's
1663  * drawn reflects the new status (e.g., no city outline). */
1664  if (unit_drawn_with_city_outline(punit, true)) {
1665  refresh_unit_mapcanvas(punit, unit_tile(punit), true);
1666  }
1667 
1668  ret = true;
1669  punit->activity_count = packet_unit->activity_count;
1670  unit_change_battlegroup(punit, packet_unit->battlegroup);
1671  if (punit->ssa_controller != packet_unit->ssa_controller) {
1672  punit->ssa_controller = packet_unit->ssa_controller;
1673  repaint_unit = true;
1674  // AI is set: may change focus
1675  // AI is cleared: keep focus
1676  if (packet_unit->ssa_controller != SSA_NONE
1677  && unit_is_in_focus(punit)) {
1678  check_focus = true;
1679  }
1680  }
1681 
1682  if (punit->facing != packet_unit->facing) {
1683  punit->facing = packet_unit->facing;
1684  repaint_unit = true;
1685  }
1686 
1687  if (punit->activity != packet_unit->activity
1688  || punit->activity_target == packet_unit->activity_target
1689  || punit->client.transported_by != packet_unit->client.transported_by
1690  || punit->client.occupied != packet_unit->client.occupied
1691  || punit->has_orders != packet_unit->has_orders
1692  || punit->orders.repeat != packet_unit->orders.repeat
1693  || punit->orders.vigilant != packet_unit->orders.vigilant
1694  || punit->orders.index != packet_unit->orders.index) {
1695  /*** Change in activity or activity's target. ***/
1696 
1697  /* May change focus if focus unit gets a new activity.
1698  * But if new activity is Idle, it means user specifically selected
1699  * the unit */
1700  if (unit_is_in_focus(punit)
1701  && (packet_unit->activity != ACTIVITY_IDLE
1702  || packet_unit->has_orders)) {
1703  check_focus = true;
1704  }
1705 
1706  repaint_unit = true;
1707 
1708  // Wakeup Focus
1709  if (gui_options->wakeup_focus && nullptr != client.conn.playing
1711  && unit_owner(punit) == client.conn.playing
1712  && punit->activity == ACTIVITY_SENTRY
1713  && packet_unit->activity == ACTIVITY_IDLE
1714  && !unit_is_in_focus(punit)
1715  && is_player_phase(client.conn.playing, game.info.phase)) {
1716  // many wakeup units per tile are handled
1717  unit_focus_urgent(punit);
1718  check_focus = false; // and keep it
1719  }
1720 
1721  punit->activity = packet_unit->activity;
1722  punit->activity_target = packet_unit->activity_target;
1723 
1724  if (punit->client.transported_by
1725  != packet_unit->client.transported_by) {
1726  if (packet_unit->client.transported_by == -1) {
1727  /* The unit was unloaded from its transport. The check for a new
1728  * transport is done below. */
1729  unit_transport_unload(punit);
1730  }
1731 
1732  punit->client.transported_by = packet_unit->client.transported_by;
1733  }
1734 
1735  if (punit->client.occupied != packet_unit->client.occupied) {
1736  if (get_focus_unit_on_tile(unit_tile(packet_unit))) {
1737  /* Special case: (un)loading a unit in a transporter on the same
1738  *tile as the focus unit may (dis)allow the focus unit to be
1739  * loaded. Thus the orders->(un)load menu item needs updating. */
1740  need_menus_update = true;
1741  }
1742  punit->client.occupied = packet_unit->client.occupied;
1743  }
1744 
1745  punit->has_orders = packet_unit->has_orders;
1746  punit->orders.length = packet_unit->orders.length;
1747  punit->orders.index = packet_unit->orders.index;
1748  punit->orders.repeat = packet_unit->orders.repeat;
1749  punit->orders.vigilant = packet_unit->orders.vigilant;
1750 
1751  // We cheat by just stealing the packet unit's list.
1752  if (punit->orders.list) {
1753  delete[] punit->orders.list;
1754  }
1755  punit->orders.list = packet_unit->orders.list;
1756  packet_unit->orders.list = nullptr;
1757 
1758  if (nullptr == client.conn.playing
1759  || unit_owner(punit) == client.conn.playing) {
1761  }
1762  } /*** End of Change in activity or activity's target. ***/
1763 
1764  /* These two lines force the menus to be updated as appropriate when
1765  * the focus unit changes. */
1766  if (unit_is_in_focus(punit)) {
1767  need_menus_update = true;
1768  }
1769 
1770  if (punit->homecity != packet_unit->homecity) {
1771  // change homecity
1772  struct city *hcity;
1773 
1774  if ((hcity = game_city_by_number(punit->homecity))) {
1775  unit_list_remove(hcity->units_supported, punit);
1776  refresh_city_dialog(hcity);
1777  }
1778 
1779  punit->homecity = packet_unit->homecity;
1780  if ((hcity = game_city_by_number(punit->homecity))) {
1781  unit_list_prepend(hcity->units_supported, punit);
1782  repaint_city = true;
1783  }
1784 
1785  // This can change total upkeep figures
1786  need_units_report_update = true;
1787  }
1788 
1789  if (punit->name != packet_unit->name) {
1790  // Name changed
1791  punit->name = packet_unit->name;
1792 
1793  if (unit_is_in_focus(punit)) {
1794  // Update the orders menu -- the name is shown there
1795  need_menus_update = true;
1796  }
1797  }
1798 
1799  if (punit->hp != packet_unit->hp) {
1800  // hp changed
1801  punit->hp = packet_unit->hp;
1802  repaint_unit = true;
1803  }
1804 
1805  if (punit->utype != unit_type_get(packet_unit)) {
1806  // Unit type has changed (been upgraded)
1807  struct city *ccity = tile_city(unit_tile(punit));
1808 
1809  punit->utype = unit_type_get(packet_unit);
1810  repaint_unit = true;
1811  repaint_city = true;
1812  if (ccity != nullptr && (ccity->id != punit->homecity)) {
1813  refresh_city_dialog(ccity);
1814  }
1815  if (unit_is_in_focus(punit)) {
1816  // Update the orders menu -- the unit might have new abilities
1817  need_menus_update = true;
1818  }
1819  need_units_report_update = true;
1820  }
1821 
1822  // May change focus if an attempted move or attack exhausted unit
1823  if (punit->moves_left != packet_unit->moves_left
1824  && unit_is_in_focus(punit)) {
1825  check_focus = true;
1826  }
1827 
1828  if (!same_pos(unit_tile(punit), unit_tile(packet_unit))) {
1829  /*** Change position ***/
1830  struct city *ccity = tile_city(unit_tile(punit));
1831 
1832  old_tile = unit_tile(punit);
1833  moved = true;
1834 
1835  // Show where the unit is going.
1836  do_move_unit(punit, packet_unit);
1837 
1838  if (ccity != nullptr) {
1840  // Unit moved out of a city - update the occupied status.
1841  bool new_occupied = (unit_list_size(ccity->tile->units) > 0);
1842 
1843  if (ccity->client.occupied != new_occupied) {
1844  ccity->client.occupied = new_occupied;
1845  refresh_city_mapcanvas(ccity, ccity->tile, false);
1846  update_city_description(ccity);
1847  }
1848  }
1849 
1850  if (ccity->id == punit->homecity) {
1851  repaint_city = true;
1852  } else {
1853  refresh_city_dialog(ccity);
1854  }
1855  }
1856 
1857  if ((ccity = tile_city(unit_tile(punit)))) {
1859  // Unit moved into a city - obviously it's occupied.
1860  if (!ccity->client.occupied) {
1861  ccity->client.occupied = true;
1862  refresh_city_mapcanvas(ccity, ccity->tile, false);
1863  update_city_description(ccity);
1864  }
1865  }
1866 
1867  if (ccity->id == punit->homecity) {
1868  repaint_city = true;
1869  } else {
1870  refresh_city_dialog(ccity);
1871  }
1872  }
1873  } /*** End of Change position. ***/
1874 
1875  if (repaint_city || repaint_unit) {
1876  /* We repaint the city if the unit itself needs repainting or if
1877  * there is a special city-only redrawing to be done. */
1878  if ((pcity = game_city_by_number(punit->homecity))) {
1879  refresh_city_dialog(pcity);
1880  }
1881  if (repaint_unit && tile_city(unit_tile(punit))
1882  && tile_city(unit_tile(punit)) != pcity) {
1883  // Refresh the city we're occupying too.
1885  }
1886  }
1887 
1888  need_economy_report_update =
1889  (punit->upkeep[O_GOLD] != packet_unit->upkeep[O_GOLD]);
1890  // unit upkeep information
1891  output_type_iterate(o) { punit->upkeep[o] = packet_unit->upkeep[o]; }
1893 
1894  punit->nationality = packet_unit->nationality;
1895  punit->veteran = packet_unit->veteran;
1896  punit->moves_left = packet_unit->moves_left;
1897  punit->fuel = packet_unit->fuel;
1898  punit->goto_tile = packet_unit->goto_tile;
1899  punit->paradropped = packet_unit->paradropped;
1900  punit->stay = packet_unit->stay;
1901  if (punit->done_moving != packet_unit->done_moving) {
1902  punit->done_moving = packet_unit->done_moving;
1903  check_focus = true;
1904  }
1905 
1907 
1908  punit->action_decision_tile = packet_unit->action_decision_tile;
1909  punit->action_timestamp = packet_unit->action_timestamp;
1910  punit->action_turn = packet_unit->action_turn;
1911  if (punit->action_decision_want != packet_unit->action_decision_want
1912  && should_ask_server_for_actions(packet_unit)) {
1913  // The unit wants the player to decide.
1914  action_decision_request(punit);
1915  check_focus = true;
1916  }
1917  punit->action_decision_want = packet_unit->action_decision_want;
1918  } else {
1919  /*** Create new unit ***/
1920  punit = packet_unit;
1921  idex_register_unit(&wld, punit);
1922 
1923  unit_list_prepend(unit_owner(punit)->units, punit);
1924  unit_list_prepend(unit_tile(punit)->units, punit);
1925 
1927 
1928  if ((pcity = game_city_by_number(punit->homecity))) {
1929  unit_list_prepend(pcity->units_supported, punit);
1930  }
1931 
1932  log_debug("New %s %s id %d (%d %d) hc %d %s",
1934  TILE_XY(unit_tile(punit)), punit->id, punit->homecity,
1935  (pcity ? city_name_get(pcity) : "(unknown)"));
1936 
1937  repaint_unit = !unit_transported(punit);
1938 
1939  /* Check if we should link cargo units.
1940  * (This might be necessary if the cargo info was sent to us before
1941  * this transporter.) */
1942  if (punit->client.occupied) {
1943  unit_list_iterate(unit_tile(punit)->units, aunit)
1944  {
1945  if (aunit->client.transported_by == punit->id) {
1946  fc_assert(aunit->transporter == nullptr);
1947  unit_transport_load(aunit, punit, true);
1948  }
1949  }
1951  }
1952  pcity = tile_city(unit_tile(punit));
1953  if (pcity) {
1954  // The unit is in a city - obviously it's occupied.
1955  pcity->client.occupied = true;
1956  }
1957 
1958  if (should_ask_server_for_actions(punit)) {
1959  // The unit wants the player to decide.
1960  action_decision_request(punit);
1961  check_focus = true;
1962  }
1963 
1964  need_units_report_update = true;
1965  } /*** End of Create new unit ***/
1966 
1967  fc_assert_ret_val(punit != nullptr, ret);
1968 
1969  // Check if we have to load the unit on a transporter.
1970  if (punit->client.transported_by != -1) {
1971  struct unit *ptrans =
1972  game_unit_by_number(packet_unit->client.transported_by);
1973 
1974  /* Load unit only if transporter is known by the client.
1975  * (If not, cargo will be loaded later when the transporter info is
1976  * sent to the client.) */
1977  if (ptrans && ptrans != unit_transport_get(punit)) {
1978  // First, we have to unload the unit from its old transporter.
1979  unit_transport_unload(punit);
1980  unit_transport_load(punit, ptrans, true);
1981 #ifdef DEBUG_TRANSPORT
1982  log_debug("load %s (ID: %d) onto %s (ID: %d)",
1983  unit_name_translation(punit), punit->id,
1984  unit_name_translation(ptrans), ptrans->id);
1985  } else if (ptrans && ptrans == unit_transport_get(punit)) {
1986  log_debug("%s (ID: %d) is loaded onto %s (ID: %d)",
1987  unit_name_translation(punit), punit->id,
1988  unit_name_translation(ptrans), ptrans->id);
1989  } else {
1990  log_debug("%s (ID: %d) is not loaded", unit_name_translation(punit),
1991  punit->id);
1992 #endif // DEBUG_TRANSPORT
1993  }
1994  }
1995 
1996  if (unit_is_in_focus(punit) || get_focus_unit_on_tile(unit_tile(punit))
1997  || (moved && get_focus_unit_on_tile(old_tile))) {
1999  // Update (an possible active) unit select dialog.
2001  }
2002 
2003  if (repaint_unit) {
2004  refresh_unit_mapcanvas(punit, unit_tile(punit), true);
2005  }
2006 
2007  if ((check_focus || get_num_units_in_focus() == 0)
2008  && nullptr != client.conn.playing && is_human(client.conn.playing)
2010  && !queen()->city_overlay->isVisible()) {
2012  }
2013 
2014  if (need_menus_update) {
2015  menus_update();
2016  }
2017 
2018  if (!client_has_player() || unit_owner(punit) == client_player()) {
2019  if (need_economy_report_update) {
2021  }
2022  if (need_units_report_update) {
2024  }
2025  }
2026 
2027  return ret;
2028 }
2029 
2033 void handle_unit_short_info(const struct packet_unit_short_info *packet)
2034 {
2035  struct city *pcity;
2036  struct unit *punit;
2037 
2038  /* Special case for a diplomat/spy investigating a city: The investigator
2039  * needs to know the supported and present units of a city, whether or not
2040  * they are fogged. So, we send a list of them all before sending the city
2041  * info. */
2042  if (packet->packet_use == UNIT_INFO_CITY_SUPPORTED
2043  || packet->packet_use == UNIT_INFO_CITY_PRESENT) {
2044  static int last_serial_num = 0;
2045 
2046  pcity = game_city_by_number(packet->info_city_id);
2047  if (!pcity) {
2048  qCritical("Investigate city: unknown city id %d!",
2049  packet->info_city_id);
2050  return;
2051  }
2052 
2053  // New serial number: start collecting supported and present units.
2054  if (last_serial_num
2055  != client.conn.client.request_id_of_currently_handled_packet) {
2056  last_serial_num =
2057  client.conn.client.request_id_of_currently_handled_packet;
2058  // Ensure we are not already in an investigate cycle.
2059  fc_assert(pcity->client.collecting_info_units_supported == nullptr);
2060  fc_assert(pcity->client.collecting_info_units_present == nullptr);
2061  pcity->client.collecting_info_units_supported =
2062  unit_list_new_full(unit_virtual_destroy);
2063  pcity->client.collecting_info_units_present =
2064  unit_list_new_full(unit_virtual_destroy);
2065  }
2066 
2067  // Okay, append a unit struct to the proper list.
2068  punit = unpackage_short_unit(packet);
2069  if (packet->packet_use == UNIT_INFO_CITY_SUPPORTED) {
2070  fc_assert(pcity->client.collecting_info_units_supported != nullptr);
2071  unit_list_append(pcity->client.collecting_info_units_supported, punit);
2072  } else {
2073  fc_assert(packet->packet_use == UNIT_INFO_CITY_PRESENT);
2074  fc_assert(pcity->client.collecting_info_units_present != nullptr);
2075  unit_list_append(pcity->client.collecting_info_units_present, punit);
2076  }
2077 
2078  // Done with special case.
2079  return;
2080  }
2081 
2082  if (player_by_number(packet->owner) == client.conn.playing) {
2083  qCritical("handle_unit_short_info() for own unit.");
2084  }
2085 
2086  punit = unpackage_short_unit(packet);
2087  if (handle_unit_packet_common(punit)) {
2088  punit->client.transported_by = -1;
2089  unit_virtual_destroy(punit);
2090  }
2091 }
2092 
2096 void handle_set_topology(int topology_id)
2097 {
2098  wld.map.topology_id = topology_id;
2099 
2100  if (forced_tileset_name.isEmpty()
2101  && (tileset_map_topo_compatible(topology_id, tileset)
2102  == TOPO_INCOMP_HARD
2103  || strcmp(tileset_basename(tileset),
2104  game.control.preferred_tileset))) {
2105  const char *ts_to_load;
2106 
2107  ts_to_load = tileset_name_for_topology(topology_id);
2108 
2109  if (ts_to_load != nullptr && ts_to_load[0] != '\0') {
2110  tilespec_reread_frozen_refresh(ts_to_load);
2111  }
2112  }
2113 }
2114 
2119 void handle_map_info(int xsize, int ysize, int topology_id)
2120 {
2121  if (!map_is_empty()) {
2122  map_free(&(wld.map));
2124  }
2125 
2126  wld.map.xsize = xsize;
2127  wld.map.ysize = ysize;
2128 
2129  if (tileset_map_topo_compatible(topology_id, tileset)
2130  == TOPO_INCOMP_HARD) {
2132  _("Map topology and tileset incompatible."));
2133  }
2134 
2135  wld.map.topology_id = topology_id;
2136 
2140  init_client_goto();
2141  mapdeco_init();
2142 
2144 
2146 
2147  packhand_init();
2148 }
2149 
2153 void handle_game_info(const struct packet_game_info *pinfo)
2154 {
2155  bool boot_help;
2156  bool update_aifill_button = false, update_ai_skill_level = false;
2157 
2158  if (game.info.aifill != pinfo->aifill) {
2159  update_aifill_button = true;
2160  }
2161  if (game.info.skill_level != pinfo->skill_level) {
2162  update_ai_skill_level = true;
2163  }
2164 
2165  if (game.info.is_edit_mode != pinfo->is_edit_mode) {
2167  // Clears the current goto command.
2169 
2170  if (pinfo->is_edit_mode && game.scenario.handmade) {
2171  if (!handmade_scenario_warning()) {
2172  // Gui didn't handle this
2174  ftc_client,
2175  _("This scenario may have manually set properties the editor "
2176  "cannot handle."));
2178  _("They won't be saved when scenario is saved "
2179  "from the editor."));
2180  }
2181  }
2182  }
2183 
2184  game.info = *pinfo;
2185 
2186  // check the values!
2187 #define VALIDATE(_count, _maximum, _string) \
2188  if (game.info._count > _maximum) { \
2189  qCritical("handle_game_info(): Too many " _string "; using %d of %d", \
2190  _maximum, game.info._count); \
2191  game.info._count = _maximum; \
2192  }
2193 
2194  VALIDATE(granary_num_inis, MAX_GRANARY_INIS, "granary entries");
2195 #undef VALIDATE
2196 
2198  government_by_number(game.info.default_government_id);
2200  government_by_number(game.info.government_during_revolution_id);
2201 
2202  boot_help = (can_client_change_view()
2203  && game.info.victory_conditions != pinfo->victory_conditions);
2204  if (boot_help) {
2205  // reboot, after setting game.spacerace
2208  }
2210  menus_update();
2212  if (update_aifill_button || update_ai_skill_level) {
2214  }
2215 
2216  if (can_client_change_view()) {
2218  }
2219 
2221 }
2222 
2226 void handle_calendar_info(const struct packet_calendar_info *pcalendar)
2227 {
2228  game.calendar = *pcalendar;
2229 }
2230 
2234 void handle_timeout_info(float seconds_to_phasedone,
2235  float last_turn_change_time)
2236 {
2237  if (current_turn_timeout() != 0 && seconds_to_phasedone >= 0) {
2238  /* If this packet is received in the middle of a turn, this value
2239  * represents the number of seconds from now to the end of the turn
2240  * (not from the start of the turn). So we need to restart our
2241  * timer. */
2242  set_miliseconds_to_turndone(seconds_to_phasedone * 1000);
2243  }
2244 
2245  game.tinfo.last_turn_change_time = last_turn_change_time;
2246 }
2247 
2253 {
2254  if (nullptr != client.conn.playing && can_client_issue_orders()
2256  dsend_packet_player_change_government(&client.conn,
2258  }
2259 }
2260 
2266 {
2267  dsend_packet_player_change_government(
2268  &client.conn, game.info.government_during_revolution_id);
2269 }
2270 
2276 void handle_player_remove(int playerno)
2277 {
2278  struct player_slot *pslot;
2279  struct player *pplayer;
2280  int plr_nbr;
2281 
2282  pslot = player_slot_by_number(playerno);
2283 
2284  if (nullptr == pslot || !player_slot_is_used(pslot)) {
2285  // Ok, just ignore.
2286  return;
2287  }
2288 
2289  pplayer = player_slot_get_player(pslot);
2290 
2291  if (can_client_change_view()) {
2292  close_intel_dialog(pplayer);
2293  }
2294 
2295  // Update the connection informations.
2296  if (client_player() == pplayer) {
2297  client.conn.playing = nullptr;
2298  }
2299  conn_list_iterate(pplayer->connections, pconn)
2300  {
2301  pconn->playing = nullptr;
2302  }
2304  conn_list_clear(pplayer->connections);
2305 
2306  // Save player number before player is freed
2307  plr_nbr = player_number(pplayer);
2308 
2309  player_destroy(pplayer);
2310 
2313 
2314  editgui_refresh();
2316 }
2317 
2323 void handle_player_info(const struct packet_player_info *pinfo)
2324 {
2325  bool is_new_nation = false;
2326  bool turn_done_changed = false;
2327  bool new_player = false;
2328  int i;
2329  struct player *pplayer, *my_player;
2330  struct nation_type *pnation;
2331  struct government *pgov, *ptarget_gov;
2332  struct player_slot *pslot;
2333  struct team_slot *tslot;
2334 
2335  // Player.
2336  pslot = player_slot_by_number(pinfo->playerno);
2337  fc_assert(nullptr != pslot);
2338  new_player = !player_slot_is_used(pslot);
2339  pplayer = player_new(pslot);
2340 
2341  if ((pplayer->rgb == nullptr) != !pinfo->color_valid
2342  || (pinfo->color_valid
2343  && (pplayer->rgb->r != pinfo->color_red
2344  || pplayer->rgb->g != pinfo->color_green
2345  || pplayer->rgb->b != pinfo->color_blue))) {
2346  struct rgbcolor *prgbcolor;
2347 
2348  if (pinfo->color_valid) {
2349  prgbcolor = rgbcolor_new(pinfo->color_red, pinfo->color_green,
2350  pinfo->color_blue);
2351  fc_assert_ret(prgbcolor != nullptr);
2352  } else {
2353  prgbcolor = nullptr;
2354  }
2355 
2356  player_set_color(pplayer, prgbcolor);
2357  tileset_player_init(tileset, pplayer);
2358 
2359  rgbcolor_destroy(prgbcolor);
2360 
2361  // Queue a map update -- may need to redraw borders, etc.
2363  }
2364  pplayer->client.color_changeable = pinfo->color_changeable;
2365 
2366  if (new_player) {
2367  /* Initialise client side player data (tile vision). At the moment
2368  * redundant as the values are initialised with 0 due to fc_calloc(). */
2369  client_player_init(pplayer);
2370  }
2371 
2372  // Information visibility
2373  if (!has_capability("player-intel-visibility", client.conn.capability)) {
2374  // Providing full backward compat here would be too much work. Let the
2375  // client believe that it knows everything.
2376  BV_SET_ALL(pplayer->client.visible);
2377  }
2378  pplayer->client.visible = pinfo->visible;
2379 
2380  // Team.
2381  tslot = team_slot_by_number(pinfo->team);
2382  fc_assert(nullptr != tslot);
2383  team_add_player(pplayer, team_new(tslot));
2384 
2385  pnation = nation_by_number(pinfo->nation);
2386  pgov = government_by_number(pinfo->government);
2387  ptarget_gov = government_by_number(pinfo->target_government);
2388 
2389  // Now update the player information.
2390  sz_strlcpy(pplayer->name, pinfo->name);
2391  sz_strlcpy(pplayer->username, pinfo->username);
2392  pplayer->unassigned_user = pinfo->unassigned_user;
2393 
2394  is_new_nation = player_set_nation(pplayer, pnation);
2395  pplayer->is_male = pinfo->is_male;
2396  pplayer->score.game = pinfo->score;
2397  pplayer->was_created = pinfo->was_created;
2398 
2399  pplayer->economic.gold = pinfo->gold;
2400  pplayer->economic.tax = pinfo->tax;
2401  pplayer->economic.science = pinfo->science;
2402  pplayer->economic.luxury = pinfo->luxury;
2403  pplayer->client.tech_upkeep = pinfo->tech_upkeep;
2404  pplayer->government = pgov;
2405  pplayer->target_government = ptarget_gov;
2406  /* Don't use player_iterate here, because we ignore the real number
2407  * of players and we want to read all the datas. */
2408  BV_CLR_ALL(pplayer->real_embassy);
2409  fc_assert(8 * sizeof(pplayer->real_embassy)
2410  >= ARRAY_SIZE(pinfo->real_embassy));
2411  for (i = 0; i < ARRAY_SIZE(pinfo->real_embassy); i++) {
2412  if (pinfo->real_embassy[i]) {
2413  BV_SET(pplayer->real_embassy, i);
2414  }
2415  }
2416  pplayer->gives_shared_vision = pinfo->gives_shared_vision;
2417  pplayer->style = style_by_number(pinfo->style);
2418 
2419  if (pplayer == client.conn.playing) {
2420  bool music_change = false;
2421 
2422  if (pplayer->music_style != pinfo->music_style) {
2423  pplayer->music_style = pinfo->music_style;
2424  music_change = true;
2425  }
2426  if (pplayer->client.mood != pinfo->mood) {
2427  pplayer->client.mood = pinfo->mood;
2428  music_change = true;
2429  }
2430 
2431  if (music_change) {
2433  }
2434  }
2435 
2436  pplayer->history = pinfo->history;
2437  pplayer->client.culture = pinfo->culture;
2438 
2439  /* Don't use player_iterate or player_slot_count here, because we ignore
2440  * the real number of players and we want to read all the datas. */
2441  fc_assert(ARRAY_SIZE(pplayer->ai_common.love) >= ARRAY_SIZE(pinfo->love));
2442  for (i = 0; i < ARRAY_SIZE(pinfo->love); i++) {
2443  pplayer->ai_common.love[i] = pinfo->love[i];
2444  }
2445 
2446  my_player = client_player();
2447 
2448  pplayer->is_connected = pinfo->is_connected;
2449 
2450  for (i = 0; i < B_LAST; i++) {
2451  pplayer->wonders[i] = pinfo->wonders[i];
2452  }
2453 
2454  // Set AI.control.
2455  if (is_ai(pplayer) != BV_ISSET(pinfo->flags, PLRF_AI)) {
2456  BV_SET_VAL(pplayer->flags, PLRF_AI, BV_ISSET(pinfo->flags, PLRF_AI));
2457  if (pplayer == my_player) {
2458  if (is_ai(my_player)) {
2459  output_window_append(ftc_client, _("AI mode is now ON."));
2460  if (!gui_options->ai_manual_turn_done && !pplayer->phase_done) {
2461  // End turn immediately
2462  user_ended_turn();
2463  }
2464  } else {
2465  output_window_append(ftc_client, _("AI mode is now OFF."));
2466  }
2467  }
2468  }
2469 
2470  pplayer->flags = pinfo->flags;
2471 
2472  pplayer->ai_common.science_cost = pinfo->science_cost;
2473 
2474  turn_done_changed = (pplayer->phase_done != pinfo->phase_done
2475  || (BV_ISSET(pplayer->flags, PLRF_AI)
2476  != BV_ISSET(pinfo->flags, PLRF_AI)));
2477  pplayer->phase_done = pinfo->phase_done;
2478 
2479  pplayer->is_ready = pinfo->is_ready;
2480  pplayer->nturns_idle = pinfo->nturns_idle;
2481  pplayer->is_alive = pinfo->is_alive;
2482  pplayer->turns_alive = pinfo->turns_alive;
2483  pplayer->ai_common.barbarian_type = pinfo->barbarian_type;
2484  pplayer->revolution_finishes = pinfo->revolution_finishes;
2485  pplayer->ai_common.skill_level =
2486  static_cast<ai_level>(pinfo->ai_skill_level);
2487 
2488  fc_assert(pinfo->multip_count == multiplier_count());
2489  game.control.num_multipliers = pinfo->multip_count;
2490  multipliers_iterate(pmul)
2491  {
2492  pplayer->multipliers[multiplier_index(pmul)] =
2493  pinfo->multiplier[multiplier_index(pmul)];
2494  pplayer->multipliers_target[multiplier_index(pmul)] =
2495  pinfo->multiplier_target[multiplier_index(pmul)];
2496  }
2498 
2499  /* if the server requests that the client reset, then information about
2500  * connections to this player are lost. If this is the case, insert the
2501  * correct conn back into the player->connections list */
2502  if (conn_list_size(pplayer->connections) == 0) {
2504  {
2505  if (pplayer == pconn->playing) {
2506  // insert the controller into first position
2507  if (pconn->observer) {
2508  conn_list_append(pplayer->connections, pconn);
2509  } else {
2510  conn_list_prepend(pplayer->connections, pconn);
2511  }
2512  }
2513  }
2515  }
2516 
2517  // The player information is now fully set. Update the GUI.
2518 
2519  if (pplayer == my_player && can_client_change_view()) {
2520  if (turn_done_changed) {
2522  }
2529  menus_update();
2530  }
2531 
2533 
2536 
2537  if (is_new_nation) {
2539 
2540  /* When changing nation during a running game, some refreshing is needed.
2541  * This may not be the only one! */
2543  }
2544 
2545  if (can_client_change_view()) {
2546  /* Just about any changes above require an update to the intelligence
2547  * dialog. */
2548  update_intel_dialog(pplayer);
2549  }
2550 
2551  editgui_refresh();
2553  false);
2554 }
2555 
2559 void handle_research_info(const struct packet_research_info *packet)
2560 {
2561  struct research *presearch;
2562  bool tech_changed = false;
2563  bool poptechup = false;
2564  std::vector<Tech_type_id> gained_techs;
2565  gained_techs.resize(advance_count());
2566  int gained_techs_num = 0, i;
2567  enum tech_state newstate, oldstate;
2568 
2569 #ifdef FREECIV_DEBUG
2570  qDebug("Research nb %d inventions: %s", packet->id, packet->inventions);
2571 #endif
2572  presearch = research_by_number(packet->id);
2573  fc_assert_ret(nullptr != presearch);
2574 
2575  poptechup = (presearch->researching != packet->researching
2576  || presearch->tech_goal != packet->tech_goal);
2577  presearch->techs_researched = packet->techs_researched;
2578  if (presearch->future_tech == 0 && packet->future_tech > 0) {
2579  gained_techs[gained_techs_num++] = A_FUTURE;
2580  }
2581  presearch->future_tech = packet->future_tech;
2582  presearch->researching = packet->researching;
2583  presearch->client.researching_cost = packet->researching_cost;
2584  presearch->bulbs_researched = packet->bulbs_researched;
2585  presearch->tech_goal = packet->tech_goal;
2586  presearch->client.total_bulbs_prod = packet->total_bulbs_prod;
2587 
2589  {
2590  newstate = static_cast<tech_state>(packet->inventions[advi] - '0');
2591  oldstate = research_invention_set(presearch, advi, newstate);
2592 
2593  if (newstate != oldstate) {
2594  if (TECH_KNOWN == newstate) {
2595  tech_changed = true;
2596  if (A_NONE != advi) {
2597  gained_techs[gained_techs_num++] = advi;
2598  }
2599  } else if (TECH_KNOWN == oldstate) {
2600  tech_changed = true;
2601  }
2602  }
2603  }
2605  if (!client_is_global_observer()) {
2606  research_update(presearch);
2607  }
2608 
2609  if (C_S_RUNNING == client_state()) {
2610  if (presearch == research_get(client_player())) {
2611  if (poptechup && is_human(client_player())) {
2613  }
2615  if (tech_changed) {
2616  /* Some ways a new or lost tech can affect menus:
2617  * - If tech is needed for certain governments, the government
2618  * switching menus need updating.
2619  * - If we just learned/lost bridge building and focus is on a
2620  * worker on a river, the road menu item needs updating. */
2621  menus_update();
2622 
2623  script_client_signal_emit("new_tech");
2624 
2625  // If we got a new tech the tech tree news an update.
2627  }
2628  for (i = 0; i < gained_techs_num; i++) {
2629  show_tech_gained_dialog(gained_techs[i]);
2630  }
2631  }
2632  if (editor_is_active()) {
2633  editgui_refresh();
2634  research_players_iterate(presearch, pplayer)
2635  {
2637  false);
2638  }
2640  }
2641  }
2642 }
2643 
2647 void handle_player_diplstate(const struct packet_player_diplstate *packet)
2648 {
2649  struct player *plr1 = player_by_number(packet->plr1);
2650  struct player *plr2 = player_by_number(packet->plr2);
2651  struct player *my_player = client_player();
2652  struct player_diplstate *ds = player_diplstate_get(plr1, plr2);
2653  bool need_players_dialog_update = false;
2654 
2655  fc_assert_ret(ds != nullptr);
2656 
2657  if (client_has_player() && my_player == plr2) {
2658  if (ds->type != packet->type) {
2659  need_players_dialog_update = true;
2660  }
2661 
2662  /* Check if we detect change to armistice with us. If so,
2663  * ready all units for movement out of the territory in
2664  * question; otherwise they will be disbanded. */
2665  if (DS_ARMISTICE != player_diplstate_get(plr1, my_player)->type
2666  && DS_ARMISTICE == packet->type) {
2667  unit_list_iterate(my_player->units, punit)
2668  {
2669  if (!tile_owner(unit_tile(punit))
2670  || tile_owner(unit_tile(punit)) != plr1) {
2671  continue;
2672  }
2673  if (punit->client.focus_status == FOCUS_WAIT) {
2674  punit->client.focus_status = FOCUS_AVAIL;
2675  }
2676  if (punit->activity != ACTIVITY_IDLE) {
2677  request_new_unit_activity(punit, ACTIVITY_IDLE);
2678  }
2679  }
2681  }
2682  }
2683 
2684  ds->type = packet->type;
2685  ds->turns_left = packet->turns_left;
2686  ds->has_reason_to_cancel = packet->has_reason_to_cancel;
2687  ds->contact_turns_left = packet->contact_turns_left;
2688 
2689  if (need_players_dialog_update) {
2691  }
2692 
2693  if (need_players_dialog_update
2695  /* An action selection dialog is open and our diplomatic state just
2696  * changed. Find out if the relationship that changed was to a
2697  * potential target. */
2698  struct tile *tgt_tile = nullptr;
2699 
2700  // Is a refresh needed because of a unit target?
2702  struct unit *tgt_unit;
2703 
2705 
2706  if (tgt_unit != nullptr && tgt_unit->owner == plr1) {
2707  // An update is needed because of this unit target.
2708  tgt_tile = unit_tile(tgt_unit);
2709  fc_assert(tgt_tile != nullptr);
2710  }
2711  }
2712 
2713  // Is a refresh needed because of a city target?
2715  struct city *tgt_city;
2716 
2718 
2719  if (tgt_city != nullptr && tgt_city->owner == plr1) {
2720  /* An update is needed because of this city target.
2721  * Overwrites any target tile from a unit. */
2722  tgt_tile = city_tile(tgt_city);
2723  fc_assert(tgt_tile != nullptr);
2724  }
2725  }
2726 
2727  if (tgt_tile
2728  || ((tgt_tile =
2730  && tile_owner(tgt_tile) == plr1)) {
2731  /* The diplomatic relationship to the target in an open action
2732  * selection dialog have changed. This probably changes
2733  * the set of available actions. */
2734  dsend_packet_unit_get_actions(
2736  action_selection_target_unit(), tgt_tile->index,
2738  }
2739  }
2740 }
2741 
2748 void handle_conn_info(const struct packet_conn_info *pinfo)
2749 {
2750  struct connection *pconn = conn_by_number(pinfo->id);
2751  bool preparing_client_state = false;
2752 
2753  log_debug("conn_info id%d used%d est%d plr%d obs%d acc%d", pinfo->id,
2754  pinfo->used, pinfo->established, pinfo->player_num,
2755  pinfo->observer, (int) pinfo->access_level);
2756  log_debug("conn_info \"%s\" \"%s\" \"%s\"", pinfo->username, pinfo->addr,
2757  pinfo->capability);
2758 
2759  if (!pinfo->used) {
2760  // Forget the connection
2761  if (!pconn) {
2762  qDebug("Server removed unknown connection %d", pinfo->id);
2763  return;
2764  }
2765  client_remove_cli_conn(pconn);
2766  pconn = nullptr;
2767  } else {
2768  struct player_slot *pslot = player_slot_by_number(pinfo->player_num);
2769  struct player *pplayer = nullptr;
2770 
2771  if (nullptr != pslot) {
2772  pplayer = player_slot_get_player(pslot);
2773  }
2774 
2775  if (!pconn) {
2776  qDebug("Server reports new connection %d %s", pinfo->id,
2777  pinfo->username);
2778 
2779  pconn = new connection{};
2780  pconn->buffer = nullptr;
2781  pconn->send_buffer = nullptr;
2782  pconn->ping_time = -1.0;
2783  if (pplayer) {
2784  conn_list_append(pplayer->connections, pconn);
2785  }
2786  conn_list_append(game.all_connections, pconn);
2787  conn_list_append(game.est_connections, pconn);
2788  } else {
2789  log_packet("Server reports updated connection %d %s", pinfo->id,
2790  pinfo->username);
2791  if (pplayer != pconn->playing) {
2792  if (nullptr != pconn->playing) {
2793  conn_list_remove(pconn->playing->connections, pconn);
2794  }
2795  if (pplayer) {
2796  conn_list_append(pplayer->connections, pconn);
2797  }
2798  }
2799  }
2800 
2801  pconn->id = pinfo->id;
2802  pconn->established = pinfo->established;
2803  pconn->observer = pinfo->observer;
2804  pconn->access_level = pinfo->access_level;
2805  pconn->playing = pplayer;
2806 
2807  sz_strlcpy(pconn->username, pinfo->username);
2808  pconn->addr = pinfo->addr;
2809  sz_strlcpy(pconn->capability, pinfo->capability);
2810 
2811  if (pinfo->id == client.conn.id) {
2812  /* NB: In this case, pconn is not a duplication of client.conn.
2813  *
2814  * pconn->addr is our address that the server knows whereas
2815  * client.conn.addr is the address to the server. Also,
2816  * pconn->capability stores our capabilites known at server side
2817  * whereas client.conn.capability represents the capabilities of the
2818  * server. */
2819  if (client.conn.playing != pplayer
2820  || client.conn.observer != pinfo->observer) {
2821  /* Our connection state changed, let prepare the changes and reset
2822  * the game. */
2823  preparing_client_state = true;
2824  }
2825 
2826  /* Copy our current state into the static structure (our connection
2827  * to the server). */
2828  client.conn.established = pinfo->established;
2829  client.conn.observer = pinfo->observer;
2830  client.conn.access_level = pinfo->access_level;
2831  client.conn.playing = pplayer;
2832  sz_strlcpy(client.conn.username, pinfo->username);
2833  }
2834  }
2835 
2838 
2839  if (pinfo->used && pinfo->id == client.conn.id) {
2840  /* For updating the sensitivity of the "Edit Mode" menu item,
2841  * among other things. */
2842  menus_update();
2843  }
2844 
2845  if (preparing_client_state) {
2847  }
2848 }
2849 
2855 void handle_conn_ping_info(int connections, const int *conn_id,
2856  const float *ping_time)
2857 {
2858  Q_UNUSED(connections)
2859  Q_UNUSED(conn_id)
2860  Q_UNUSED(ping_time)
2861 }
2862 
2866 void handle_achievement_info(int id, bool gained, bool first)
2867 {
2868  struct achievement *pach;
2869 
2870  if (id < 0 || id >= game.control.num_achievement_types) {
2871  qCritical("Received illegal achievement info %d", id);
2872  return;
2873  }
2874 
2875  pach = achievement_by_number(id);
2876 
2877  if (gained) {
2879  } else {
2881  }
2882 
2883  if (first) {
2884  pach->first = client_player();
2885  }
2886 }
2887 
2903 static bool spaceship_autoplace(struct player *pplayer,
2904  struct player_spaceship *ship)
2905 {
2906  if (can_client_issue_orders()) {
2907  struct spaceship_component place;
2908 
2909  if (next_spaceship_component(pplayer, ship, &place)) {
2910  dsend_packet_spaceship_place(&client.conn, place.type, place.num);
2911 
2912  return true;
2913  }
2914  }
2915 
2916  return false;
2917 }
2918 
2922 void handle_spaceship_info(const struct packet_spaceship_info *p)
2923 {
2924  struct player_spaceship *ship;
2925  struct player *pplayer = player_by_number(p->player_num);
2926 
2927  fc_assert_ret_msg(nullptr != pplayer, "Invalid player number %d.",
2928  p->player_num);
2929 
2930  ship = &pplayer->spaceship;
2931  ship->state = static_cast<spaceship_state>(p->sship_state);
2932  ship->structurals = p->structurals;
2933  ship->components = p->components;
2934  ship->modules = p->modules;
2935  ship->fuel = p->fuel;
2936  ship->propulsion = p->propulsion;
2937  ship->habitation = p->habitation;
2938  ship->life_support = p->life_support;
2939  ship->solar_panels = p->solar_panels;
2940  ship->launch_year = p->launch_year;
2941  ship->population = p->population;
2942  ship->mass = p->mass;
2943  ship->support_rate = p->support_rate;
2944  ship->energy_rate = p->energy_rate;
2945  ship->success_rate = p->success_rate;
2946  ship->travel_time = p->travel_time;
2947  ship->structure = p->structure;
2948 
2949  if (pplayer != client_player()) {
2950  refresh_spaceship_dialog(pplayer);
2951  menus_update();
2952  return;
2953  }
2954 
2955  if (!spaceship_autoplace(pplayer, ship)) {
2956  /* We refresh the dialog when the packet did *not* cause placing
2957  * of new part. That's because those cases where part is placed, are
2958  * followed by exactly one case where there's no more parts to place -
2959  * we want to refresh the dialog only when that last packet comes. */
2960  refresh_spaceship_dialog(pplayer);
2961  }
2962 }
2963 
2967 void handle_tile_info(const struct packet_tile_info *packet)
2968 {
2969  enum known_type new_known;
2970  enum known_type old_known;
2971  bool known_changed = false;
2972  bool tile_changed = false;
2973  struct player *powner = player_by_number(packet->owner);
2974  struct player *eowner = player_by_number(packet->extras_owner);
2975  struct extra_type *presource = nullptr;
2976  struct terrain *pterrain = terrain_by_number(packet->terrain);
2977  struct tile *ptile = index_to_tile(&(wld.map), packet->tile);
2978 
2979  fc_assert_ret_msg(nullptr != ptile, "Invalid tile index %d.",
2980  packet->tile);
2981  old_known = client_tile_get_known(ptile);
2982 
2983  if (packet->resource != MAX_EXTRA_TYPES) {
2984  presource = extra_by_number(packet->resource);
2985  }
2986 
2987  if (nullptr == tile_terrain(ptile) || pterrain != tile_terrain(ptile)) {
2988  tile_changed = true;
2989  switch (old_known) {
2990  case TILE_UNKNOWN:
2991  tile_set_terrain(ptile, pterrain);
2992  break;
2993  case TILE_KNOWN_UNSEEN:
2994  case TILE_KNOWN_SEEN:
2995  if (nullptr != pterrain || TILE_UNKNOWN == packet->known) {
2996  tile_set_terrain(ptile, pterrain);
2997  } else {
2998  tile_changed = false;
2999  qCritical("handle_tile_info() unknown terrain (%d, %d).",
3000  TILE_XY(ptile));
3001  }
3002  break;
3003  };
3004  }
3005 
3006  if (!BV_ARE_EQUAL(ptile->extras, packet->extras)) {
3007  ptile->extras = packet->extras;
3008  tile_changed = true;
3009  }
3010 
3011  tile_changed = tile_changed || (tile_resource(ptile) != presource);
3012 
3013  // always called after setting terrain
3014  tile_set_resource(ptile, presource);
3015 
3016  if (tile_owner(ptile) != powner) {
3017  tile_set_owner(ptile, powner, nullptr);
3018  tile_changed = true;
3019  }
3020  if (extra_owner(ptile) != eowner) {
3021  ptile->extras_owner = eowner;
3022  tile_changed = true;
3023  }
3024 
3025  if (packet->placing < 0) {
3026  if (ptile->placing != nullptr) {
3027  tile_changed = true;
3028  ptile->placing = nullptr;
3029  ptile->infra_turns = 0;
3030  }
3031  } else {
3032  struct extra_type *old = ptile->placing;
3033 
3034  ptile->placing = extra_by_number(packet->placing);
3035  if (ptile->placing != old
3036  || ptile->infra_turns != packet->place_turn - game.info.turn) {
3037  tile_changed = true;
3038  }
3039  ptile->infra_turns = packet->place_turn - game.info.turn;
3040  }
3041 
3042  if (nullptr == tile_worked(ptile)
3043  || tile_worked(ptile)->id != packet->worked) {
3044  if (IDENTITY_NUMBER_ZERO != packet->worked) {
3045  struct city *pwork = game_city_by_number(packet->worked);
3046 
3047  if (nullptr == pwork) {
3048  char named[MAX_LEN_CITYNAME];
3049 
3050  // new unseen ("invisible") city, or before city_info
3051  fc_snprintf(named, sizeof(named), "%06u", packet->worked);
3052 
3053  pwork = create_city_virtual(invisible.placeholder, nullptr, named);
3054  pwork->id = packet->worked;
3055  idex_register_city(&wld, pwork);
3056 
3057  city_list_prepend(invisible.cities, pwork);
3058 
3059  log_debug("(%d,%d) invisible city %d, %s", TILE_XY(ptile), pwork->id,
3060  city_name_get(pwork));
3061  } else if (nullptr == city_tile(pwork)) {
3062  // old unseen ("invisible") city, or before city_info
3063  if (nullptr != powner && city_owner(pwork) != powner) {
3064  // update placeholder with current owner
3065  pwork->owner = powner;
3066  pwork->original = powner;
3067  }
3068  } else {
3069  /* We have a real (not invisible) city record for this ID, but
3070  * perhaps our info about that city is out of date. */
3071  int dist_sq = sq_map_distance(city_tile(pwork), ptile);
3072 
3073  if (dist_sq > city_map_radius_sq_get(pwork)) {
3074  /* This is probably enemy city which has grown in diameter since we
3075  * last saw it. We need city_radius_sq to be at least big enough so
3076  * that all workers fit in, so set it so. */
3077  city_map_radius_sq_set(pwork, dist_sq);
3078  }
3079  /* This might be a known city that is open in a dialog.
3080  * (And this might be our only prompt to refresh the worked tiles
3081  * display in its city map, if a worker rearrangement does not
3082  * change anything else about the city such as output.) */
3083  {
3084  struct city *oldwork = tile_worked(ptile);
3085  if (oldwork && nullptr != city_tile(oldwork)) {
3086  // Refresh previous city too if it's real and different
3087  refresh_city_dialog(oldwork);
3088  }
3089  // Refresh new city working tile (which we already know is real)
3090  refresh_city_dialog(pwork);
3091  }
3092  }
3093 
3094  /* This marks tile worked by (possibly invisible) city. Other
3095  * parts of the code have to handle invisible cities correctly
3096  * (ptile->worked->tile == nullptr) */
3097  tile_set_worked(ptile, pwork);
3098  } else {
3099  /* Tile is no longer being worked by a city.
3100  * (Again, this might be our only prompt to refresh the worked tiles
3101  * display for the previous working city.) */
3102  if (tile_worked(ptile) && nullptr != city_tile(tile_worked(ptile))) {
3104  }
3105  tile_set_worked(ptile, nullptr);
3106  }
3107 
3108  tile_changed = true;
3109  }
3110 
3111  if (old_known != packet->known) {
3112  known_changed = true;
3113  }
3114 
3115  if (nullptr != client.conn.playing) {
3116  client.conn.playing->tile_known->setBit(tile_index(ptile), false);
3118  {
3119  client.conn.playing->client.tile_vision[v]->setBit(tile_index(ptile),
3120  false);
3121  }
3123 
3124  switch (packet->known) {
3125  case TILE_KNOWN_SEEN:
3126  client.conn.playing->tile_known->setBit(tile_index(ptile));
3128  {
3129  client.conn.playing->client.tile_vision[v]->setBit(
3130  tile_index(ptile));
3131  }
3133  break;
3134  case TILE_KNOWN_UNSEEN:
3135  client.conn.playing->tile_known->setBit(tile_index(ptile));
3136  break;
3137  case TILE_UNKNOWN:
3138  break;
3139  default:
3140  qCritical("handle_tile_info() invalid known (%d).", packet->known);
3141  break;
3142  };
3143  }
3144  new_known = client_tile_get_known(ptile);
3145 
3146  if (packet->spec_sprite[0] != '\0') {
3147  if (!ptile->spec_sprite
3148  || strcmp(ptile->spec_sprite, packet->spec_sprite) != 0) {
3149  delete[] ptile->spec_sprite;
3150  ptile->spec_sprite = fc_strdup(packet->spec_sprite);
3151  tile_changed = true;
3152  }
3153  } else {
3154  if (ptile->spec_sprite) {
3155  delete[] ptile->spec_sprite;
3156  ptile->spec_sprite = nullptr;
3157  tile_changed = true;
3158  }
3159  }
3160 
3161  if (TILE_KNOWN_SEEN == old_known && TILE_KNOWN_SEEN != new_known) {
3162  /* This is an error. So first we log the error,
3163  * then make an assertion. */
3164  unit_list_iterate(ptile->units, punit)
3165  {
3166  qCritical("%p %d %s at (%d,%d) %s", punit, punit->id,
3167  unit_rule_name(punit), TILE_XY(unit_tile(punit)),
3168  player_name(unit_owner(punit)));
3169  }
3171  fc_assert_msg(0 == unit_list_size(ptile->units), "Ghost units seen");
3172  // Repairing...
3173  unit_list_clear(ptile->units);
3174  }
3175 
3176  ptile->continent = packet->continent;
3178 
3179  if (packet->label[0] == '\0') {
3180  if (ptile->label != nullptr) {
3181  delete[] ptile->label;
3182  ptile->label = nullptr;
3183  tile_changed = true;
3184  }
3185  } else if (ptile->label == nullptr
3186  || strcmp(packet->label, ptile->label)) {
3187  tile_set_label(ptile, packet->label);
3188  tile_changed = true;
3189  }
3190 
3191  if (known_changed || tile_changed) {
3193  }
3194 
3195  // refresh tiles
3196  if (can_client_change_view()) {
3197  // the tile itself (including the necessary parts of adjacent tiles)
3198  if (tile_changed || old_known != new_known) {
3199  refresh_tile_mapcanvas(ptile, true);
3200  }
3201  }
3202 
3203  // update menus if the focus unit is on the tile.
3204  if (tile_changed) {
3205  if (get_focus_unit_on_tile(ptile)) {
3206  menus_update();
3207  }
3208  }
3209 
3210  /* FIXME: we really ought to call refresh_city_dialog() for any city
3211  * whose radii include this tile, to update the city map display.
3212  * But that would be expensive. We deal with the (common) special
3213  * case of changes in worked tiles above. */
3214 }
3215 
3219 void handle_scenario_info(const struct packet_scenario_info *packet)
3220 {
3221  game.scenario.is_scenario = packet->is_scenario;
3222  sz_strlcpy(game.scenario.name, packet->name);
3223  sz_strlcpy(game.scenario.authors, packet->authors);
3224  game.scenario.players = packet->players;
3225  game.scenario.startpos_nations = packet->startpos_nations;
3226  game.scenario.prevent_new_cities = packet->prevent_new_cities;
3227  game.scenario.lake_flooding = packet->lake_flooding;
3228  game.scenario.have_resources = packet->have_resources;
3229  game.scenario.ruleset_locked = packet->ruleset_locked;
3230  game.scenario.save_random = packet->save_random;
3231  game.scenario.handmade = packet->handmade;
3232  game.scenario.allow_ai_type_fallback = packet->allow_ai_type_fallback;
3233 
3235 }
3236 
3240 void handle_scenario_description(const char *description)
3241 {
3242  sz_strlcpy(game.scenario_desc.description, description);
3243 
3245 }
3246 
3252 void handle_ruleset_control(const struct packet_ruleset_control *packet)
3253 {
3254  /* The ruleset is going to load new nations. So close
3255  * the nation selection dialog if it is open. */
3257 
3258  game.client.ruleset_init = false;
3259  game.client.ruleset_ready = false;
3262  game.client.ruleset_init = true;
3263  game.control = *packet;
3264 
3265  // check the values!
3266 #define VALIDATE(_count, _maximum, _string) \
3267  if (game.control._count > _maximum) { \
3268  qCritical("handle_ruleset_control(): Too many " _string \
3269  "; using %d of %d", \
3270  _maximum, game.control._count); \
3271  game.control._count = _maximum; \
3272  }
3273 
3274  VALIDATE(num_unit_classes, UCL_LAST, "unit classes");
3275  VALIDATE(num_unit_types, U_LAST, "unit types");
3276  VALIDATE(num_impr_types, B_LAST, "improvements");
3277  VALIDATE(num_tech_types, A_LAST, "advances");
3278  VALIDATE(num_base_types, MAX_BASE_TYPES, "bases");
3279  VALIDATE(num_road_types, MAX_ROAD_TYPES, "roads");
3280  VALIDATE(num_resource_types, MAX_RESOURCE_TYPES, "resources");
3281  VALIDATE(num_disaster_types, MAX_DISASTER_TYPES, "disasters");
3282  VALIDATE(num_achievement_types, MAX_ACHIEVEMENT_TYPES, "achievements");
3283 
3284  /* game.control.government_count, game.control.nation_count and
3285  * game.control.styles_count are allocated dynamically, and does
3286  * not need a size check. See the allocation bellow. */
3287 
3288  VALIDATE(terrain_count, MAX_NUM_TERRAINS, "terrains");
3289 
3290  VALIDATE(num_specialist_types, SP_MAX, "specialists");
3291 #undef VALIDATE
3292 
3293  governments_alloc(game.control.government_count);
3294  nations_alloc(game.control.nation_count);
3295  styles_alloc(game.control.num_styles);
3296  city_styles_alloc(game.control.styles_count);
3297  music_styles_alloc(game.control.num_music_styles);
3298 
3299  if (game.control.desc_length > 0) {
3300  game.ruleset_description = new char[game.control.desc_length + 1];
3301  game.ruleset_description[0] = '\0';
3302  }
3303 
3304  if (packet->preferred_tileset[0] != '\0') {
3305  // There is tileset suggestion
3306  if (strcmp(packet->preferred_tileset, tileset_basename(tileset))) {
3307  // It's not currently in use
3309  tilespec_reread(game.control.preferred_tileset, true);
3310  } else {
3312  }
3313  }
3314  }
3315 
3316  if (packet->preferred_soundset[0] != '\0') {
3317  // There is soundset suggestion
3318  if (QString(packet->preferred_soundset) != sound_set_name) {
3319  // It's not currently in use
3321  audio_restart(game.control.preferred_soundset, music_set_name);
3322  } else {
3324  }
3325  }
3326  }
3327 
3328  if (packet->preferred_musicset[0] != '\0') {
3329  // There is musicset suggestion
3330  if (QString(packet->preferred_musicset) != music_set_name) {
3331  // It's not currently in use
3333  audio_restart(sound_set_name, game.control.preferred_musicset);
3334  } else {
3336  }
3337  }
3338  }
3339 
3341 }
3342 
3346 void handle_ruleset_summary(const struct packet_ruleset_summary *packet)
3347 {
3348  int len;
3349 
3350  delete[] game.ruleset_summary;
3351  len = qstrlen(packet->text);
3352  game.ruleset_summary = new char[len + 1];
3353 
3354  fc_strlcpy(game.ruleset_summary, packet->text, len + 1);
3355 }
3356 
3361  const struct packet_ruleset_description_part *packet)
3362 {
3363  fc_strlcat(game.ruleset_description, packet->text,
3364  game.control.desc_length + 1);
3365 }
3366 
3371 {
3372  // Init extras - has to come after terrain
3373  extra_type_iterate(pextra) { tileset_setup_extra(tileset, pextra); }
3375 
3376  // Setup extra hiders caches
3377  extra_type_iterate(pextra)
3378  {
3379  pextra->hiders = extra_type_list_new();
3380  extra_type_iterate(phider)
3381  {
3382  if (BV_ISSET(pextra->hidden_by, extra_index(phider))) {
3383  extra_type_list_append(pextra->hiders, phider);
3384  }
3385  }
3387  pextra->bridged = extra_type_list_new();
3388  extra_type_iterate(pbridged)
3389  {
3390  if (BV_ISSET(pextra->bridged_over, extra_index(pbridged))) {
3391  extra_type_list_append(pextra->bridged, pbridged);
3392  }
3393  }
3395  }
3397 
3398  unit_class_iterate(pclass)
3399  {
3400  set_unit_class_caches(pclass);
3401  set_unit_move_type(pclass);
3402  }
3404 
3405  // Setup improvement feature caches
3407 
3408  // Setup road integrators caches
3410 
3411  // Pre calculate action related data.
3413 
3414  // Setup unit unknown move cost caches
3415  unit_type_iterate(ptype)
3416  {
3417  ptype->unknown_move_cost = utype_unknown_move_cost(ptype);
3418  set_unit_type_caches(ptype);
3420  }
3422 
3423  // Cache what city production can receive help from caravans.
3425 
3426  // Adjust editor for changed ruleset.
3428 
3429  // We are not going to crop any more sprites from big sprites, free them.
3431 
3432  game.client.ruleset_ready = true;
3433 }
3434 
3438 void handle_ruleset_unit_class(const struct packet_ruleset_unit_class *p)
3439 {
3440  struct unit_class *c = uclass_by_number(p->id);
3441 
3442  fc_assert_ret_msg(nullptr != c, "Bad unit_class %d.", p->id);
3443 
3444  names_set(&c->name, nullptr, p->name, p->rule_name);
3445  c->min_speed = p->min_speed;
3446  c->hp_loss_pct = p->hp_loss_pct;
3447  c->hut_behavior = static_cast<hut_behavior>(p->hut_behavior);
3448  c->non_native_def_pct = p->non_native_def_pct;
3449  c->flags = p->flags;
3450 
3451  c->helptext = packet_strvec_extract(p->helptext);
3452 }
3453 
3457 void handle_ruleset_unit(const struct packet_ruleset_unit *p)
3458 {
3459  int i;
3460  struct unit_type *u = utype_by_number(p->id);
3461 
3462  fc_assert_ret_msg(nullptr != u, "Bad unit_type %d.", p->id);
3463 
3464  names_set(&u->name, nullptr, p->name, p->rule_name);
3465  sz_strlcpy(u->graphic_str, p->graphic_str);
3466  sz_strlcpy(u->graphic_alt, p->graphic_alt);
3467  sz_strlcpy(u->sound_move, p->sound_move);
3468  sz_strlcpy(u->sound_move_alt, p->sound_move_alt);
3469  sz_strlcpy(u->sound_fight, p->sound_fight);
3470  sz_strlcpy(u->sound_fight_alt, p->sound_fight_alt);
3471 
3472  u->uclass = uclass_by_number(p->unit_class_id);
3473  u->build_cost = p->build_cost;
3474  u->pop_cost = p->pop_cost;
3475  u->attack_strength = p->attack_strength;
3476  u->defense_strength = p->defense_strength;
3477  u->move_rate = p->move_rate;
3478  u->require_advance = advance_by_number(p->tech_requirement);
3479  for (i = 0; i < p->build_reqs_count; i++) {
3480  requirement_vector_append(&u->build_reqs, p->build_reqs[i]);
3481  }
3482  u->vision_radius_sq = p->vision_radius_sq;
3483  u->transport_capacity = p->transport_capacity;
3484  u->hp = p->hp;
3485  u->firepower = p->firepower;
3486  u->obsoleted_by = utype_by_number(p->obsoleted_by);
3487  u->converted_to = utype_by_number(p->converted_to);
3488  u->convert_time = p->convert_time;
3489  u->fuel = p->fuel;
3490  u->flags = p->flags;
3491  u->roles = p->roles;
3492  u->happy_cost = p->happy_cost;
3493  output_type_iterate(o) { u->upkeep[o] = p->upkeep[o]; }
3495  u->paratroopers_range = p->paratroopers_range;
3496  u->bombard_rate = p->bombard_rate;
3497  u->city_size = p->city_size;
3498  u->city_slots = p->city_slots;
3499  u->cargo = p->cargo;
3500  u->targets = p->targets;
3501  u->embarks = p->embarks;
3502  u->disembarks = p->disembarks;
3503  u->vlayer = p->vlayer;
3504 
3505  if (p->veteran_levels == 0) {
3506  u->veteran = nullptr;
3507  } else {
3508  u->veteran = veteran_system_new(p->veteran_levels);
3509 
3510  for (i = 0; i < p->veteran_levels; i++) {
3511  veteran_system_definition(u->veteran, i, p->veteran_name[i],
3512  p->power_fact[i], p->move_bonus[i],
3513  p->base_raise_chance[i],
3514  p->work_raise_chance[i]);
3515  }
3516  }
3517 
3518  u->helptext = packet_strvec_extract(p->helptext);
3519 
3520  u->adv.worker = p->worker;
3521 
3523 }
3524 
3528 void handle_ruleset_unit_bonus(const struct packet_ruleset_unit_bonus *p)
3529 {
3530  struct unit_type *u = utype_by_number(p->unit);
3531  struct combat_bonus *bonus;
3532 
3533  fc_assert_ret_msg(nullptr != u, "Bad unit_type %d.", p->unit);
3534 
3535  bonus = new combat_bonus;
3536 
3537  bonus->flag = p->flag;
3538  bonus->type = p->type;
3539  bonus->value = p->value;
3540  bonus->quiet = p->quiet;
3541 
3542  combat_bonus_list_append(u->bonuses, bonus);
3543 }
3544 
3548 void handle_ruleset_unit_flag(const struct packet_ruleset_unit_flag *p)
3549 {
3550  const char *flagname;
3551  const char *helptxt;
3552 
3553  fc_assert_ret_msg(p->id >= UTYF_USER_FLAG_1
3554  && p->id <= UTYF_LAST_USER_FLAG,
3555  "Bad user flag %d.", p->id);
3556 
3557  if (p->name[0] == '\0') {
3558  flagname = nullptr;
3559  } else {
3560  flagname = p->name;
3561  }
3562 
3563  if (p->helptxt[0] == '\0') {
3564  helptxt = nullptr;
3565  } else {
3566  helptxt = p->helptxt;
3567  }
3568 
3569  set_user_unit_type_flag_name(static_cast<unit_type_flag_id>(p->id),
3570  flagname, helptxt);
3571 }
3572 
3577  const struct packet_ruleset_unit_class_flag *p)
3578 {
3579  const char *flagname;
3580  const char *helptxt;
3581 
3582  fc_assert_ret_msg(p->id >= UCF_USER_FLAG_1 && p->id <= UCF_LAST_USER_FLAG,
3583  "Bad user flag %d.", p->id);
3584 
3585  if (p->name[0] == '\0') {
3586  flagname = nullptr;
3587  } else {
3588  flagname = p->name;
3589  }
3590 
3591  if (p->helptxt[0] == '\0') {
3592  helptxt = nullptr;
3593  } else {
3594  helptxt = p->helptxt;
3595  }
3596 
3597  set_user_unit_class_flag_name(static_cast<unit_class_flag_id>(p->id),
3598  flagname, helptxt);
3599 }
3600 
3609 static int unpack_tech_req(const enum tech_req r_num, const int reqs_size,
3610  const struct requirement *reqs, struct advance *a,
3611  int i)
3612 {
3613  if (i < reqs_size && reqs[i].source.kind == VUT_ADVANCE) {
3614  // Extract the tech req so the old code can reason about it.
3615 
3616  // This IS a traditional tech req... right?
3617  fc_assert(reqs[i].present);
3618  fc_assert(reqs[i].range == REQ_RANGE_PLAYER);
3619 
3620  // Put it in the advance structure.
3621  a->require[r_num] = reqs[i].source.value.advance;
3622 
3623  // Move on in the requirement vector.
3624  i++;
3625  } else {
3626  // No tech req.
3627  a->require[r_num] = advance_by_number(A_NONE);
3628  }
3629 
3630  return i;
3631 }
3632 
3636 void handle_ruleset_tech(const struct packet_ruleset_tech *p)
3637 {
3638  int i;
3639  struct advance *a = advance_by_number(p->id);
3640 
3641  fc_assert_ret_msg(nullptr != a, "Bad advance %d.", p->id);
3642 
3643  names_set(&a->name, nullptr, p->name, p->rule_name);
3644  sz_strlcpy(a->graphic_str, p->graphic_str);
3645  sz_strlcpy(a->graphic_alt, p->graphic_alt);
3646 
3647  i = 0;
3648 
3649  fc_assert(game.control.num_tech_classes == 0
3650  || p->tclass < game.control.num_tech_classes);
3651  if (p->tclass >= 0) {
3652  a->tclass = tech_class_by_number(p->tclass);
3653  } else {
3654  a->tclass = nullptr;
3655  }
3656 
3657  /* The tech requirements req1 and req2 are send inside research_reqs
3658  * since they too are required to be fulfilled before the tech can be
3659  * researched. */
3660 
3661  if (p->removed) {
3662  /* The Freeciv data structures currently records that a tech is removed
3663  * by setting req1 and req2 to "Never". */
3664  a->require[AR_ONE] = A_NEVER;
3665  a->require[AR_TWO] = A_NEVER;
3666  } else {
3667  // Unpack req1 and req2 from the research_reqs requirement vector.
3668  i = unpack_tech_req(AR_ONE, p->research_reqs_count, p->research_reqs, a,
3669  i);
3670  i = unpack_tech_req(AR_TWO, p->research_reqs_count, p->research_reqs, a,
3671  i);
3672  }
3673 
3674  /* Any remaining requirements are a part of the research_reqs requirement
3675  * vector. */
3676  for (; i < p->research_reqs_count; i++) {
3677  requirement_vector_append(&a->research_reqs, p->research_reqs[i]);
3678  }
3679 
3680  /* The packet's research_reqs should contain req1, req2 and the
3681  * requirements of the tech's research_reqs. */
3682  fc_assert((a->research_reqs.size
3683  + ((a->require[AR_ONE]
3684  && (advance_number(a->require[AR_ONE]) != A_NONE))
3685  ? 1
3686  : 0)
3687  + ((a->require[AR_TWO]
3688  && (advance_number(a->require[AR_TWO]) != A_NONE))
3689  ? 1
3690  : 0))
3691  == p->research_reqs_count);
3692 
3693  a->require[AR_ROOT] = advance_by_number(p->root_req);
3694 
3695  a->flags = p->flags;
3696  a->cost = p->cost;
3697  a->num_reqs = p->num_reqs;
3698  a->helptext = packet_strvec_extract(p->helptext);
3699 
3701 }
3702 
3706 void handle_ruleset_tech_class(const struct packet_ruleset_tech_class *p)
3707 {
3708  struct tech_class *ptclass = tech_class_by_number(p->id);
3709 
3710  fc_assert_ret_msg(nullptr != ptclass, "Bad tech_class %d.", p->id);
3711 
3712  names_set(&ptclass->name, nullptr, p->name, p->rule_name);
3713  ptclass->cost_pct = p->cost_pct;
3714 }
3715 
3719 void handle_ruleset_tech_flag(const struct packet_ruleset_tech_flag *p)
3720 {
3721  const char *flagname;
3722  const char *helptxt;
3723 
3724  fc_assert_ret_msg(p->id >= TECH_USER_1 && p->id <= TECH_USER_LAST,
3725  "Bad user flag %d.", p->id);
3726 
3727  if (p->name[0] == '\0') {
3728  flagname = nullptr;
3729  } else {
3730  flagname = p->name;
3731  }
3732 
3733  if (p->helptxt[0] == '\0') {
3734  helptxt = nullptr;
3735  } else {
3736  helptxt = p->helptxt;
3737  }
3738 
3739  set_user_tech_flag_name(static_cast<tech_flag_id>(p->id), flagname,
3740  helptxt);
3741 }
3742 
3746 void handle_ruleset_building(const struct packet_ruleset_building *p)
3747 {
3748  int i;
3749  struct impr_type *b = improvement_by_number(p->id);
3750 
3751  fc_assert_ret_msg(nullptr != b, "Bad improvement %d.", p->id);
3752 
3753  b->genus = p->genus;
3754  names_set(&b->name, nullptr, p->name, p->rule_name);
3755  sz_strlcpy(b->graphic_str, p->graphic_str);
3756  sz_strlcpy(b->graphic_alt, p->graphic_alt);
3757  for (i = 0; i < p->reqs_count; i++) {
3758  requirement_vector_append(&b->reqs, p->reqs[i]);
3759  }
3760  fc_assert(b->reqs.size == p->reqs_count);
3761  for (i = 0; i < p->obs_count; i++) {
3762  requirement_vector_append(&b->obsolete_by, p->obs_reqs[i]);
3763  }
3764  fc_assert(b->obsolete_by.size == p->obs_count);
3765  b->build_cost = p->build_cost;
3766  b->upkeep = p->upkeep;
3767  b->sabotage = p->sabotage;
3768  b->flags = p->flags;
3769  b->helptext = packet_strvec_extract(p->helptext);
3770 
3771  sz_strlcpy(b->soundtag, p->soundtag);
3772  sz_strlcpy(b->soundtag_alt, p->soundtag_alt);
3773 
3774 #ifdef FREECIV_DEBUG
3775  if (p->id == improvement_count() - 1) {
3776  improvement_iterate(bdbg)
3777  {
3778  log_debug("Improvement: %s...", improvement_rule_name(bdbg));
3779  log_debug(" build_cost %3d", bdbg->build_cost);
3780  log_debug(" upkeep %2d", bdbg->upkeep);
3781  log_debug(" sabotage %3d", bdbg->sabotage);
3782  if (nullptr != bdbg->helptext) {
3783  for (auto text : *bdbg->helptext) {
3784  log_debug(" helptext %s", qUtf8Printable(text));
3785  }
3786  }
3787  }
3789  }
3790 #endif // FREECIV_DEBUG
3791 
3793 }
3794 
3798 void handle_ruleset_multiplier(const struct packet_ruleset_multiplier *p)
3799 {
3800  struct multiplier *pmul = multiplier_by_number(p->id);
3801  int j;
3802 
3803  fc_assert_ret_msg(nullptr != pmul, "Bad multiplier %d.", p->id);
3804 
3805  pmul->start = p->start;
3806  pmul->stop = p->stop;
3807  pmul->step = p->step;
3808  pmul->def = p->def;
3809  pmul->offset = p->offset;
3810  pmul->factor = p->factor;
3811 
3812  names_set(&pmul->name, nullptr, p->name, p->rule_name);
3813 
3814  for (j = 0; j < p->reqs_count; j++) {
3815  requirement_vector_append(&pmul->reqs, p->reqs[j]);
3816  }
3817  fc_assert(pmul->reqs.size == p->reqs_count);
3818 
3819  pmul->helptext = packet_strvec_extract(p->helptext);
3820 }
3821 
3825 void handle_ruleset_government(const struct packet_ruleset_government *p)
3826 {
3827  int j;
3828  struct government *gov = government_by_number(p->id);
3829 
3830  fc_assert_ret_msg(nullptr != gov, "Bad government %d.", p->id);
3831 
3832  gov->item_number = p->id;
3833 
3834  for (j = 0; j < p->reqs_count; j++) {
3835  requirement_vector_append(&gov->reqs, p->reqs[j]);
3836  }
3837  fc_assert(gov->reqs.size == p->reqs_count);
3838 
3839  names_set(&gov->name, nullptr, p->name, p->rule_name);
3840  sz_strlcpy(gov->graphic_str, p->graphic_str);
3841  sz_strlcpy(gov->graphic_alt, p->graphic_alt);
3842 
3843  gov->helptext = packet_strvec_extract(p->helptext);
3844 
3846 }
3847 
3852  const struct packet_ruleset_government_ruler_title *packet)
3853 {
3854  struct government *gov = government_by_number(packet->gov);
3855 
3856  fc_assert_ret_msg(nullptr != gov, "Bad government %d.", packet->gov);
3857 
3858  (void) government_ruler_title_new(gov, nation_by_number(packet->nation),
3859  packet->male_title,
3860  packet->female_title);
3861 }
3862 
3866 void handle_ruleset_terrain(const struct packet_ruleset_terrain *p)
3867 {
3868  int j;
3869  struct terrain *pterrain = terrain_by_number(p->id);
3870 
3871  fc_assert_ret_msg(nullptr != pterrain, "Bad terrain %d.", p->id);
3872 
3873  pterrain->tclass = static_cast<terrain_class>(p->tclass);
3874  pterrain->native_to = p->native_to;
3875  names_set(&pterrain->name, nullptr, p->name, p->rule_name);
3876  sz_strlcpy(pterrain->graphic_str, p->graphic_str);
3877  sz_strlcpy(pterrain->graphic_alt, p->graphic_alt);
3878  pterrain->movement_cost = p->movement_cost;
3879  pterrain->defense_bonus = p->defense_bonus;
3880 
3881  output_type_iterate(o) { pterrain->output[o] = p->output[o]; }
3883 
3884  delete[] pterrain->resources;
3885  pterrain->resources = new extra_type *[p->num_resources + 1]();
3886  for (j = 0; j < p->num_resources; j++) {
3887  pterrain->resources[j] = extra_by_number(p->resources[j]);
3888  if (!pterrain->resources[j]) {
3889  qCritical("handle_ruleset_terrain() "
3890  "Mismatched resource %d for terrain \"%s\".",
3891  p->resources[j], terrain_rule_name(pterrain));
3892  }
3893  }
3894  pterrain->resources[p->num_resources] = nullptr;
3895 
3897  {
3898  pterrain->road_output_incr_pct[o] = p->road_output_incr_pct[o];
3899  }
3901 
3902  pterrain->base_time = p->base_time;
3903  pterrain->road_time = p->road_time;
3904  pterrain->cultivate_time = p->cultivate_time;
3905  pterrain->plant_time = p->plant_time;
3906  pterrain->irrigation_result = terrain_by_number(p->irrigation_result);
3907  pterrain->irrigation_food_incr = p->irrigation_food_incr;
3908  pterrain->irrigation_time = p->irrigation_time;
3909  pterrain->mining_result = terrain_by_number(p->mining_result);
3910  pterrain->mining_shield_incr = p->mining_shield_incr;
3911  pterrain->mining_time = p->mining_time;
3912  if (p->animal < 0) {
3913  pterrain->animal = nullptr;
3914  } else {
3915  pterrain->animal = utype_by_number(p->animal);
3916  }
3917  pterrain->transform_result = terrain_by_number(p->transform_result);
3918  pterrain->transform_time = p->transform_time;
3919  pterrain->placing_time = p->placing_time;
3920  pterrain->pillage_time = p->pillage_time;
3921  pterrain->clean_pollution_time = p->clean_pollution_time;
3922  pterrain->clean_fallout_time = p->clean_fallout_time;
3923 
3924  pterrain->flags = p->flags;
3925 
3926  fc_assert_ret(pterrain->rgb == nullptr);
3927  pterrain->rgb = rgbcolor_new(p->color_red, p->color_green, p->color_blue);
3928 
3929  pterrain->helptext = packet_strvec_extract(p->helptext);
3930 
3931  tileset_setup_tile_type(tileset, pterrain);
3932 }
3933 
3937 void handle_ruleset_terrain_flag(const struct packet_ruleset_terrain_flag *p)
3938 {
3939  const char *flagname;
3940  const char *helptxt;
3941 
3942  fc_assert_ret_msg(p->id >= TER_USER_1 && p->id <= TER_USER_LAST,
3943  "Bad user flag %d.", p->id);
3944 
3945  if (p->name[0] == '\0') {
3946  flagname = nullptr;
3947  } else {
3948  flagname = p->name;
3949  }
3950 
3951  if (p->helptxt[0] == '\0') {
3952  helptxt = nullptr;
3953  } else {
3954  helptxt = p->helptxt;
3955  }
3956 
3957  set_user_terrain_flag_name(static_cast<terrain_flag_id>(p->id), flagname,
3958  helptxt);
3959 }
3960 
3964 void handle_ruleset_resource(const struct packet_ruleset_resource *p)
3965 {
3966  struct resource_type *presource;
3967 
3968  if (p->id < 0 || p->id > MAX_EXTRA_TYPES) {
3969  qCritical("Bad resource %d.", p->id);
3970  return;
3971  }
3972 
3973  presource = resource_type_init(extra_by_number(p->id));
3974 
3975  output_type_iterate(o) { presource->output[o] = p->output[o]; }
3977 }
3978 
3982 void handle_ruleset_extra(const struct packet_ruleset_extra *p)
3983 {
3984  struct extra_type *pextra = extra_by_number(p->id);
3985  int i;
3986  bool cbase;
3987  bool croad;
3988  bool cres;
3989 
3990  fc_assert_ret_msg(nullptr != pextra, "Bad extra %d.", p->id);
3991 
3992  names_set(&pextra->name, nullptr, p->name, p->rule_name);
3993 
3994  pextra->category = static_cast<extra_category>(p->category);
3995 
3996  pextra->causes = 0;
3997  for (i = 0; i < EC_COUNT; i++) {
3998  if (BV_ISSET(p->causes, i)) {
3999  pextra->causes |= (1 << i);
4000  }
4001  }
4002 
4003  pextra->rmcauses = 0;
4004  for (i = 0; i < ERM_COUNT; i++) {
4005  if (BV_ISSET(p->rmcauses, i)) {
4006  pextra->rmcauses |= (1 << i);
4007  }
4008  }
4009 
4010  if (pextra->causes == 0) {
4012  } else {
4013  for (i = 0; i < EC_COUNT; i++) {
4014  if (is_extra_caused_by(pextra, i)) {
4015  extra_to_caused_by_list(pextra, static_cast<extra_cause>(i));
4016  }
4017  }
4018  }
4019 
4020  cbase = is_extra_caused_by(pextra, EC_BASE);
4021  croad = is_extra_caused_by(pextra, EC_ROAD);
4022  cres = is_extra_caused_by(pextra, EC_RESOURCE);
4023  if (cbase) {
4024  /* Index is one less than size of list when this base is already added.
4025  */
4027  pextra, extra_type_list_size(extra_type_list_by_cause(EC_BASE)) - 1);
4028  }
4029  if (croad) {
4030  /* Index is one less than size of list when this road is already added.
4031  */
4033  pextra, extra_type_list_size(extra_type_list_by_cause(EC_ROAD)) - 1);
4034  }
4035  if (!cbase && !croad && !cres) {
4036  pextra->data.special_idx = extra_type_list_size(
4037  extra_type_list_by_cause(static_cast<extra_cause>(EC_SPECIAL)));
4038  extra_to_caused_by_list(pextra, static_cast<extra_cause>(EC_SPECIAL));
4039  }
4040 
4041  for (i = 0; i < ERM_COUNT; i++) {
4042  if (is_extra_removed_by(pextra, static_cast<extra_rmcause>(i))) {
4043  extra_to_removed_by_list(pextra, static_cast<extra_rmcause>(i));
4044  }
4045  }
4046 
4047  sz_strlcpy(pextra->activity_gfx, p->activity_gfx);
4048  sz_strlcpy(pextra->act_gfx_alt, p->act_gfx_alt);
4049  sz_strlcpy(pextra->act_gfx_alt2, p->act_gfx_alt2);
4050  sz_strlcpy(pextra->rmact_gfx, p->rmact_gfx);
4051  sz_strlcpy(pextra->rmact_gfx_alt, p->rmact_gfx_alt);
4052  sz_strlcpy(pextra->graphic_str, p->graphic_str);
4053  sz_strlcpy(pextra->graphic_alt, p->graphic_alt);
4054 
4055  for (i = 0; i < p->reqs_count; i++) {
4056  requirement_vector_append(&pextra->reqs, p->reqs[i]);
4057  }
4058  fc_assert(pextra->reqs.size == p->reqs_count);
4059 
4060  for (i = 0; i < p->rmreqs_count; i++) {
4061  requirement_vector_append(&pextra->rmreqs, p->rmreqs[i]);
4062  }
4063  fc_assert(pextra->rmreqs.size == p->rmreqs_count);
4064 
4065  pextra->appearance_chance = p->appearance_chance;
4066  for (i = 0; i < p->appearance_reqs_count; i++) {
4067  requirement_vector_append(&pextra->appearance_reqs,
4068  p->appearance_reqs[i]);
4069  }
4070  fc_assert(pextra->appearance_reqs.size == p->appearance_reqs_count);
4071 
4072  pextra->disappearance_chance = p->disappearance_chance;
4073  for (i = 0; i < p->disappearance_reqs_count; i++) {
4074  requirement_vector_append(&pextra->disappearance_reqs,
4075  p->disappearance_reqs[i]);
4076  }
4077  fc_assert(pextra->disappearance_reqs.size == p->disappearance_reqs_count);
4078 
4079  pextra->visibility_req = p->visibility_req;
4080  pextra->buildable = p->buildable;
4081  pextra->generated = p->generated;
4082  pextra->build_time = p->build_time;
4083  pextra->build_time_factor = p->build_time_factor;
4084  pextra->removal_time = p->removal_time;
4085  pextra->removal_time_factor = p->removal_time_factor;
4086  pextra->defense_bonus = p->defense_bonus;
4087 
4088  if (pextra->defense_bonus != 0) {
4089  if (extra_has_flag(pextra, EF_NATURAL_DEFENSE)) {
4091  pextra, static_cast<extra_cause>(EC_NATURAL_DEFENSIVE));
4092  } else {
4093  extra_to_caused_by_list(pextra,
4094  static_cast<extra_cause>(EC_DEFENSIVE));
4095  }
4096  }
4097 
4098  pextra->eus = p->eus;
4099  if (pextra->eus == EUS_HIDDEN) {
4100  extra_type_list_append(extra_type_list_of_unit_hiders(), pextra);
4101  }
4102 
4103  pextra->native_to = p->native_to;
4104 
4105  pextra->flags = p->flags;
4106  pextra->hidden_by = p->hidden_by;
4107  pextra->bridged_over = p->bridged_over;
4108  pextra->conflicts = p->conflicts;
4109 
4110  pextra->helptext = packet_strvec_extract(p->helptext);
4111 }
4112 
4116 void handle_ruleset_extra_flag(const struct packet_ruleset_extra_flag *p)
4117 {
4118  const char *flagname;
4119  const char *helptxt;
4120 
4121  fc_assert_ret_msg(p->id >= EF_USER_FLAG_1 && p->id <= EF_LAST_USER_FLAG,
4122  "Bad user flag %d.", p->id);
4123 
4124  if (p->name[0] == '\0') {
4125  flagname = nullptr;
4126  } else {
4127  flagname = p->name;
4128  }
4129 
4130  if (p->helptxt[0] == '\0') {
4131  helptxt = nullptr;
4132  } else {
4133  helptxt = p->helptxt;
4134  }
4135 
4136  set_user_extra_flag_name(static_cast<extra_flag_id>(p->id), flagname,
4137  helptxt);
4138 }
4139 
4143 void handle_ruleset_base(const struct packet_ruleset_base *p)
4144 {
4145  struct base_type *pbase = base_by_number(p->id);
4146 
4147  fc_assert_ret_msg(nullptr != pbase, "Bad base %d.", p->id);
4148 
4149  pbase->gui_type = p->gui_type;
4150  pbase->border_sq = p->border_sq;
4151  pbase->vision_main_sq = p->vision_main_sq;
4152  pbase->vision_invis_sq = p->vision_invis_sq;
4153  pbase->vision_subs_sq = p->vision_subs_sq;
4154 
4155  pbase->flags = p->flags;
4156 }
4157 
4161 void handle_ruleset_road(const struct packet_ruleset_road *p)
4162 {
4163  int i;
4164  struct road_type *proad = road_by_number(p->id);
4165 
4166  fc_assert_ret_msg(nullptr != proad, "Bad road %d.", p->id);
4167 
4168  for (i = 0; i < p->first_reqs_count; i++) {
4169  requirement_vector_append(&proad->first_reqs, p->first_reqs[i]);
4170  }
4171  fc_assert(proad->first_reqs.size == p->first_reqs_count);
4172 
4173  proad->move_cost = p->move_cost;
4174  proad->move_mode = p->move_mode;
4175 
4177  {
4178  proad->tile_incr_const[o] = p->tile_incr_const[o];
4179  proad->tile_incr[o] = p->tile_incr[o];
4180  proad->tile_bonus[o] = p->tile_bonus[o];
4181  }
4183 
4184  proad->compat = p->compat;
4185  proad->integrates = p->integrates;
4186  proad->flags = p->flags;
4187 }
4188 
4192 void handle_ruleset_goods(const struct packet_ruleset_goods *p)
4193 {
4194  struct goods_type *pgood = goods_by_number(p->id);
4195  int i;
4196 
4197  fc_assert_ret_msg(nullptr != pgood, "Bad goods %d.", p->id);
4198 
4199  names_set(&pgood->name, nullptr, p->name, p->rule_name);
4200 
4201  for (i = 0; i < p->reqs_count; i++) {
4202  requirement_vector_append(&pgood->reqs, p->reqs[i]);
4203  }
4204  fc_assert(pgood->reqs.size == p->reqs_count);
4205 
4206  pgood->from_pct = p->from_pct;
4207  pgood->to_pct = p->to_pct;
4208  pgood->onetime_pct = p->onetime_pct;
4209  pgood->flags = p->flags;
4210 
4211  pgood->helptext = packet_strvec_extract(p->helptext);
4212 }
4213 
4217 void handle_ruleset_action(const struct packet_ruleset_action *p)
4218 {
4219  struct action *act;
4220 
4221  if (!action_id_exists(p->id)) {
4222  // Action id out of range
4223  qCritical("handle_ruleset_action() the action id %d is out of range.",
4224  p->id);
4225 
4226  return;
4227  }
4228 
4229  act = action_by_number(p->id);
4230 
4231  sz_strlcpy(act->ui_name, p->ui_name);
4232  act->quiet = p->quiet;
4233 
4234  act->result = p->result;
4235  act->actor_consuming_always = p->actor_consuming_always;
4236 
4237  act->actor_kind = p->act_kind;
4238  act->target_kind = p->tgt_kind;
4239  act->sub_target_kind = p->sub_tgt_kind;
4240 
4241  act->min_distance = p->min_distance;
4242  act->max_distance = p->max_distance;
4243  act->blocked_by = p->blocked_by;
4244 }
4245 
4250  const struct packet_ruleset_action_enabler *p)
4251 {
4252  struct action_enabler *enabler;
4253  int i;
4254 
4255  if (!action_id_exists(p->enabled_action)) {
4256  // Non existing action
4257  qCritical("handle_ruleset_action_enabler() the action %d "
4258  "doesn't exist.",
4259  p->enabled_action);
4260 
4261  return;
4262  }
4263 
4264  enabler = action_enabler_new();
4265 
4266  enabler->action = p->enabled_action;
4267 
4268  for (i = 0; i < p->actor_reqs_count; i++) {
4269  requirement_vector_append(&enabler->actor_reqs, p->actor_reqs[i]);
4270  }
4271  fc_assert(enabler->actor_reqs.size == p->actor_reqs_count);
4272 
4273  for (i = 0; i < p->target_reqs_count; i++) {
4274  requirement_vector_append(&enabler->target_reqs, p->target_reqs[i]);
4275  }
4276  fc_assert(enabler->target_reqs.size == p->target_reqs_count);
4277 
4278  action_enabler_add(enabler);
4279 }
4280 
4284 void handle_ruleset_action_auto(const struct packet_ruleset_action_auto *p)
4285 {
4286  struct action_auto_perf *auto_perf;
4287  int i;
4288 
4289  auto_perf = action_auto_perf_slot_number(p->id);
4290 
4291  auto_perf->cause = p->cause;
4292 
4293  for (i = 0; i < p->reqs_count; i++) {
4294  requirement_vector_append(&auto_perf->reqs, p->reqs[i]);
4295  }
4296  fc_assert(auto_perf->reqs.size == p->reqs_count);
4297 
4298  for (i = 0; i < p->alternatives_count; i++) {
4299  auto_perf->alternatives[i] = p->alternatives[i];
4300  }
4301 }
4302 
4306 void handle_ruleset_disaster(const struct packet_ruleset_disaster *p)
4307 {
4308  struct disaster_type *pdis = disaster_by_number(p->id);
4309  int i;
4310 
4311  fc_assert_ret_msg(nullptr != pdis, "Bad disaster %d.", p->id);
4312 
4313  names_set(&pdis->name, nullptr, p->name, p->rule_name);
4314 
4315  for (i = 0; i < p->reqs_count; i++) {
4316  requirement_vector_append(&pdis->reqs, p->reqs[i]);
4317  }
4318  fc_assert(pdis->reqs.size == p->reqs_count);
4319 
4320  pdis->frequency = p->frequency;
4321 
4322  pdis->effects = p->effects;
4323 }
4324 
4328 void handle_ruleset_achievement(const struct packet_ruleset_achievement *p)
4329 {
4330  struct achievement *pach = achievement_by_number(p->id);
4331 
4332  fc_assert_ret_msg(nullptr != pach, "Bad achievement %d.", p->id);
4333 
4334  names_set(&pach->name, nullptr, p->name, p->rule_name);
4335 
4336  pach->type = p->type;
4337  pach->unique = p->unique;
4338  pach->value = p->value;
4339 }
4340 
4344 void handle_ruleset_trade(const struct packet_ruleset_trade *p)
4345 {
4346  struct trade_route_settings *pset =
4347  trade_route_settings_by_type(static_cast<trade_route_type>(p->id));
4348 
4349  if (pset != nullptr) {
4350  pset->trade_pct = p->trade_pct;
4351  pset->cancelling = p->cancelling;
4352  pset->bonus_type = p->bonus_type;
4353  }
4354 }
4355 
4360  const struct packet_ruleset_terrain_control *p)
4361 {
4362  /* Since terrain_control is the same as packet_ruleset_terrain_control
4363  * we can just copy the data directly. */
4364  terrain_control = *p;
4365  // terrain_control.move_fragments likely changed
4367 }
4368 
4373  const struct packet_ruleset_nation_sets *packet)
4374 {
4375  int i;
4376 
4377  for (i = 0; i < packet->nsets; i++) {
4378  struct nation_set *pset;
4379 
4380  pset = nation_set_new(packet->names[i], packet->rule_names[i],
4381  packet->descriptions[i]);
4382  fc_assert(nullptr != pset);
4383  fc_assert(i == nation_set_index(pset));
4384  }
4385 }
4386 
4391  const struct packet_ruleset_nation_groups *packet)
4392 {
4393  int i;
4394 
4395  for (i = 0; i < packet->ngroups; i++) {
4396  struct nation_group *pgroup;
4397 
4398  pgroup = nation_group_new(packet->groups[i]);
4399  fc_assert_action(nullptr != pgroup, continue);
4400  fc_assert(i == nation_group_index(pgroup));
4401  pgroup->hidden = packet->hidden[i];
4402  }
4403 }
4404 
4408 void handle_ruleset_nation(const struct packet_ruleset_nation *packet)
4409 {
4410  struct nation_type *pnation = nation_by_number(packet->id);
4411  int i;
4412 
4413  fc_assert_ret_msg(nullptr != pnation, "Bad nation %d.", packet->id);
4414 
4415  if (packet->translation_domain[0] != '\0') {
4416  size_t len = qstrlen(packet->translation_domain) + 1;
4417  pnation->translation_domain = new char[len];
4418  fc_strlcpy(pnation->translation_domain, packet->translation_domain, len);
4419  } else {
4420  pnation->translation_domain = nullptr;
4421  }
4422  names_set(&pnation->adjective, pnation->translation_domain,
4423  packet->adjective, packet->rule_name);
4424  name_set(&pnation->noun_plural, pnation->translation_domain,
4425  packet->noun_plural);
4426  sz_strlcpy(pnation->flag_graphic_str, packet->graphic_str);
4427  sz_strlcpy(pnation->flag_graphic_alt, packet->graphic_alt);
4428  pnation->style = style_by_number(packet->style);
4429  for (i = 0; i < packet->leader_count; i++) {
4430  (void) nation_leader_new(pnation, packet->leader_name[i],
4431  packet->leader_is_male[i]);
4432  }
4433 
4434  // set later by PACKET_NATION_AVAILABILITY
4435  pnation->client.is_pickable = false;
4436  pnation->is_playable = packet->is_playable;
4437  pnation->barb_type = packet->barbarian_type;
4438 
4439  if ('\0' != packet->legend[0]) {
4440  pnation->legend =
4441  fc_strdup(nation_legend_translation(pnation, packet->legend));
4442  } else {
4443  pnation->legend = fc_strdup("");
4444  }
4445 
4446  for (i = 0; i < packet->nsets; i++) {
4447  struct nation_set *pset = nation_set_by_number(packet->sets[i]);
4448 
4449  if (nullptr != pset) {
4450  nation_set_list_append(pnation->sets, pset);
4451  } else {
4452  qCritical("handle_ruleset_nation() \"%s\" have unknown set %d.",
4453  nation_rule_name(pnation), packet->sets[i]);
4454  }
4455  }
4456 
4457  for (i = 0; i < packet->ngroups; i++) {
4458  struct nation_group *pgroup = nation_group_by_number(packet->groups[i]);
4459 
4460  if (nullptr != pgroup) {
4461  nation_group_list_append(pnation->groups, pgroup);
4462  } else {
4463  qCritical("handle_ruleset_nation() \"%s\" have unknown group %d.",
4464  nation_rule_name(pnation), packet->groups[i]);
4465  }
4466  }
4467 
4468  // init_government may be nullptr
4469  pnation->init_government =
4470  government_by_number(packet->init_government_id);
4471  for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
4472  if (i < packet->init_techs_count) {
4473  pnation->init_techs[i] = packet->init_techs[i];
4474  } else {
4475  pnation->init_techs[i] = A_LAST;
4476  }
4477  }
4478  for (i = 0; i < MAX_NUM_UNIT_LIST; i++) {
4479  if (i < packet->init_units_count) {
4480  pnation->init_units[i] = utype_by_number(packet->init_units[i]);
4481  } else {
4482  /* TODO: should init_units be initialized in common/nation.c? */
4483  pnation->init_units[i] = utype_by_number(U_LAST);
4484  }
4485  }
4486  for (i = 0; i < MAX_NUM_BUILDING_LIST; i++) {
4487  if (i < packet->init_buildings_count) {
4488  pnation->init_buildings[i] = packet->init_buildings[i];
4489  } else {
4490  pnation->init_buildings[i] = B_LAST;
4491  }
4492  }
4493 
4495 }
4496 
4501 void handle_nation_availability(int ncount, const bool *is_pickable,
4502  bool nationset_change)
4503 {
4504  int i;
4505 
4506  fc_assert_action(ncount == game.control.nation_count,
4507  ncount = MIN(ncount, game.control.nation_count));
4508 
4509  for (i = 0; i < ncount; i++) {
4510  nation_by_number(i)->client.is_pickable = is_pickable[i];
4511  }
4512 
4513  races_update_pickable(nationset_change);
4514 }
4515 
4519 void handle_ruleset_style(const struct packet_ruleset_style *p)
4520 {
4521  struct nation_style *pstyle = style_by_number(p->id);
4522 
4523  fc_assert_ret_msg(nullptr != pstyle, "Bad style %d.", p->id);
4524 
4525  names_set(&pstyle->name, nullptr, p->name, p->rule_name);
4526 }
4527 
4531 void handle_ruleset_clause(const struct packet_ruleset_clause *p)
4532 {
4533  struct clause_info *info = clause_info_get(p->type);
4534  int i;
4535 
4536  fc_assert_ret_msg(nullptr != info, "Bad clause %d.", p->type);
4537 
4538  info->enabled = p->enabled;
4539 
4540  for (i = 0; i < p->giver_reqs_count; i++) {
4541  requirement_vector_append(&info->giver_reqs, p->giver_reqs[i]);
4542  }
4543  fc_assert(info->giver_reqs.size == p->giver_reqs_count);
4544 
4545  for (i = 0; i < p->receiver_reqs_count; i++) {
4546  requirement_vector_append(&info->receiver_reqs, p->receiver_reqs[i]);
4547  }
4548  fc_assert(info->receiver_reqs.size == p->receiver_reqs_count);
4549 }
4550 
4554 void handle_ruleset_city(const struct packet_ruleset_city *packet)
4555 {
4556  int id, j;
4557  struct citystyle *cs;
4558 
4559  id = packet->style_id;
4560  fc_assert_ret_msg(0 <= id && game.control.styles_count > id,
4561  "Bad citystyle %d.", id);
4562  cs = &city_styles[id];
4563 
4564  for (j = 0; j < packet->reqs_count; j++) {
4565  requirement_vector_append(&cs->reqs, packet->reqs[j]);
4566  }
4567  fc_assert(cs->reqs.size == packet->reqs_count);
4568 
4569  names_set(&cs->name, nullptr, packet->name, packet->rule_name);
4570  sz_strlcpy(cs->graphic, packet->graphic);
4571  sz_strlcpy(cs->graphic_alt, packet->graphic_alt);
4572  sz_strlcpy(cs->citizens_graphic, packet->citizens_graphic);
4573  sz_strlcpy(cs->citizens_graphic_alt, packet->citizens_graphic_alt);
4574 
4576 }
4577 
4581 void handle_ruleset_music(const struct packet_ruleset_music *packet)
4582 {
4583  int id, j;
4584  struct music_style *pmus;
4585 
4586  id = packet->id;
4587  fc_assert_ret_msg(0 <= id && game.control.num_music_styles > id,
4588  "Bad music_style %d.", id);
4589 
4590  pmus = music_style_by_number(id);
4591 
4592  for (j = 0; j < packet->reqs_count; j++) {
4593  requirement_vector_append(&pmus->reqs, packet->reqs[j]);
4594  }
4595  fc_assert(pmus->reqs.size == packet->reqs_count);
4596 
4597  pmus->music_peaceful = packet->music_peaceful;
4598  pmus->music_combat = packet->music_combat;
4599 }
4600 
4604 void handle_ruleset_game(const struct packet_ruleset_game *packet)
4605 {
4606  int i;
4607 
4608  // Must set num_specialist_types before iterating over them.
4609  DEFAULT_SPECIALIST = packet->default_specialist;
4610 
4611  fc_assert_ret(packet->veteran_levels > 0);
4612 
4613  game.veteran = veteran_system_new(packet->veteran_levels);
4614  game.veteran->levels = packet->veteran_levels;
4615 
4616  for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
4617  if (i < packet->global_init_techs_count) {
4618  game.rgame.global_init_techs[i] = packet->global_init_techs[i];
4619  } else {
4621  }
4622  }
4623  for (i = 0; i < MAX_NUM_BUILDING_LIST; i++) {
4624  if (i < packet->global_init_buildings_count) {
4625  game.rgame.global_init_buildings[i] = packet->global_init_buildings[i];
4626  } else {
4628  }
4629  }
4630 
4631  for (i = 0; i < packet->veteran_levels; i++) {
4632  veteran_system_definition(game.veteran, i, packet->veteran_name[i],
4633  packet->power_fact[i], packet->move_bonus[i],
4634  packet->base_raise_chance[i],
4635  packet->work_raise_chance[i]);
4636  }
4637 
4638  fc_assert(game.plr_bg_color == nullptr);
4639  game.plr_bg_color =
4640  rgbcolor_new(packet->background_red, packet->background_green,
4641  packet->background_blue);
4642 }
4643 
4647 void handle_ruleset_specialist(const struct packet_ruleset_specialist *p)
4648 {
4649  int j;
4650  struct specialist *s = specialist_by_number(p->id);
4651 
4652  fc_assert_ret_msg(nullptr != s, "Bad specialist %d.", p->id);
4653 
4654  names_set(&s->name, nullptr, p->plural_name, p->rule_name);
4655  name_set(&s->abbreviation, nullptr, p->short_name);
4656 
4657  sz_strlcpy(s->graphic_str, p->graphic_str);
4658  sz_strlcpy(s->graphic_alt, p->graphic_alt);
4659 
4660  for (j = 0; j < p->reqs_count; j++) {
4661  requirement_vector_append(&s->reqs, p->reqs[j]);
4662  }
4663  fc_assert(s->reqs.size == p->reqs_count);
4664 
4665  s->helptext = packet_strvec_extract(p->helptext);
4666 
4668 }
4669 
4673 void handle_city_name_suggestion_info(int unit_id, const char *name)
4674 {
4675  struct unit *punit = player_unit_by_number(client_player(), unit_id);
4676 
4677  if (!can_client_issue_orders()) {
4678  return;
4679  }
4680 
4681  if (punit) {
4682  if (gui_options->ask_city_name) {
4683  bool other_asking = false;
4684 
4685  unit_list_iterate(unit_tile(punit)->units, other)
4686  {
4687  if (other->client.asking_city_name) {
4688  other_asking = true;
4689  }
4690  }
4692  punit->client.asking_city_name = true;
4693 
4694  if (!other_asking) {
4695  popup_newcity_dialog(punit, name);
4696  }
4697  } else {
4698  request_do_action(ACTION_FOUND_CITY, unit_id,
4699  tile_index(unit_tile(punit)), 0, name);
4700  }
4701  }
4702 }
4703 
4710 void handle_unit_action_answer(int actor_id, int target_id, int cost,
4711  action_id action_type, bool disturb_player)
4712 {
4713  struct city *pcity = game_city_by_number(target_id);
4714  struct unit *punit = game_unit_by_number(target_id);
4715  struct unit *pactor = player_unit_by_number(client_player(), actor_id);
4716  struct action *paction = action_by_number(action_type);
4717 
4718  if (ACTION_NONE != action_type && !action_id_exists(action_type)) {
4719  // Non existing action
4720  qCritical("handle_unit_action_answer() the action %d doesn't exist.",
4721  action_type);
4722 
4723  if (disturb_player) {
4725  action_decision_clear_want(actor_id);
4727  }
4728 
4729  return;
4730  }
4731 
4732  if (!pactor) {
4733  log_debug("Bad actor %d.", actor_id);
4734 
4735  if (disturb_player) {
4738  }
4739 
4740  return;
4741  }
4742 
4743  switch (static_cast<enum gen_action>(action_type)) {
4744  case ACTION_SPY_BRIBE_UNIT:
4745  if (punit && client.conn.playing && is_human(client.conn.playing)) {
4746  if (disturb_player) {
4747  // Focus on the unit so the player knows where it is
4748  unit_focus_set(pactor);
4749 
4750  popup_bribe_dialog(pactor, punit, cost, paction);
4751  } else {
4752  // Not in use (yet).
4753  qCritical("Unimplemented: received background unit bribe cost.");
4754  }
4755  } else {
4756  log_debug("Bad target %d.", target_id);
4757  if (disturb_player) {
4759  action_decision_clear_want(actor_id);
4761  }
4762  }
4763  break;
4764  case ACTION_SPY_INCITE_CITY:
4765  case ACTION_SPY_INCITE_CITY_ESC:
4766  if (pcity && client.conn.playing && is_human(client.conn.playing)) {
4767  if (disturb_player) {
4768  // Focus on the unit so the player knows where it is
4769  unit_focus_set(pactor);
4770 
4771  popup_incite_dialog(pactor, pcity, cost, paction);
4772  } else {
4773  // Not in use (yet).
4774  qCritical("Unimplemented: received background city incite cost.");
4775  }
4776  } else {
4777  log_debug("Bad target %d.", target_id);
4778  if (disturb_player) {
4780  action_decision_clear_want(actor_id);
4782  }
4783  }
4784  break;
4785  case ACTION_UPGRADE_UNIT:
4786  if (pcity && client.conn.playing && is_human(client.conn.playing)) {
4787  /* TODO: The bundled clients will have to start showing the upgrade
4788  * price sent from the server before it can be allowed to rely on
4789  * things the player can't see. (Example: it becomes legal to upgrade
4790  * a unit in a foreign city.) */
4791 
4792  /* Getting unit upgrade cost from the server is currently only used by
4793  * Freeciv-web. */
4794  qCritical("Received upgrade unit price but can't forward it.");
4795  }
4796  break;
4797  case ACTION_NONE:
4798  log_debug("Server didn't respond to query.");
4799  if (disturb_player) {
4801  action_decision_clear_want(actor_id);
4803  }
4804  break;
4805  default:
4806  qCritical("handle_unit_action_answer() invalid action_type (%d).",
4807  action_type);
4808  if (disturb_player) {
4810  action_decision_clear_want(actor_id);
4812  }
4813  break;
4814  };
4815 }
4816 
4821 static action_id auto_attack_act(const struct act_prob *act_probs)
4822 {
4823  action_id attack_action = ACTION_NONE;
4824 
4825  action_iterate(act)
4826  {
4827  if (action_prob_possible(act_probs[act])) {
4828  switch (static_cast<enum gen_action>(act)) {
4829  case ACTION_DISBAND_UNIT:
4830  case ACTION_FORTIFY:
4831  case ACTION_CONVERT:
4832  case ACTION_TRANSPORT_ALIGHT:
4833  case ACTION_TRANSPORT_BOARD:
4834  case ACTION_TRANSPORT_EMBARK:
4835  case ACTION_TRANSPORT_UNLOAD:
4836  case ACTION_TRANSPORT_DISEMBARK1:
4837  case ACTION_TRANSPORT_DISEMBARK2:
4838  // Not interesting.
4839  break;
4840  case ACTION_USER_ACTION1:
4841  case ACTION_USER_ACTION2:
4842  case ACTION_USER_ACTION3:
4843  // No idea. Assume not interesting.
4844  break;
4845  case ACTION_CAPTURE_UNITS:
4846  case ACTION_BOMBARD:
4847  case ACTION_BOMBARD2:
4848  case ACTION_BOMBARD3:
4849  case ACTION_NUKE:
4850  case ACTION_NUKE_CITY:
4851  case ACTION_NUKE_UNITS:
4852  case ACTION_ATTACK:
4853  case ACTION_SUICIDE_ATTACK:
4854  case ACTION_CONQUER_CITY:
4855  case ACTION_CONQUER_CITY2:
4856  case ACTION_STRIKE_PRODUCTION:
4857  // An attack.
4858  if (attack_action == ACTION_NONE) {
4859  // No previous attack action found.
4860  attack_action = act;
4861  } else {
4862  // More than one legal attack action found.
4863  return ACTION_NONE;
4864  }
4865  break;
4866  case ACTION_ESTABLISH_EMBASSY:
4867  case ACTION_ESTABLISH_EMBASSY_STAY:
4868  case ACTION_SPY_INVESTIGATE_CITY:
4869  case ACTION_INV_CITY_SPEND:
4870  case ACTION_SPY_POISON:
4871  case ACTION_SPY_POISON_ESC:
4872  case ACTION_SPY_STEAL_GOLD:
4873  case ACTION_SPY_STEAL_GOLD_ESC:
4874  case ACTION_SPY_SPREAD_PLAGUE:
4875  case ACTION_SPY_SABOTAGE_CITY:
4876  case ACTION_SPY_SABOTAGE_CITY_ESC:
4877  case ACTION_SPY_TARGETED_SABOTAGE_CITY:
4878  case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
4879  case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
4880  case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
4881  case ACTION_SPY_STEAL_TECH:
4882  case ACTION_SPY_STEAL_TECH_ESC:
4883  case ACTION_SPY_TARGETED_STEAL_TECH:
4884  case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
4885  case ACTION_SPY_INCITE_CITY:
4886  case ACTION_SPY_INCITE_CITY_ESC:
4887  case ACTION_TRADE_ROUTE:
4888  case ACTION_MARKETPLACE:
4889  case ACTION_HELP_WONDER:
4890  case ACTION_SPY_BRIBE_UNIT:
4891  case ACTION_SPY_SABOTAGE_UNIT:
4892  case ACTION_SPY_SABOTAGE_UNIT_ESC:
4893  case ACTION_SPY_ATTACK:
4894  case ACTION_FOUND_CITY:
4895  case ACTION_JOIN_CITY:
4896  case ACTION_STEAL_MAPS:
4897  case ACTION_STEAL_MAPS_ESC:
4898  case ACTION_SPY_NUKE:
4899  case ACTION_SPY_NUKE_ESC:
4900  case ACTION_DESTROY_CITY:
4901  case ACTION_EXPEL_UNIT:
4902  case ACTION_RECYCLE_UNIT:
4903  case ACTION_HOME_CITY:
4904  case ACTION_UPGRADE_UNIT:
4905  case ACTION_PARADROP:
4906  case ACTION_AIRLIFT:
4907  case ACTION_HEAL_UNIT:
4908  case ACTION_TRANSFORM_TERRAIN:
4909  case ACTION_CULTIVATE:
4910  case ACTION_PLANT:
4911  case ACTION_PILLAGE:
4912  case ACTION_CLEAN_POLLUTION:
4913  case ACTION_CLEAN_FALLOUT:
4914  case ACTION_ROAD:
4915  case ACTION_BASE:
4916  case ACTION_MINE:
4917  case ACTION_IRRIGATE:
4918  // An interesting non attack action has been found.
4919  return ACTION_NONE;
4920  break;
4921  case ACTION_STRIKE_BUILDING:
4922  // Needs a target to be specified.
4923  return ACTION_NONE;
4924  break;
4925  case ACTION_COUNT:
4926  fc_assert(act != ACTION_COUNT);
4927  break;
4928  }
4929  }
4930  }
4932 
4933  return attack_action;
4934 }
4935 
4942 void handle_unit_actions(const struct packet_unit_actions *packet)
4943 {
4944  struct unit *actor_unit = game_unit_by_number(packet->actor_unit_id);
4945 
4946  struct tile *target_tile =
4947  index_to_tile(&(wld.map), packet->target_tile_id);
4948  struct extra_type *target_extra =
4949  packet->target_extra_id == EXTRA_NONE
4950  ? nullptr
4951  : extra_by_number(packet->target_extra_id);
4952  struct city *target_city = game_city_by_number(packet->target_city_id);
4953  struct unit *target_unit = game_unit_by_number(packet->target_unit_id);
4954 
4955  const struct act_prob *act_probs = packet->action_probabilities;
4956 
4957  bool disturb_player = packet->disturb_player;
4958  bool valid = false;
4959 
4960  // The dead can't act
4961  if (actor_unit && (target_tile || target_city || target_unit)) {
4962  // At least one action must be possible
4963  action_iterate(act)
4964  {
4965  if (action_prob_possible(act_probs[act])) {
4966  valid = true;
4967  break;
4968  }
4969  }
4971  }
4972 
4973  if (valid && disturb_player) {
4974  // The player can select an action and should be informed.
4975 
4976  action_id auto_action;
4977 
4979  // Pop up the action selection dialog no matter what.
4980  auto_action = ACTION_NONE;
4981  } else {
4982  /* Pop up the action selection dialog unless the only interesting
4983  * action the unit may be able to do is an attack action. */
4984  auto_action = auto_attack_act(act_probs);
4985  }
4986 
4987  if (auto_action != ACTION_NONE) {
4988  /* No interesting actions except a single attack action has been
4989  * found. The player wants it performed without questions. */
4990 
4991  // The order requests below doesn't send additional details.
4992  fc_assert(!action_id_requires_details(auto_action));
4993 
4994  // Give the order.
4995  switch (action_id_get_target_kind(auto_action)) {
4996  case ATK_TILE:
4997  case ATK_UNITS:
4998  request_do_action(auto_action, packet->actor_unit_id,
4999  packet->target_tile_id, 0, "");
5000  break;
5001  case ATK_CITY:
5002  request_do_action(auto_action, packet->actor_unit_id,
5003  packet->target_city_id, 0, "");
5004  break;
5005  case ATK_UNIT:
5006  request_do_action(auto_action, packet->actor_unit_id,
5007  packet->target_unit_id, 0, "");
5008  break;
5009  case ATK_SELF:
5010  request_do_action(auto_action, packet->actor_unit_id,
5011  packet->actor_unit_id, 0, "");
5012  break;
5013  case ATK_COUNT:
5014  fc_assert(action_id_get_target_kind(auto_action) != ATK_COUNT);
5015  break;
5016  }
5017 
5018  // Clean up.
5019  action_selection_no_longer_in_progress(packet->actor_unit_id);
5020  action_decision_clear_want(packet->actor_unit_id);
5021  action_selection_next_in_focus(packet->actor_unit_id);
5022  } else {
5023  // Show the client specific action dialog
5024  popup_action_selection(actor_unit, target_city, target_unit,
5025  target_tile, target_extra, act_probs);
5026  }
5027  } else if (disturb_player) {
5028  // Nothing to do.
5029  action_selection_no_longer_in_progress(packet->actor_unit_id);
5030  action_decision_clear_want(packet->actor_unit_id);
5031  action_selection_next_in_focus(packet->actor_unit_id);
5032  } else {
5033  // This was a background request.
5034 
5035  if (actor_unit && action_selection_actor_unit() == actor_unit->id) {
5036  // The situation may have changed.
5037  action_selection_refresh(actor_unit, target_city, target_unit,
5038  target_tile, target_extra, act_probs);
5039  }
5040  }
5041 }
5042 
5046 void handle_city_sabotage_list(int actor_id, int city_id,
5047  bv_imprs improvements, action_id act_id,
5048  bool disturb_player)
5049 {
5050  struct city *pcity = game_city_by_number(city_id);
5051  struct unit *pactor = player_unit_by_number(client_player(), actor_id);
5052  struct action *paction = action_by_number(act_id);
5053 
5054  if (!pactor) {
5055  log_debug("Bad diplomat %d.", actor_id);
5056 
5057  if (disturb_player) {
5060  }
5061 
5062  return;
5063  }
5064 
5065  if (!pcity) {
5066  log_debug("Bad city %d.", city_id);
5067 
5068  if (disturb_player) {
5070  action_decision_clear_want(actor_id);
5072  }
5073 
5074  return;
5075  }
5076 
5077  if (can_client_issue_orders()) {
5078  improvement_iterate(pimprove)
5079  {
5081  pcity, pimprove,
5082  BV_ISSET(improvements, improvement_index(pimprove)));
5083  }
5085 
5086  if (disturb_player) {
5087  // Focus on the unit so the player knows where it is
5088  unit_focus_set(pactor);
5089 
5090  popup_sabotage_dialog(pactor, pcity, paction);
5091  } else {
5092  // Not in use (yet).
5093  qCritical("Unimplemented: received background city building list.");
5094  }
5095  } else {
5096  log_debug("Can't issue orders");
5097  if (disturb_player) {
5099  action_decision_clear_want(actor_id);
5100  }
5101  }
5102 }
5103 
5108 void handle_endgame_report(const struct packet_endgame_report *packet)
5109 {
5112 }
5113 
5117 void handle_endgame_player(const struct packet_endgame_player *packet)
5118 {
5119  if (client_has_player()
5120  && packet->player_id == player_number(client_player())) {
5121  if (packet->winner) {
5122  start_menu_music(QStringLiteral("music_victory"), nullptr);
5123  } else {
5124  start_menu_music(QStringLiteral("music_defeat"), nullptr);
5125  }
5126  }
5128 }
5129 
5134  const struct packet_player_attribute_chunk *packet)
5135 {
5136  if (!client_has_player()) {
5137  return;
5138  }
5139 
5141 
5142  if (packet->offset + packet->chunk_length == packet->total_length) {
5143  /* We successful received the last chunk. The attribute block is
5144  now complete. */
5146  }
5147 }
5148 
5153 {
5154  governor::i()->freeze();
5155 
5156  fc_assert(client.conn.client.request_id_of_currently_handled_packet == 0);
5157  client.conn.client.request_id_of_currently_handled_packet =
5158  get_next_request_id(client.conn.client.last_processed_request_id_seen);
5159 
5160  log_debug("start processing packet %d",
5161  client.conn.client.request_id_of_currently_handled_packet);
5162 }
5163 
5168 {
5169  log_debug("finish processing packet %d",
5170  client.conn.client.request_id_of_currently_handled_packet);
5171 
5172  fc_assert(client.conn.client.request_id_of_currently_handled_packet != 0);
5173 
5174  client.conn.client.last_processed_request_id_seen =
5175  client.conn.client.request_id_of_currently_handled_packet;
5177  client.conn.client.last_processed_request_id_seen);
5178 
5179  client.conn.client.request_id_of_currently_handled_packet = 0;
5180 
5181  governor::i()->unfreeze();
5182 }
5183 
5187 void notify_about_incoming_packet(struct connection *pc, int packet_type,
5188  int size)
5189 {
5190  fc_assert(pc == &client.conn);
5191  log_debug("incoming packet={type=%d, size=%d}", packet_type, size);
5192 }
5193 
5197 void notify_about_outgoing_packet(struct connection *pc, int packet_type,
5198  int size, int request_id)
5199 {
5200  fc_assert(pc == &client.conn);
5201  log_debug("outgoing packet={type=%d, size=%d, request_id=%d}", packet_type,
5202  size, request_id);
5203 
5204  fc_assert(request_id);
5205 }
5206 
5211 {
5212  log_debug("handle_freeze_client");
5213 
5214  governor::i()->freeze();
5215 }
5216 
5221 {
5222  log_debug("handle_thaw_client");
5223 
5224  governor::i()->unfreeze();
5226 }
5227 
5231 void handle_conn_ping() { send_packet_conn_pong(&client.conn); }
5232 
5236 void handle_server_shutdown() { qDebug("server shutdown"); }
5237 
5241 void handle_ruleset_effect(const struct packet_ruleset_effect *packet)
5242 {
5243  recv_ruleset_effect(packet);
5244 }
5245 
5252 void handle_edit_object_created(int tag, int id)
5253 {
5255 }
5256 
5260 void handle_edit_startpos(const struct packet_edit_startpos *packet)
5261 {
5262  struct tile *ptile = index_to_tile(&(wld.map), packet->id);
5263  bool changed = false;
5264 
5265  // Check.
5266  if (nullptr == ptile) {
5267  qCritical("%s(): invalid tile index %d.", __FUNCTION__, packet->id);
5268  return;
5269  }
5270 
5271  // Handle.
5272  if (packet->removal) {
5273  changed = map_startpos_remove(ptile);
5274  } else {
5275  if (nullptr != map_startpos_get(ptile)) {
5276  changed = false;
5277  } else {
5278  map_startpos_new(ptile);
5279  changed = true;
5280  }
5281  }
5282 
5283  // Notify.
5284  if (changed && can_client_change_view()) {
5285  refresh_tile_mapcanvas(ptile, true);
5286  if (packet->removal) {
5288  } else {
5289  editgui_notify_object_created(packet->tag, packet->id);
5290  }
5291  }
5292 }
5293 
5298  const struct packet_edit_startpos_full *packet)
5299 {
5300  struct tile *ptile = index_to_tile(&(wld.map), packet->id);
5301  struct startpos *psp;
5302 
5303  // Check.
5304  if (nullptr == ptile) {
5305  qCritical("%s(): invalid tile index %d.", __FUNCTION__, packet->id);
5306  return;
5307  }
5308 
5309  psp = map_startpos_get(ptile);
5310  if (nullptr == psp) {
5311  qCritical("%s(): no start position at (%d, %d)", __FUNCTION__,
5312  TILE_XY(ptile));
5313  return;
5314  }
5315 
5316  // Handle.
5317  if (startpos_unpack(psp, packet) && can_client_change_view()) {
5318  // Notify.
5319  refresh_tile_mapcanvas(ptile, true);
5321  false);
5322  }
5323 }
5324 
5328 void handle_vote_remove(int vote_no)
5329 {
5332 }
5333 
5337 void handle_vote_update(int vote_no, int yes, int no, int abstain,
5338  int num_voters)
5339 {
5340  struct voteinfo *vi;
5341 
5343  fc_assert_ret_msg(nullptr != vi,
5344  "Got packet_vote_update for non-existant vote %d!",
5345  vote_no);
5346 
5347  vi->yes = yes;
5348  vi->no = no;
5349  vi->abstain = abstain;
5350  vi->num_voters = num_voters;
5351 
5353 }
5354 
5358 void handle_vote_new(const struct packet_vote_new *packet)
5359 {
5360  fc_assert_ret_msg(nullptr == voteinfo_queue_find(packet->vote_no),
5361  "Got a packet_vote_new for already existing "
5362  "vote %d!",
5363  packet->vote_no);
5364 
5365  voteinfo_queue_add(packet->vote_no, packet->user, packet->desc,
5366  packet->percent_required, packet->flags);
5368 }
5369 
5374 {
5375  struct voteinfo *vi;
5376 
5378  fc_assert_ret_msg(nullptr != vi,
5379  "Got packet_vote_resolve for non-existant vote %d!",
5380  vote_no);
5381 
5382  vi->resolved = true;
5383  vi->passed = passed;
5384 
5386 }
5387 
5391 void handle_play_music(const char *tag) { play_single_track(tag); }
struct achievement * achievement_by_number(int id)
Return achievements of given id.
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_enabler * action_enabler_new()
Create a new action enabler.
Definition: actions.cpp:1810
void action_enabler_add(struct action_enabler *enabler)
Add an action enabler to the current ruleset.
Definition: actions.cpp:1854
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
bool action_id_exists(const action_id act_id)
Returns TRUE iff the specified action ID refers to a valid action.
Definition: actions.cpp:1138
void actions_rs_pre_san_gen()
Generate action related data based on the currently loaded ruleset.
Definition: actions.cpp:984
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Returns action auto performer rule slot number num so it can be filled.
Definition: actions.cpp:5832
#define action_id_requires_details(act_id)
Definition: actions.h:545
#define action_iterate_end
Definition: actions.h:383
#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
void attribute_restore()
Recreate the attribute set from the player's attribute_block.
Definition: attribute.cpp:305
void audio_play_sound(const QString &tag, const QString &alt_tag)
Play an audio sample as suggested by sound tags.
Definition: audio.cpp:494
void audio_restart(const QString &soundset_name, const QString &musicset_name)
Switch soundset.
Definition: audio.cpp:343
void base_type_init(struct extra_type *pextra, int idx)
Initialize base_type structures.
Definition: base.cpp:157
struct base_type * base_by_number(const Base_type_id id)
Returns base_type entry for an ID value.
Definition: base.cpp:119
#define BV_SET_VAL(bv, bit, val)
Definition: bitvector.h:54
#define BV_SET_ALL(bv)
Definition: bitvector.h:66
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
#define BV_ARE_EQUAL(vec1, vec2)
Definition: bitvector.h:80
#define BV_CLR(bv, bit)
Definition: bitvector.h:49
bool has_capability(const char *cap, const char *capstr)
Wrapper for fc_has_capability() for nullptr terminated strings.
Definition: capability.cpp:71
const char *const our_capability
Definition: capstr.cpp:28
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.
void output_window_printf(const struct ft_color color, const char *format,...)
Add a line of text to the output ("chatline") window.
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Set the number of citizens with the given nationality.
Definition: citizens.cpp:137
citizens citizens_count(const struct city *pcity)
Return the number of citizens in a city.
Definition: citizens.cpp:154
void citizens_init(struct city *pcity)
Initialise citizens data.
Definition: citizens.cpp:26
void city_map_radius_sq_set(struct city *pcity, int radius_sq)
Returns the current squared radius of the city.
Definition: city.cpp:141
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct citystyle * city_styles
Definition: city.cpp:78
void city_styles_alloc(int num)
Allocate memory for this amount of city styles.
Definition: city.cpp:3312
void city_remove_improvement(struct city *pcity, const struct impr_type *pimprove)
Removes an improvement (and its effects) from a city.
Definition: city.cpp:3287
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
void city_size_add(struct city *pcity, int add)
Add a (positive or negative) value to the city size.
Definition: city.cpp:1112
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
bool city_unhappy(const struct city *pcity)
Return TRUE iff the city is unhappy.
Definition: city.cpp:1544
bool city_happy(const struct city *pcity)
Return TRUE iff the city is happy.
Definition: city.cpp:1531
void city_size_set(struct city *pcity, citizens size)
Set the city size.
Definition: city.cpp:1126
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Adds an improvement (and its effects) to a city.
Definition: city.cpp:3272
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
Definition: city.cpp:130
void destroy_city_virtual(struct city *pcity)
Removes the virtual skeleton of a city.
Definition: city.cpp:3421
void free_city_map_index()
Free memory allocated by generate_citymap_index.
Definition: city.cpp:581
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Create virtual skeleton for a city.
Definition: city.cpp:3346
citizens city_size_get(const struct city *pcity)
Get the city size.
Definition: city.cpp:1101
void city_production_caravan_shields_init()
Initialize the cache of what city production can use shields from caravans.
Definition: city.cpp:1664
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
@ CITIZEN_LAST
Definition: city.h:244
@ CITIZEN_ANGRY
Definition: city.h:243
@ CITIZEN_HAPPY
Definition: city.h:240
@ CITIZEN_CONTENT
Definition: city.h:241
@ CITIZEN_UNHAPPY
Definition: city.h:242
#define output_type_iterate(output)
Definition: city.h:764
#define city_list_iterate_end
Definition: city.h:484
#define I_NEVER
Definition: city.h:219
@ FEELING_FINAL
Definition: city.h:256
@ FEELING_LAST
Definition: city.h:257
#define city_tile_iterate_skip_center_end
Definition: city.h:193
#define city_tile_iterate_skip_center(_radius_sq, _city_tile, _tile, _index, _x, _y)
Definition: city.h:183
#define output_type_iterate_end
Definition: city.h:771
bool city_dialog_is_open(struct city *pcity)
Return whether the dialog for the given city is open.
Definition: citydlg.cpp:2338
void refresh_unit_city_dialogs(struct unit *punit)
Update city dialogs when the given unit's status changes.
Definition: citydlg.cpp:2304
void popdown_city_dialog()
Closes the city overlay.
Definition: citydlg.cpp:2264
void generate_citydlg_dimensions()
Calculate the citydlg width and height.
void popup_city_dialog(struct city *pcity)
void refresh_city_dialog(struct city *pcity)
void city_report_dialog_update_city(struct city *pcity)
void city_report_dialog_update()
void add_city_remove(struct city *pcity)
Definition: governor.cpp:128
void add_city_changed(struct city *pcity)
Definition: governor.cpp:116
static governor * i()
Definition: governor.cpp:107
void add_city_new(struct city *pcity)
Definition: governor.cpp:122
void unfreeze()
Definition: governor.h:24
void freeze()
Definition: governor.h:23
void center_on_tile(tile *tile, bool animate=true)
Centers the view on a tile.
Definition: view_map.cpp:197
map_view * mapview_wdg
Definition: page_game.h:81
static update_queue * uq()
void processing_finished(int request_id)
enum client_states client_state()
Return current client state.
void start_turn_change_wait()
Start waiting of the server turn change activities.
void client_remove_cli_conn(struct connection *pconn)
Remove pconn from all connection lists in client, then free it.
bool client_has_player()
Either controlling or observing.
void set_miliseconds_to_turndone(int miliseconds)
Reset the number of seconds to turndone from an "authentic" source.
bool client_is_global_observer()
Returns whether client is global observer.
void set_server_busy(bool busy)
Sets if server is considered busy.
struct player * client_player()
Either controlling or observing.
struct civclient client
bool can_client_issue_orders()
Returns TRUE iff the client can issue orders (such as giving unit commands).
bool auto_connect
void user_ended_turn()
Handle user ending his/her turn.
bool client_is_observer()
Returns whether client is observer.
QString music_set_name
bool can_client_change_view()
Return TRUE if the client can change the view; i.e.
void stop_turn_change_wait()
Server is responsive again.
QString sound_set_name
void set_client_state(enum client_states newstate)
Change client state.
@ C_S_PREPARING
Definition: client_main.h:42
@ C_S_RUNNING
Definition: client_main.h:43
@ C_S_OVER
Definition: client_main.h:44
enum known_type client_tile_get_known(const struct tile *ptile)
A tile's "known" field is used by the server to store whether each player knows the tile.
Definition: climap.cpp:29
void client_player_maps_reset()
Reset the private maps of all players.
Definition: climisc.cpp:1104
void create_event(struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Creates a struct packet_generic_message packet and injects it via handle_chat_msg.
Definition: climisc.cpp:952
void client_player_init(struct player *pplayer)
Initialize a player on the client side.
Definition: climisc.cpp:1092
void client_remove_city(struct city *pcity)
Remove city, client end version.
Definition: climisc.cpp:134
void flush_dirty_overview()
This module contains various general - mostly highlevel - functions used throughout the client.
struct nation_set * client_current_nation_set()
Returns the nation set in use.
Definition: climisc.cpp:1190
void client_remove_unit(struct unit *punit)
Remove unit, client end version.
Definition: climisc.cpp:69
void unit_focus_set_status(struct player *pplayer)
Set focus status of all player units to FOCUS_AVAIL.
Definition: climisc.cpp:1080
void handle_event(const char *featured_text, struct tile *ptile, enum event_type event, int turn, int phase, int conn_id)
Handles a chat or event message.
Definition: climisc.cpp:827
void send_client_wants_hack(const char *filename)
If the client is capable of 'wanting hack', then the server will send the client a filename in the pa...
bool is_server_running()
The general chain of events:
int get_next_request_id(int old_request_id)
Get next request id.
Definition: connection.cpp:490
void conn_set_capability(struct connection *pconn, const char *capability)
Set the network capability string for 'pconn'.
Definition: connection.cpp:603
struct connection * conn_by_number(int id)
Find connection by id, from game.all_connections.
Definition: connection.cpp:376
#define conn_list_iterate(connlist, pconn)
Definition: connection.h:99
#define conn_list_iterate_end
Definition: connection.h:101
void do_move_unit(struct unit *punit, struct unit *target_unit)
Called to have the client move a unit from one location to another, updating the graphics if necessar...
Definition: control.cpp:2303
bool unit_is_in_focus(const struct unit *punit)
Return TRUE iff this unit is in focus.
Definition: control.cpp:364
std::vector< unit * > & get_units_in_focus()
Returns list of units currently in focus.
Definition: control.cpp:169
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 action_decision_request(struct unit *actor_unit)
Request that the player makes a decision for the specified unit.
Definition: control.cpp:976
void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
Adjusts way combatants are displayed suitable for combat.
Definition: control.cpp:905
void unit_focus_update()
If there is no unit currently in focus, or if the current unit in focus should not be in focus,...
Definition: control.cpp:718
void unit_focus_set(struct unit *punit)
Sets the focus unit directly.
Definition: control.cpp:479
bool should_ask_server_for_actions(const struct unit *punit)
Returns TRUE iff the client should ask the server about what actions a unit can perform.
Definition: control.cpp:318
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 unit_focus_urgent(struct unit *punit)
Store a priority focus unit.
Definition: control.cpp:193
void unit_change_battlegroup(struct unit *punit, int battlegroup)
Change the battlegroup for this unit.
Definition: control.cpp:237
int get_num_units_in_focus()
Return the number of units currently in focus (0 or more).
Definition: control.cpp:174
bool non_ai_unit_focus
Definition: control.cpp:118
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
struct unit * get_focus_unit_on_tile(const struct tile *ptile)
Return TRUE iff a unit on this tile is in focus.
Definition: control.cpp:373
void clear_hover_state()
Clear current hover state (go to HOVER_NONE).
Definition: control.cpp:308
void unit_register_battlegroup(struct unit *punit)
Call this on new units to enter them in the battlegroup lists.
Definition: control.cpp:257
void auto_center_on_focus_unit()
Center on the focus unit, if off-screen and auto_center_on_unit is true.
Definition: control.cpp:422
void request_new_unit_activity(struct unit *punit, enum unit_activity act)
Send request for unit activity changing to server.
Definition: control.cpp:1712
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
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
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
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
bool handmade_scenario_warning()
Give a warning when user is about to edit scenario with manually set properties.
Definition: dialogs.cpp:3818
void popup_musicset_suggestion_dialog(void)
Ruleset (modpack) has suggested loading certain musicset.
Definition: dialogs.cpp:3461
void action_selection_close(void)
Closes the action selection dialog.
Definition: dialogs.cpp:3740
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
void show_tech_gained_dialog(Tech_type_id tech)
Player has gained a new tech.
Definition: dialogs.cpp:3754
void popup_soundset_suggestion_dialog(void)
Ruleset (modpack) has suggested loading certain soundset.
Definition: dialogs.cpp:3436
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
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
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
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 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 popup_connect_msg(const char *headline, const char *message)
Popup a dialog to display connection message from server.
Definition: dialogs.cpp:956
void races_toggles_set_sensitive(void)
In the nation selection dialog, make already-taken nations unavailable.
Definition: dialogs.cpp:1061
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
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
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
void unit_select_dialog_update()
struct clause_info * clause_info_get(enum clause_type type)
Free memory associated with clause infos.
Definition: diptreaty.cpp:257
struct disaster_type * disaster_by_number(Disaster_type_id id)
Return disaster type of given id.
Definition: disaster.cpp:72
void editor_ruleset_changed()
Adjust editor for changed ruleset.
Definition: editor.cpp:171
bool editor_is_active()
Returns TRUE if the client is in edit mode.
Definition: editor.cpp:335
@ OBJTYPE_PLAYER
Definition: editor.h:22
@ OBJTYPE_UNIT
Definition: editor.h:20
@ OBJTYPE_STARTPOS
Definition: editor.h:19
@ OBJTYPE_GAME
Definition: editor.h:23
@ OBJTYPE_CITY
Definition: editor.h:21
@ OBJTYPE_TILE
Definition: editor.h:18
void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
Receives a new effect.
Definition: effects.cpp:447
struct @19::@20 reqs
void endgame_report_dialog_start(const struct packet_endgame_report *packet)
Show a dialog with player statistics at endgame.
void endgame_report_dialog_player(const struct packet_endgame_player *packet)
Received endgame report information about single player.
const char * get_event_tag(enum event_type event)
Returns a string for the sound to be used for this message type.
Definition: events.cpp:268
struct extra_type_list * extra_type_list_of_unit_hiders()
Returns extra types that hide units.
Definition: extras.cpp:234
void set_user_extra_flag_name(enum extra_flag_id id, const char *name, const char *helptxt)
Sets user defined name for extra flag.
Definition: extras.cpp:859
struct extra_type * extra_by_number(int id)
Return extras type of given id.
Definition: extras.cpp:154
struct player * extra_owner(const struct tile *ptile)
Who owns extras on tile.
Definition: extras.cpp:1013
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Check if extra has given flag.
Definition: extras.cpp:779
void extra_to_caused_by_list(struct extra_type *pextra, enum extra_cause cause)
Add extra type to list of extra caused by given cause.
Definition: extras.cpp:274
void extra_to_removed_by_list(struct extra_type *pextra, enum extra_rmcause rmcause)
Add extra type to list of extra removed by given cause.
Definition: extras.cpp:296
struct extra_type_list * extra_type_list_by_cause(enum extra_cause cause)
Returns extra type for given cause.
Definition: extras.cpp:224
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Is given cause one of the removal causes for the given extra?
Definition: extras.cpp:307
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_iterate_end
Definition: extras.h:285
#define is_extra_caused_by(e, c)
Definition: extras.h:182
#define extra_index(_e_)
Definition: extras.h:163
#define EXTRA_NONE
Definition: extras.h:72
#define EF_LAST_USER_FLAG
Definition: extras.h:69
void update_start_page(void)
Update the start page.
Definition: fc_client.cpp:597
#define MAX_DISASTER_TYPES
Definition: fc_types.h:46
#define MAX_BASE_TYPES
Definition: fc_types.h:43
#define MAX_GRANARY_INIS
Definition: fc_types.h:67
#define MAX_ROAD_TYPES
Definition: fc_types.h:44
#define MAX_NUM_BUILDING_LIST
Definition: fc_types.h:38
#define EC_NATURAL_DEFENSIVE
Definition: fc_types.h:937
#define EC_SPECIAL
Definition: fc_types.h:935
int action_id
Definition: fc_types.h:306
#define SP_MAX
Definition: fc_types.h:324
#define EC_NONE
Definition: fc_types.h:934
#define EC_DEFENSIVE
Definition: fc_types.h:936
#define MAX_NUM_UNIT_LIST
Definition: fc_types.h:37
#define MAX_EXTRA_TYPES
Definition: fc_types.h:42
#define MAX_ACHIEVEMENT_TYPES
Definition: fc_types.h:47
#define MAX_NUM_TECH_LIST
Definition: fc_types.h:36
@ O_SHIELD
Definition: fc_types.h:86
@ O_FOOD
Definition: fc_types.h:85
@ O_SCIENCE
Definition: fc_types.h:90
@ O_GOLD
Definition: fc_types.h:88
#define MAX_LEN_CITYNAME
Definition: fc_types.h:62
#define UCL_LAST
Definition: fc_types.h:332
#define IDENTITY_NUMBER_ZERO
Definition: fc_types.h:76
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_client
void game_ruleset_init()
Initialize the objects which will read from a ruleset.
Definition: game.cpp:489
void game_ruleset_free()
Frees all memory which in objects which are read from a ruleset.
Definition: game.cpp:534
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
bool is_player_phase(const struct player *pplayer, int phase)
Return TRUE if it is this player's phase.
Definition: game.cpp:672
struct world wld
Definition: game.cpp:48
int current_turn_timeout()
Return timeout value for the current turn.
Definition: game.cpp:808
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
void init_client_goto()
Called only by handle_map_info() in client/packhand.c.
Definition: goto.cpp:79
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
Definition: government.cpp:107
struct government * government_by_number(const Government_type_id gov)
Return the government with the given index.
Definition: government.cpp:96
void governments_alloc(int num)
Allocate the governments.
Definition: government.cpp:437
struct ruler_title * government_ruler_title_new(struct government *pgovern, const struct nation_type *pnation, const char *ruler_male_title, const char *ruler_female_title)
Add a new ruler title for the nation.
Definition: government.cpp:300
Government_type_id government_number(const struct government *pgovern)
Return the government index.
Definition: government.cpp:84
void editgui_notify_object_created(int tag, int id)
Stub for editor function.
Definition: gui_main.cpp:272
void editgui_notify_object_changed(int objtype, int object_id, bool removal)
Stub for editor function.
Definition: gui_main.cpp:265
void editgui_refresh()
Stub for editor function.
Definition: gui_main.cpp:250
void conn_list_dialog_update()
void boot_help_texts(const nation_set *nations_to_show, help_item *tileset_help)
pplayer may be nullptr.
Definition: helpdata.cpp:682
void popdown_help_dialog(void)
Close the help dialog.
Definition: helpdlg.cpp:75
void idex_register_unit(struct world *iworld, struct unit *punit)
Register a unit into idex, with current punit->id.
Definition: idex.cpp:79
void idex_unregister_city(struct world *iworld, struct city *pcity)
Remove a city from idex, with current pcity->id.
Definition: idex.cpp:97
void idex_register_city(struct world *iworld, struct city *pcity)
Register a city into idex, with current pcity->id.
Definition: idex.cpp:61
Impr_type_id improvement_count()
Return the number of improvements.
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
void improvement_feature_cache_init()
Cache features of the improvement.
Definition: improvement.cpp:77
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
bool is_improvement_visible(const struct impr_type *pimprove)
Return TRUE if the improvement should be visible to others without spying.
Impr_type_id improvement_index(const struct impr_type *pimprove)
Return the improvement index.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
#define B_LAST
Definition: improvement.h:33
const char * name
Definition: inputfile.cpp:118
#define fc_assert_msg(condition, message,...)
Definition: log.h:96
#define fc_assert_ret(condition)
Definition: log.h:112
#define log_packet
Definition: log.h:72
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_msg(condition, message,...)
Definition: log.h:129
constexpr auto LOG_NORMAL
Definition: log.h:25
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define fc_assert_action(condition, action)
Definition: log.h:104
#define log_debug(message,...)
Definition: log.h:65
int startpos_number(const struct startpos *psp)
Returns the unique ID number for this start position.
Definition: map.cpp:1375
void map_free(struct civ_map *fmap)
Frees the allocated memory of the map.
Definition: map.cpp:498
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Return squared distance between two tiles.
Definition: map.cpp:610
bool map_is_empty()
Returns TRUE if we are at a stage of the game where the map has not yet been generated/loaded.
Definition: map.cpp:124
struct startpos * map_startpos_get(const struct tile *ptile)
Returns the start position at the given tile, or nullptr if none exists there.
Definition: map.cpp:1548
bool map_startpos_remove(struct tile *ptile)
Remove the start position at the given tile.
Definition: map.cpp:1565
struct startpos * map_startpos_new(struct tile *ptile)
Create a new start position at the given tile and return it.
Definition: map.cpp:1531
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
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Fills the start position with the nation information in the packet.
Definition: map.cpp:1469
void map_init_topology()
map_init_topology needs to be called after map.topology_id is changed.
Definition: map.cpp:276
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
Definition: map.cpp:429
struct terrain_misc terrain_control
Definition: map.cpp:40
void main_map_allocate()
Allocate main map and related global structures.
Definition: map.cpp:487
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define whole_map_iterate_end
Definition: map.h:480
void update_turn_done_button_state()
Update the turn done button state.
struct city * city_workers_display
void upgrade_canvas_clipboard()
A newer technology may be available for units.
void popup_newcity_dialog(struct unit *punit, const char *suggestname)
Popup a dialog to ask for the name of a new city.
Definition: mapctrl.cpp:44
void update_info_label(void)
Typically an info box is provided to tell the player about the state of their civilization.
Definition: page_game.cpp:750
void update_unit_info_label(const std::vector< unit * > &unit_list)
Update the information label which gives info on the current unit and the tile under the current unit...
Definition: view_map.cpp:446
void menus_update()
void meswin_clear_older(int turn, int phase)
Clear all messages.
int utype_unknown_move_cost(const struct unit_type *utype)
This function calculates the movement cost to unknown tiles.
Definition: movement.cpp:93
void init_move_fragments()
Call whenever terrain_control.move_fragments / SINGLE_MOVE changes.
Definition: movement.cpp:777
struct multiplier * multiplier_by_number(Multiplier_type_id id)
Returns multiplier associated to given number.
Definition: multipliers.cpp:54
Multiplier_type_id multiplier_count()
Return number of loaded multipliers in the ruleset.
Definition: multipliers.cpp:85
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Returns multiplier index.
Definition: multipliers.cpp:77
#define multipliers_iterate(_mul_)
Definition: multipliers.h:45
#define multipliers_iterate_end
Definition: multipliers.h:51
void start_style_music()
Start music suitable for current game situation.
Definition: music.cpp:27
void start_menu_music(const QString &tag, const QString &alt_tag)
Start menu music.
Definition: music.cpp:78
void play_single_track(const QString &tag)
Play single track before continuing normal style music.
Definition: music.cpp:93
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
struct nation_set * nation_set_by_number(int id)
Return the nation set with the given index.
Definition: nation.cpp:640
struct nation_type * nation_by_number(const Nation_type_id nation)
Return the nation with the given index.
Definition: nation.cpp:450
struct nation_type * nation_of_city(const struct city *pcity)
Return the nation of the player who owns the city.
Definition: nation.cpp:429
int nation_group_index(const struct nation_group *pgroup)
Return the nation group index.
Definition: nation.cpp:814
struct nation_leader * nation_leader_new(struct nation_type *pnation, const char *name, bool is_male)
Create a new leader for the nation.
Definition: nation.cpp:215
int nation_set_index(const struct nation_set *pset)
Return the nation set index.
Definition: nation.cpp:582
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
struct nation_group * nation_group_new(const char *name)
Add new group into the array of groups.
Definition: nation.cpp:831
struct nation_type * nation_of_unit(const struct unit *punit)
Return the nation of the player who owns the unit.
Definition: nation.cpp:438
const char * nation_legend_translation(const struct nation_type *pnation, const char *legend)
Return translated version of nation legend.
Definition: nation.cpp:275
struct nation_group * nation_group_by_number(int id)
Return the nation group with the given index.
Definition: nation.cpp:870
struct nation_set * nation_set_new(const char *set_name, const char *set_rule_name, const char *set_description)
Add new set into the array of nation sets.
Definition: nation.cpp:599
void nations_alloc(int num)
Allocate space for the given number of nations.
Definition: nation.cpp:520
client_options * gui_options
Definition: options.cpp:74
const char * tileset_name_for_topology(int topology_id)
Option framework wrapper for mapimg_get_format_list()
Definition: options.cpp:4864
void calculate_overview_dimensions()
Called if the map size is know or changes.
QVector< QString > * packet_strvec_extract(const char *str)
Definition: packets.cpp:819
void generic_handle_player_attribute_chunk(struct player *pplayer, const struct packet_player_attribute_chunk *chunk)
Updates pplayer->attribute_block according to the given packet.
Definition: packets.cpp:639
@ UNIT_INFO_CITY_PRESENT
Definition: packets.h:63
@ UNIT_INFO_CITY_SUPPORTED
Definition: packets.h:62
void handle_ruleset_game(const struct packet_ruleset_game *packet)
Packet ruleset_game handler.
Definition: packhand.cpp:4604
void handle_player_diplstate(const struct packet_player_diplstate *packet)
Packet player_diplstate handler.
Definition: packhand.cpp:2647
void handle_conn_ping()
Reply to 'ping' packet with 'pong'.
Definition: packhand.cpp:5231
static action_id auto_attack_act(const struct act_prob *act_probs)
Returns a possibly legal attack action iff it is the only interesting action that currently is legal.
Definition: packhand.cpp:4821
void handle_ruleset_nation_sets(const struct packet_ruleset_nation_sets *packet)
Handle the list of nation sets, sent as part of the ruleset.
Definition: packhand.cpp:4372
void handle_ruleset_nation(const struct packet_ruleset_nation *packet)
Handle initial ruleset nation info.
Definition: packhand.cpp:4408
void handle_city_name_suggestion_info(int unit_id, const char *name)
Handle reply to our city name request.
Definition: packhand.cpp:4673
void handle_nuke_tile_info(int tile)
The tile (x,y) has been nuked!
Definition: packhand.cpp:468
void handle_city_sabotage_list(int actor_id, int city_id, bv_imprs improvements, action_id act_id, bool disturb_player)
Handle list of potenttial buildings to sabotage.
Definition: packhand.cpp:5046
void handle_processing_finished()
Handle request to stop processing packet.
Definition: packhand.cpp:5167
void handle_ruleset_government_ruler_title(const struct packet_ruleset_government_ruler_title *packet)
Packet ruleset_government_ruler_title handler.
Definition: packhand.cpp:3851
void handle_city_info(const struct packet_city_info *packet)
A city-info packet contains all information about a city.
Definition: packhand.cpp:639
char * caption
Definition: packhand.cpp:129
enum event_type event
Definition: packhand.cpp:128
void handle_conn_info(const struct packet_conn_info *pinfo)
Remove, add, or update dummy connection struct representing some connection to the server,...
Definition: packhand.cpp:2748
void handle_vote_remove(int vote_no)
A vote no longer exists.
Definition: packhand.cpp:5328
void handle_page_msg_part(const char *lines)
Page_msg part handler.
Definition: packhand.cpp:1580
void handle_unit_combat_info(const struct packet_unit_combat_info *packet)
A combat packet.
Definition: packhand.cpp:491
void handle_ruleset_style(const struct packet_ruleset_style *p)
Handle a packet about a particular style.
Definition: packhand.cpp:4519
void handle_unit_remove(int unit_id)
Handle a remove-unit packet, sent by the server to tell us any time a unit is no longer there.
Definition: packhand.cpp:416
void handle_vote_update(int vote_no, int yes, int no, int abstain, int num_voters)
Find and update the corresponding vote and refresh the GUI.
Definition: packhand.cpp:5337
static int last_turn
Definition: packhand.cpp:137
void handle_freeze_client()
We have received PACKET_FREEZE_CLIENT.
Definition: packhand.cpp:5210
void handle_ruleset_multiplier(const struct packet_ruleset_multiplier *p)
Packet ruleset_multiplier handler.
Definition: packhand.cpp:3798
void handle_player_info(const struct packet_player_info *pinfo)
Handle information about a player.
Definition: packhand.cpp:2323
void handle_ruleset_extra(const struct packet_ruleset_extra *p)
Handle a packet about a particular extra type.
Definition: packhand.cpp:3982
void handle_ruleset_action_auto(const struct packet_ruleset_action_auto *p)
Handle a packet about a particular action auto performer rule.
Definition: packhand.cpp:4284
void handle_ruleset_unit_bonus(const struct packet_ruleset_unit_bonus *p)
Packet ruleset_unit_bonus handler.
Definition: packhand.cpp:3528
void handle_start_phase(int phase)
Called by the network code when an start-phase packet is received.
Definition: packhand.cpp:1388
void handle_timeout_info(float seconds_to_phasedone, float last_turn_change_time)
Sets the remaining turn time.
Definition: packhand.cpp:2234
void handle_ruleset_terrain_control(const struct packet_ruleset_terrain_control *p)
Handle the terrain control ruleset packet sent by the server.
Definition: packhand.cpp:4359
static struct unit * unpackage_short_unit(const struct packet_unit_short_info *packet)
Unpackage a short_unit_info packet.
Definition: packhand.cpp:294
void handle_end_phase()
Called by the network code when an end-phase packet is received.
Definition: packhand.cpp:1377
void handle_play_music(const char *tag)
Play suitable music.
Definition: packhand.cpp:5391
void handle_processing_started()
Handle request to start processing packet.
Definition: packhand.cpp:5152
void handle_edit_object_created(int tag, int id)
Handle a notification from the server that an object was successfully created.
Definition: packhand.cpp:5252
static void packhand_init()
Called only by handle_map_info() below.
Definition: packhand.cpp:165
int parts
Definition: packhand.cpp:132
static struct @141 invisible
void handle_ruleset_tech_class(const struct packet_ruleset_tech_class *p)
Packet ruleset_tech_class handler.
Definition: packhand.cpp:3706
void handle_ruleset_control(const struct packet_ruleset_control *packet)
Take arrival of ruleset control packet to indicate that current allocated governments should be free'...
Definition: packhand.cpp:3252
void handle_server_info(const char *version_label, int major_version, int minor_version, int patch_version, int emerg_version)
Handle server info packet.
Definition: packhand.cpp:1534
void handle_ruleset_nation_groups(const struct packet_ruleset_nation_groups *packet)
Handle the list of nation groups, sent as part of the ruleset.
Definition: packhand.cpp:4390
void handle_traderoute_info(const struct packet_traderoute_info *packet)
A traderoute-info packet contains information about one end of a traderoute.
Definition: packhand.cpp:1096
void handle_ruleset_effect(const struct packet_ruleset_effect *packet)
Add effect data to ruleset cache.
Definition: packhand.cpp:5241
void handle_new_year(int year, int fragments, int turn)
Handle turn and year advancement.
Definition: packhand.cpp:1330
void handle_rulesets_ready()
Received packet indicating that all rulesets have now been received.
Definition: packhand.cpp:3370
char * headline
Definition: packhand.cpp:130
void handle_research_info(const struct packet_research_info *packet)
Receive a research info packet.
Definition: packhand.cpp:2559
void handle_ruleset_goods(const struct packet_ruleset_goods *p)
Handle a packet about a particular goods type.
Definition: packhand.cpp:4192
void handle_unit_info(const struct packet_unit_info *packet)
Packet unit_info.
Definition: packhand.cpp:1605
void handle_ruleset_city(const struct packet_ruleset_city *packet)
Handle city style packet.
Definition: packhand.cpp:4554
void handle_ruleset_unit_class(const struct packet_ruleset_unit_class *p)
Packet ruleset_unit_class handler.
Definition: packhand.cpp:3438
void handle_server_shutdown()
Handle server shutdown.
Definition: packhand.cpp:5236
void handle_ruleset_government(const struct packet_ruleset_government *p)
Packet ruleset_government handler.
Definition: packhand.cpp:3825
void handle_ruleset_terrain_flag(const struct packet_ruleset_terrain_flag *p)
Packet ruleset_terrain_flag handler.
Definition: packhand.cpp:3937
void handle_connect_msg(const char *message)
Handle a connect message packet.
Definition: packhand.cpp:1525
void packhand_free()
Called below, and by client/client_main.c client_game_free()
Definition: packhand.cpp:142
void handle_tile_info(const struct packet_tile_info *packet)
Packet tile_info handler.
Definition: packhand.cpp:2967
void handle_ruleset_action(const struct packet_ruleset_action *p)
Handle a packet about a particular action.
Definition: packhand.cpp:4217
void handle_achievement_info(int id, bool gained, bool first)
Received package about gaining an achievement.
Definition: packhand.cpp:2866
void handle_unit_bombard_info(int attacker_unit_id, int target_tile_id)
A bombardment packet.
Definition: packhand.cpp:547
void handle_scenario_description(const char *description)
Received packet containing description of current scenario.
Definition: packhand.cpp:3240
void play_sound_for_event(enum event_type type)
Plays sound associated with event.
Definition: packhand.cpp:1486
static struct @142 page_msg_report
void handle_edit_startpos(const struct packet_edit_startpos *packet)
Handle start position creation/removal.
Definition: packhand.cpp:5260
static int unpack_tech_req(const enum tech_req r_num, const int reqs_size, const struct requirement *reqs, struct advance *a, int i)
Unpack a traditional tech req from a standard requirement vector (that still is in the network serial...
Definition: packhand.cpp:3609
void handle_city_short_info(const struct packet_city_short_info *packet)
A city-short-info packet is sent to tell us about any cities we can't see the internals of.
Definition: packhand.cpp:1131
void handle_endgame_player(const struct packet_endgame_player *packet)
Pass endgame report about single player.
Definition: packhand.cpp:5117
void handle_ruleset_resource(const struct packet_ruleset_resource *p)
Handle a packet about a particular terrain resource.
Definition: packhand.cpp:3964
void handle_ruleset_tech(const struct packet_ruleset_tech *p)
Packet ruleset_tech handler.
Definition: packhand.cpp:3636
void handle_team_name_info(int team_id, const char *team_name)
The name of team 'team_id'.
Definition: packhand.cpp:476
void handle_calendar_info(const struct packet_calendar_info *pcalendar)
Packet calendar_info handler.
Definition: packhand.cpp:2226
void set_government_choice(struct government *government)
Sets the target government.
Definition: packhand.cpp:2252
void handle_ruleset_disaster(const struct packet_ruleset_disaster *p)
Handle a packet about a particular disaster type.
Definition: packhand.cpp:4306
static bool handle_unit_packet_common(struct unit *packet_unit)
Called to do basic handling for a unit_info or short_unit_info packet.
Definition: packhand.cpp:1632
void handle_ruleset_unit_class_flag(const struct packet_ruleset_unit_class_flag *p)
Packet ruleset_unit_class_flag handler.
Definition: packhand.cpp:3576
void handle_server_join_reply(bool you_can_join, const char *message, const char *capability, const char *challenge_file, int conn_id)
After we send a join packet to the server we receive a reply.
Definition: packhand.cpp:332
void handle_ruleset_summary(const struct packet_ruleset_summary *packet)
Ruleset summary.
Definition: packhand.cpp:3346
void handle_page_msg(const char *caption, const char *headline, enum event_type event, int len, int parts)
Page_msg header handler.
Definition: packhand.cpp:1550
void handle_edit_startpos_full(const struct packet_edit_startpos_full *packet)
Handle start position internal information.
Definition: packhand.cpp:5297
void handle_conn_ping_info(int connections, const int *conn_id, const float *ping_time)
Handles a conn_ping_info packet from the server.
Definition: packhand.cpp:2855
static bool spaceship_autoplace(struct player *pplayer, struct player_spaceship *ship)
Ideally the client should let the player choose which type of modules and components to build,...
Definition: packhand.cpp:2903
void handle_player_remove(int playerno)
Handle a notification that the player slot identified by 'playerno' has become unused.
Definition: packhand.cpp:2276
void handle_end_turn()
Called when end-turn packet is received.
Definition: packhand.cpp:1463
void handle_endgame_report(const struct packet_endgame_report *packet)
Pass the header information about things be displayed in a gui-specific endgame dialog.
Definition: packhand.cpp:5108
void handle_early_chat_msg(const struct packet_early_chat_msg *packet)
Handle an early message packet.
Definition: packhand.cpp:1515
void handle_ruleset_clause(const struct packet_ruleset_clause *p)
Handle a packet about a particular clause.
Definition: packhand.cpp:4531
void handle_ruleset_road(const struct packet_ruleset_road *p)
Handle a packet about a particular road type.
Definition: packhand.cpp:4161
void handle_unit_actions(const struct packet_unit_actions *packet)
Handle reply to possible actions.
Definition: packhand.cpp:4942
void handle_ruleset_music(const struct packet_ruleset_music *packet)
Handle music style packet.
Definition: packhand.cpp:4581
void handle_ruleset_base(const struct packet_ruleset_base *p)
Handle a packet about a particular base type.
Definition: packhand.cpp:4143
void notify_about_incoming_packet(struct connection *pc, int packet_type, int size)
Notify interested parties about incoming packet.
Definition: packhand.cpp:5187
void handle_city_remove(int city_id)
Handles a remove-city packet, used by the server to tell us any time a city is no longer there.
Definition: packhand.cpp:393
void handle_chat_msg(const struct packet_chat_msg *packet)
Handle a message packet.
Definition: packhand.cpp:1499
static void city_packet_common(struct city *pcity, struct tile *pcenter, struct player *powner, struct tile_list *worked_tiles, bool is_new, bool popup, bool investigate)
A helper function for handling city-info and city-short-info packets.
Definition: packhand.cpp:993
void handle_player_attribute_chunk(const struct packet_player_attribute_chunk *packet)
Packet player_attribute_chunk handler.
Definition: packhand.cpp:5133
void handle_vote_new(const struct packet_vote_new *packet)
Create a new vote and add it to the queue.
Definition: packhand.cpp:5358
void handle_set_topology(int topology_id)
Server requested topology change.
Definition: packhand.cpp:2096
void handle_scenario_info(const struct packet_scenario_info *packet)
Received packet containing info about current scenario.
Definition: packhand.cpp:3219
static struct unit * unpackage_unit(const struct packet_unit_info *packet)
Unpackage the unit information into a newly allocated unit structure.
Definition: packhand.cpp:189
void handle_ruleset_extra_flag(const struct packet_ruleset_extra_flag *p)
Packet ruleset_extra_flag handler.
Definition: packhand.cpp:4116
char * lines
Definition: packhand.cpp:131
void notify_about_outgoing_packet(struct connection *pc, int packet_type, int size, int request_id)
Notify interested parties about outgoing packet.
Definition: packhand.cpp:5197
#define VALIDATE(_count, _maximum, _string)
struct city_list * cities
Definition: packhand.cpp:122
void handle_ruleset_tech_flag(const struct packet_ruleset_tech_flag *p)
Packet ruleset_tech_flag handler.
Definition: packhand.cpp:3719
void handle_nation_availability(int ncount, const bool *is_pickable, bool nationset_change)
Handle nation availability info.
Definition: packhand.cpp:4501
void handle_spaceship_info(const struct packet_spaceship_info *p)
Packet spaceship_info handler.
Definition: packhand.cpp:2922
void handle_begin_turn()
Called when begin-turn packet is received.
Definition: packhand.cpp:1449
void handle_ruleset_specialist(const struct packet_ruleset_specialist *p)
Handle info about a single specialist.
Definition: packhand.cpp:4647
void handle_unit_short_info(const struct packet_unit_short_info *packet)
Receive a short_unit info packet.
Definition: packhand.cpp:2033
void handle_ruleset_unit_flag(const struct packet_ruleset_unit_flag *p)
Packet ruleset_unit_flag handler.
Definition: packhand.cpp:3548
void handle_thaw_client()
We have received PACKET_THAW_CLIENT.
Definition: packhand.cpp:5220
QString forced_tileset_name
void handle_ruleset_building(const struct packet_ruleset_building *p)
Packet ruleset_building handler.
Definition: packhand.cpp:3746
void handle_map_info(int xsize, int ysize, int topology_id)
Receive information about the map size and topology from the server.
Definition: packhand.cpp:2119
static bool update_improvement_from_packet(struct city *pcity, struct impr_type *pimprove, bool have_impr)
Updates a city's list of improvements from packet data.
Definition: packhand.cpp:617
void handle_ruleset_unit(const struct packet_ruleset_unit *p)
Packet ruleset_unit handler.
Definition: packhand.cpp:3457
void handle_ruleset_terrain(const struct packet_ruleset_terrain *p)
Packet ruleset_terrain handler.
Definition: packhand.cpp:3866
void handle_unit_action_answer(int actor_id, int target_id, int cost, action_id action_type, bool disturb_player)
Handle the requested follow up question about an action.
Definition: packhand.cpp:4710
void handle_ruleset_action_enabler(const struct packet_ruleset_action_enabler *p)
Handle a packet about a particular action enabler.
Definition: packhand.cpp:4249
void handle_ruleset_achievement(const struct packet_ruleset_achievement *p)
Handle a packet about a particular achievement type.
Definition: packhand.cpp:4328
void handle_game_info(const struct packet_game_info *pinfo)
Packet game_info handler.
Definition: packhand.cpp:2153
struct player * placeholder
Definition: packhand.cpp:123
void handle_vote_resolve(int vote_no, bool passed)
Update the vote's status and refresh the GUI.
Definition: packhand.cpp:5373
void start_revolution()
Begin a revolution by telling the server to start it.
Definition: packhand.cpp:2265
void handle_worker_task(const struct packet_worker_task *packet)
Handle worker task assigned to the city.
Definition: packhand.cpp:1278
void handle_ruleset_description_part(const struct packet_ruleset_description_part *packet)
Next part of ruleset description.
Definition: packhand.cpp:3360
void handle_ruleset_trade(const struct packet_ruleset_trade *p)
Handle a packet about a particular trade route type.
Definition: packhand.cpp:4344
int len
Definition: packhand.cpp:127
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
void set_client_page(enum client_pages page)
enum client_pages get_client_page()
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
Definition: player.cpp:1139
struct player_slot * player_slot_by_number(int player_id)
Return the possibly unused and uninitialized player slot.
Definition: player.cpp:410
bool player_slot_is_used(const struct player_slot *pslot)
Returns TRUE is this slot is "used" i.e.
Definition: player.cpp:395
struct player * player_by_number(const int player_id)
Return struct player pointer for the given player index.
Definition: player.cpp:768
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
int player_count()
Return the number of players.
Definition: player.cpp:739
void player_set_color(struct player *pplayer, const struct rgbcolor *prgbcolor)
Set the player's color.
Definition: player.cpp:598
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
struct player * player_slot_get_player(const struct player_slot *pslot)
Returns the team corresponding to the slot.
Definition: player.cpp:384
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Set the player's nation to the given nation (may be nullptr).
Definition: player.cpp:780
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Return TRUE iff the player can see units in the city.
Definition: player.cpp:1045
bool can_player_see_city_internals(const struct player *pplayer, const struct city *pcity)
Return TRUE iff the player can see the city's internals.
Definition: player.cpp:1060
struct player * player_new(struct player_slot *pslot)
Creates a new player for the slot.
Definition: player.cpp:442
void player_destroy(struct player *pplayer)
Destroys and remove a player from the game.
Definition: player.cpp:684
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
#define ANON_USER_NAME
Definition: player.h:31
#define is_ai(plr)
Definition: player.h:227
#define ANON_PLAYER_NAME
Definition: player.h:26
#define is_human(plr)
Definition: player.h:226
void start_turn()
New turn callback.
Definition: view_map.cpp:712
#define fc_rand(_size)
Definition: rand.h:16
void multipliers_dialog_update()
void science_report_dialog_popup(bool raise)
Display the science report.
void science_report_dialog_update()
void economy_report_dialog_update()
void units_report_dialog_update()
void science_report_dialog_redraw(void)
Resize and redraw the requirement tree.
struct universal universal_by_number(const enum universals_n kind, const int value)
Combine values into a universal structure.
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
Return TRUE iff the two sources are equivalent.
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Set research knowledge about tech to given state.
Definition: research.cpp:627
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
struct research * research_by_number(int number)
Returns the research for the given index.
Definition: research.cpp:100
void research_update(struct research *presearch)
Mark as TECH_PREREQS_KNOWN each tech which is available, not known and which has all requirements ful...
Definition: research.cpp:486
#define research_players_iterate(_presearch, _pplayer)
Definition: research.h:151
#define research_players_iterate_end
Definition: research.h:155
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Free rgbcolor structure.
Definition: rgbcolor.cpp:65
struct rgbcolor * rgbcolor_new(int r, int g, int b)
Allocate new rgbcolor structure.
Definition: rgbcolor.cpp:25
void road_integrators_cache_init()
Initialize the road integrators cache.
Definition: road.cpp:97
void road_type_init(struct extra_type *pextra, int idx)
Initialize road_type structures.
Definition: road.cpp:81
struct road_type * road_by_number(Road_type_id id)
Return road type of given id.
Definition: road.cpp:46
void script_client_signal_emit(const char *signal_name,...)
Invoke all the callback functions attached to a given signal.
static struct connection connections[MAX_NUM_CONNECTIONS]
Definition: sernet.cpp:57
#define ARRAY_SIZE(x)
Definition: shared.h:79
#define MIN(x, y)
Definition: shared.h:49
#define MAX(x, y)
Definition: shared.h:48
bool next_spaceship_component(struct player *pplayer, struct player_spaceship *ship, struct spaceship_component *fill)
Find (default) place for next spaceship component.
Definition: spaceship.cpp:79
spaceship_state
Definition: spaceship.h:77
void refresh_spaceship_dialog(struct player *pplayer)
Refresh (update) the spaceship dialog for the given player.
struct specialist * specialist_by_number(const Specialist_type_id id)
Return the specialist pointer for the given number.
Definition: specialist.cpp:92
#define specialist_type_iterate_end
Definition: specialist.h:73
#define specialist_type_iterate(sp)
Definition: specialist.h:67
#define DEFAULT_SPECIALIST
Definition: specialist.h:37
size_t size
Definition: specvec.h:64
enum achievement_type type
Definition: achievements.h:24
struct player * first
Definition: achievements.h:28
bv_player achievers
Definition: achievements.h:29
struct name_translation name
Definition: achievements.h:22
struct requirement_vector reqs
Definition: actions.h:461
enum action_auto_perf_cause cause
Definition: actions.h:457
action_id alternatives[MAX_NUM_ACTIONS]
Definition: actions.h:465
action_id action
Definition: actions.h:364
struct requirement_vector actor_reqs
Definition: actions.h:365
struct requirement_vector target_reqs
Definition: actions.h:366
bool actor_consuming_always
Definition: actions.h:337
int max_distance
Definition: actions.h:320
bool quiet
Definition: actions.h:327
enum action_sub_target_kind sub_target_kind
Definition: actions.h:312
enum action_result result
Definition: actions.h:308
char ui_name[MAX_LEN_NAME]
Definition: actions.h:323
enum action_actor_kind actor_kind
Definition: actions.h:310
bv_actions blocked_by
Definition: actions.h:331
enum action_target_kind target_kind
Definition: actions.h:311
int min_distance
Definition: actions.h:320
Definition: tech.h:113
struct requirement_vector research_reqs
Definition: tech.h:125
struct tech_class * tclass
Definition: tech.h:118
double cost
Definition: tech.h:138
struct advance * require[AR_SIZE]
Definition: tech.h:120
struct name_translation name
Definition: tech.h:115
bv_tech_flags flags
Definition: tech.h:127
int num_reqs
Definition: tech.h:144
char graphic_str[MAX_LEN_NAME]
Definition: tech.h:116
char graphic_alt[MAX_LEN_NAME]
Definition: tech.h:117
QVector< QString > * helptext
Definition: tech.h:128
Definition: base.h:43
int border_sq
Definition: base.h:46
int vision_main_sq
Definition: base.h:47
enum base_gui_type gui_type
Definition: base.h:45
bv_base_flags flags
Definition: base.h:51
int vision_invis_sq
Definition: base.h:48
int vision_subs_sq
Definition: base.h:49
int turn
Definition: city.h:218
Definition: city.h:291
struct worker_task_list * task_reqs
Definition: city.h:381
struct city::@15::@18 client
int turn_last_built
Definition: city.h:358
int surplus[O_LAST]
Definition: city.h:324
int food_stock
Definition: city.h:338
struct built_status built[B_LAST]
Definition: city.h:366
struct player * original
Definition: city.h:295
int history
Definition: city.h:379
int pollution
Definition: city.h:340
bool did_sell
Definition: city.h:352
int id
Definition: city.h:296
int last_turns_shield_surplus
Definition: city.h:364
enum capital_type capital
Definition: city.h:298
int disbanded_shields
Definition: city.h:363
int waste[O_LAST]
Definition: city.h:325
bv_city_options city_options
Definition: city.h:375
int city_radius_sq
Definition: city.h:346
bool was_happy
Definition: city.h:353
struct player * owner
Definition: city.h:294
int turn_founded
Definition: city.h:357
int airlift
Definition: city.h:349
int citizen_base[O_LAST]
Definition: city.h:328
int caravan_shields
Definition: city.h:362
bool did_buy
Definition: city.h:351
struct trade_route_list * routes
Definition: city.h:313
int usage[O_LAST]
Definition: city.h:329
struct worklist worklist
Definition: city.h:373
struct universal production
Definition: city.h:368
int steal
Definition: city.h:383
int unhappy_penalty[O_LAST]
Definition: city.h:326
char name[MAX_LEN_CITYNAME]
Definition: city.h:292
citizens size
Definition: city.h:301
int before_change_shields
Definition: city.h:360
int bought_shields
Definition: city.h:350
int style
Definition: city.h:297
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition: city.h:302
citizens specialists[SP_MAX]
Definition: city.h:305
struct tile * tile
Definition: city.h:293
int shield_stock
Definition: city.h:339
int prod[O_LAST]
Definition: city.h:327
struct universal changed_from
Definition: city.h:371
struct unit_list * units_supported
Definition: city.h:377
int illness_trade
Definition: city.h:341
struct requirement_vector reqs
Definition: city.h:470
char citizens_graphic[MAX_LEN_NAME]
Definition: city.h:468
char graphic_alt[MAX_LEN_NAME]
Definition: city.h:467
struct name_translation name
Definition: city.h:465
char graphic[MAX_LEN_NAME]
Definition: city.h:466
char citizens_graphic_alt[MAX_LEN_NAME]
Definition: city.h:469
struct rgbcolor * plr_bg_color
Definition: game.h:93
struct packet_scenario_description scenario_desc
Definition: game.h:79
struct packet_ruleset_control control
Definition: game.h:74
char * ruleset_summary
Definition: game.h:75
struct civ_game::@28::@31 client
struct conn_list * est_connections
Definition: game.h:88
int global_init_techs[MAX_NUM_TECH_LIST]
Definition: game.h:98
struct packet_game_info info
Definition: game.h:80
int global_init_buildings[MAX_NUM_BUILDING_LIST]
Definition: game.h:99
struct packet_scenario_info scenario
Definition: game.h:78
char * ruleset_description
Definition: game.h:76
struct conn_list * all_connections
Definition: game.h:87
struct civ_game::@27 rgame
struct packet_timeout_info tinfo
Definition: game.h:82
struct veteran_system * veteran
Definition: game.h:91
struct packet_calendar_info calendar
Definition: game.h:81
struct government * default_government
Definition: game.h:84
struct government * government_during_revolution
Definition: game.h:85
int xsize
Definition: map_types.h:73
int ysize
Definition: map_types.h:73
int num_continents
Definition: map_types.h:74
int topology_id
Definition: map_types.h:68
struct connection conn
Definition: client_main.h:89
struct requirement_vector receiver_reqs
Definition: diptreaty.h:50
struct requirement_vector giver_reqs
Definition: diptreaty.h:49
enum clause_type type
Definition: diptreaty.h:47
bool enabled
Definition: diptreaty.h:48
bool sound_bell_at_new_turn
Definition: options.h:80
bool autoaccept_tileset_suggestion
Definition: options.h:111
bool autoaccept_musicset_suggestion
Definition: options.h:113
bool draw_city_names
Definition: options.h:123
bool draw_city_productions
Definition: options.h:125
bool popup_new_cities
Definition: options.h:96
bool draw_city_trade_routes
Definition: options.h:127
bool wakeup_focus
Definition: options.h:89
bool autoaccept_soundset_suggestion
Definition: options.h:112
bool ask_city_name
Definition: options.h:95
bool draw_city_growth
Definition: options.h:124
bool ai_manual_turn_done
Definition: options.h:84
int smooth_combat_step_msec
Definition: options.h:83
bool auto_center_on_combat
Definition: options.h:87
bool popup_attack_actions
Definition: options.h:98
enum unit_type_flag_id flag
Definition: unittype.h:432
bool quiet
Definition: unittype.h:437
enum combat_bonus_type type
Definition: unittype.h:433
bool established
Definition: connection.h:131
struct player * playing
Definition: connection.h:142
enum cmdlevel access_level
Definition: connection.h:164
bool observer
Definition: connection.h:138
char username[MAX_LEN_NAME]
Definition: connection.h:151
struct connection::@55::@60 client
struct socket_packet_buffer * send_buffer
Definition: connection.h:145
char capability[MAX_LEN_CAPSTR]
Definition: connection.h:158
double ping_time
Definition: connection.h:148
struct socket_packet_buffer * buffer
Definition: connection.h:144
QString addr
Definition: connection.h:152
struct name_translation name
Definition: disaster.h:40
struct requirement_vector reqs
Definition: disaster.h:42
bv_disaster_effects effects
Definition: disaster.h:49
int frequency
Definition: disaster.h:47
bv_unit_classes native_to
Definition: extras.h:113
char rmact_gfx[MAX_LEN_NAME]
Definition: extras.h:87
bv_extras conflicts
Definition: extras.h:116
uint8_t rmcauses
Definition: extras.h:80
char act_gfx_alt[MAX_LEN_NAME]
Definition: extras.h:85
struct requirement_vector appearance_reqs
Definition: extras.h:92
bv_extra_flags flags
Definition: extras.h:115
char rmact_gfx_alt[MAX_LEN_NAME]
Definition: extras.h:88
uint16_t causes
Definition: extras.h:79
bv_extras bridged_over
Definition: extras.h:118
int removal_time
Definition: extras.h:104
int build_time_factor
Definition: extras.h:103
struct requirement_vector disappearance_reqs
Definition: extras.h:93
bool generated
Definition: extras.h:101
int special_idx
Definition: extras.h:133
struct requirement_vector rmreqs
Definition: extras.h:91
Tech_type_id visibility_req
Definition: extras.h:120
enum extra_category category
Definition: extras.h:78
int id
Definition: extras.h:75
struct extra_type::@22 data
char graphic_alt[MAX_LEN_NAME]
Definition: extras.h:83
char activity_gfx[MAX_LEN_NAME]
Definition: extras.h:84
int disappearance_chance
Definition: extras.h:109
int removal_time_factor
Definition: extras.h:105
char act_gfx_alt2[MAX_LEN_NAME]
Definition: extras.h:86
struct requirement_vector reqs
Definition: extras.h:90
bool buildable
Definition: extras.h:100
enum extra_unit_seen_type eus
Definition: extras.h:111
int defense_bonus
Definition: extras.h:107
int appearance_chance
Definition: extras.h:108
char graphic_str[MAX_LEN_NAME]
Definition: extras.h:82
int build_time
Definition: extras.h:102
bv_extras hidden_by
Definition: extras.h:117
QVector< QString > * helptext
Definition: extras.h:130
struct name_translation name
Definition: extras.h:76
struct requirement_vector reqs
Definition: traderoutes.h:185
int onetime_pct
Definition: traderoutes.h:189
bv_goods_flags flags
Definition: traderoutes.h:191
QVector< QString > * helptext
Definition: traderoutes.h:193
struct name_translation name
Definition: traderoutes.h:182
struct requirement_vector reqs
Definition: government.h:41
char graphic_alt[MAX_LEN_NAME]
Definition: government.h:40
Government_type_id item_number
Definition: government.h:36
QVector< QString > * helptext
Definition: government.h:44
struct name_translation name
Definition: government.h:37
char graphic_str[MAX_LEN_NAME]
Definition: government.h:39
int build_cost
Definition: improvement.h:68
char graphic_str[MAX_LEN_NAME]
Definition: improvement.h:64
int upkeep
Definition: improvement.h:69
enum impr_genus_id genus
Definition: improvement.h:71
char graphic_alt[MAX_LEN_NAME]
Definition: improvement.h:65
struct requirement_vector obsolete_by
Definition: improvement.h:67
int sabotage
Definition: improvement.h:70
char soundtag_alt[MAX_LEN_NAME]
Definition: improvement.h:75
struct requirement_vector reqs
Definition: improvement.h:66
struct name_translation name
Definition: improvement.h:61
bv_impr_flags flags
Definition: improvement.h:72
QVector< QString > * helptext
Definition: improvement.h:73
char soundtag[MAX_LEN_NAME]
Definition: improvement.h:74
struct requirement_vector reqs
Definition: multipliers.h:25
QVector< QString > * helptext
Definition: multipliers.h:26
Multiplier_type_id id
Definition: multipliers.h:15
struct name_translation name
Definition: multipliers.h:16
struct requirement_vector reqs
Definition: style.h:28
QString music_peaceful
Definition: style.h:26
QString music_combat
Definition: style.h:27
int id
Definition: style.h:25
bool hidden
Definition: nation.h:152
Functions for handling the nations.
Definition: nation.cpp:33
struct name_translation name
Definition: style.h:20
int id
Definition: style.h:19
int init_buildings[MAX_NUM_BUILDING_LIST]
Definition: nation.h:102
struct nation_group_list * groups
Definition: nation.h:95
struct name_translation noun_plural
Definition: nation.h:81
struct nation_set_list * sets
Definition: nation.h:92
char flag_graphic_str[MAX_LEN_NAME]
Definition: nation.h:82
struct name_translation adjective
Definition: nation.h:80
char flag_graphic_alt[MAX_LEN_NAME]
Definition: nation.h:83
std::array< unit_type *, MAX_NUM_UNIT_LIST > init_units
Definition: nation.h:105
char * legend
Definition: nation.h:86
enum barbarian_type barb_type
Definition: nation.h:89
char * translation_domain
Definition: nation.h:79
struct nation_type::@48::@51 client
struct nation_style * style
Definition: nation.h:85
int init_techs[MAX_NUM_TECH_LIST]
Definition: nation.h:101
government * init_government
Definition: nation.h:103
bool is_playable
Definition: nation.h:88
enum ai_level skill_level
Definition: player.h:109
enum barbarian_type barbarian_type
Definition: player.h:115
int science_cost
Definition: player.h:112
int love[MAX_NUM_PLAYER_SLOTS]
Definition: player.h:117
int has_reason_to_cancel
Definition: player.h:197
int contact_turns_left
Definition: player.h:198
enum diplstate_type type
Definition: player.h:193
int game
Definition: player.h:103
double energy_rate
Definition: spaceship.h:111
bv_spaceship_structure structure
Definition: spaceship.h:97
double success_rate
Definition: spaceship.h:112
double support_rate
Definition: spaceship.h:110
double travel_time
Definition: spaceship.h:113
enum spaceship_state state
Definition: spaceship.h:105
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct player_ai ai_common
Definition: player.h:270
bv_plr_flags flags
Definition: player.h:274
struct player::@65::@68 client
int primary_capital_id
Definition: player.h:257
bool is_male
Definition: player.h:239
int wonders[B_LAST]
Definition: player.h:283
struct government * target_government
Definition: player.h:241
char username[MAX_LEN_NAME]
Definition: player.h:234
bool is_connected
Definition: player.h:278
int revolution_finishes
Definition: player.h:255
int nturns_idle
Definition: player.h:247
struct government * government
Definition: player.h:240
int turns_alive
Definition: player.h:248
bool was_created
Definition: player.h:276
struct unit_list * units
Definition: player.h:264
struct conn_list * connections
Definition: player.h:280
bool is_alive
Definition: player.h:250
bv_player real_embassy
Definition: player.h:259
struct player_economic economic
Definition: player.h:266
struct player_spaceship spaceship
Definition: player.h:268
char name[MAX_LEN_NAME]
Definition: player.h:233
bv_player gives_shared_vision
Definition: player.h:281
struct player_score score
Definition: player.h:265
int multipliers[MAX_NUM_MULTIPLIERS]
Definition: player.h:296
QBitArray * tile_known
Definition: player.h:291
int music_style
Definition: player.h:262
struct nation_style * style
Definition: player.h:261
int multipliers_target[MAX_NUM_MULTIPLIERS]
Definition: player.h:298
bool phase_done
Definition: player.h:245
bool is_ready
Definition: player.h:244
int history
Definition: player.h:300
struct rgbcolor * rgb
Definition: player.h:293
bool unassigned_user
Definition: player.h:235
Tech_type_id researching
Definition: research.h:45
struct research::@71::@73 client
int future_tech
Definition: research.h:35
Tech_type_id tech_goal
Definition: research.h:78
int techs_researched
Definition: research.h:35
int bulbs_researched
Definition: research.h:46
int output[O_LAST]
Definition: terrain.h:43
int g
Definition: rgbcolor.h:27
int b
Definition: rgbcolor.h:27
int r
Definition: rgbcolor.h:27
Definition: road.h:54
struct requirement_vector first_reqs
Definition: road.h:64
enum road_move_mode move_mode
Definition: road.h:58
int id
Definition: road.h:55
int tile_bonus[O_LAST]
Definition: road.h:61
int tile_incr_const[O_LAST]
Definition: road.h:59
int tile_incr[O_LAST]
Definition: road.h:60
bv_roads integrates
Definition: road.h:66
bv_road_flags flags
Definition: road.h:67
int move_cost
Definition: road.h:57
enum road_compat compat
Definition: road.h:62
enum spaceship_place_type type
Definition: spaceship.h:129
struct requirement_vector reqs
Definition: specialist.h:32
char graphic_alt[MAX_LEN_NAME]
Definition: specialist.h:30
char graphic_str[MAX_LEN_NAME]
Definition: specialist.h:29
struct name_translation name
Definition: specialist.h:25
QVector< QString > * helptext
Definition: specialist.h:34
struct name_translation abbreviation
Definition: specialist.h:26
struct name_translation name
Definition: tech.h:108
int cost_pct
Definition: tech.h:110
int placing_time
Definition: terrain.h:208
struct extra_type ** resources
Definition: terrain.h:190
bv_terrain_flags flags
Definition: terrain.h:238
bv_unit_classes native_to
Definition: terrain.h:236
int road_time
Definition: terrain.h:194
struct name_translation name
Definition: terrain.h:172
int plant_time
Definition: terrain.h:198
int irrigation_food_incr
Definition: terrain.h:201
int clean_fallout_time
Definition: terrain.h:213
struct terrain * irrigation_result
Definition: terrain.h:200
int defense_bonus
Definition: terrain.h:186
int cultivate_time
Definition: terrain.h:196
int movement_cost
Definition: terrain.h:185
QVector< QString > * helptext
Definition: terrain.h:242
const struct unit_type * animal
Definition: terrain.h:216
int pillage_time
Definition: terrain.h:214
int output[O_LAST]
Definition: terrain.h:188
int transform_time
Definition: terrain.h:211
struct terrain * mining_result
Definition: terrain.h:204
char graphic_alt[MAX_LEN_NAME]
Definition: terrain.h:175
int mining_time
Definition: terrain.h:206
struct rgbcolor * rgb
Definition: terrain.h:240
int clean_pollution_time
Definition: terrain.h:212
char graphic_str[MAX_LEN_NAME]
Definition: terrain.h:174
enum terrain_class tclass
Definition: terrain.h:183
int road_output_incr_pct[O_LAST]
Definition: terrain.h:192
struct terrain * transform_result
Definition: terrain.h:210
int irrigation_time
Definition: terrain.h:202
int base_time
Definition: terrain.h:193
int mining_shield_incr
Definition: terrain.h:205
Definition: tile.h:42
char * spec_sprite
Definition: tile.h:58
char * label
Definition: tile.h:57
int index
Definition: tile.h:43
bv_extras extras
Definition: tile.h:47
struct unit_list * units
Definition: tile.h:50
struct player * extras_owner
Definition: tile.h:55
int infra_turns
Definition: tile.h:54
struct extra_type * placing
Definition: tile.h:53
struct player * owner
Definition: tile.h:52
Continent_id continent
Definition: tile.h:46
enum traderoute_bonus_type bonus_type
Definition: traderoutes.h:67
enum traderoute_illegal_cancelling cancelling
Definition: traderoutes.h:66
enum route_direction dir
Definition: traderoutes.h:75
struct goods_type * goods
Definition: traderoutes.h:76
int hp_loss_pct
Definition: unittype.h:126
int non_native_def_pct
Definition: unittype.h:128
int min_speed
Definition: unittype.h:125
enum hut_behavior hut_behavior
Definition: unittype.h:129
QVector< QString > * helptext
Definition: unittype.h:132
struct name_translation name
Definition: unittype.h:122
bv_unit_class_flags flags
Definition: unittype.h:130
int transport_capacity
Definition: unittype.h:488
struct unit_class * uclass
Definition: unittype.h:519
int pop_cost
Definition: unittype.h:477
struct unit_type::@82 adv
struct requirement_vector build_reqs
Definition: unittype.h:485
int defense_strength
Definition: unittype.h:480
bv_unit_classes cargo
Definition: unittype.h:521
int firepower
Definition: unittype.h:490
QVector< QString > * helptext
Definition: unittype.h:534
int paratroopers_range
Definition: unittype.h:506
char graphic_alt[MAX_LEN_NAME]
Definition: unittype.h:471
bool worker
Definition: unittype.h:538
char sound_move_alt[MAX_LEN_NAME]
Definition: unittype.h:473
int build_cost
Definition: unittype.h:476
int convert_time
Definition: unittype.h:496
int city_size
Definition: unittype.h:515
struct veteran_system * veteran
Definition: unittype.h:509
const struct unit_type * obsoleted_by
Definition: unittype.h:494
int vision_radius_sq
Definition: unittype.h:487
int move_rate
Definition: unittype.h:481
bv_unit_classes targets
Definition: unittype.h:524
enum vision_layer vlayer
Definition: unittype.h:532
struct advance * require_advance
Definition: unittype.h:484
int bombard_rate
Definition: unittype.h:512
char graphic_str[MAX_LEN_NAME]
Definition: unittype.h:470
int city_slots
Definition: unittype.h:517
char sound_move[MAX_LEN_NAME]
Definition: unittype.h:472
int hp
Definition: unittype.h:489
char sound_fight_alt[MAX_LEN_NAME]
Definition: unittype.h:475
struct name_translation name
Definition: unittype.h:467
int fuel
Definition: unittype.h:497
bv_unit_type_roles roles
Definition: unittype.h:500
int upkeep[O_LAST]
Definition: unittype.h:503
bv_unit_classes disembarks
Definition: unittype.h:530
const struct unit_type * converted_to
Definition: unittype.h:495
bv_unit_type_flags flags
Definition: unittype.h:499
char sound_fight[MAX_LEN_NAME]
Definition: unittype.h:474
bv_unit_classes embarks
Definition: unittype.h:527
int attack_strength
Definition: unittype.h:479
int happy_cost
Definition: unittype.h:502
struct combat_bonus_list * bonuses
Definition: unittype.h:491
Definition: unit.h:134
time_t action_timestamp
Definition: unit.h:203
int length
Definition: unit.h:192
int upkeep[O_LAST]
Definition: unit.h:145
bool has_orders
Definition: unit.h:190
enum action_decision action_decision_want
Definition: unit.h:199
int battlegroup
Definition: unit.h:188
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
struct unit::@76::@78 client
int id
Definition: unit.h:141
bool moved
Definition: unit.h:170
int index
Definition: unit.h:192
bool vigilant
Definition: unit.h:194
int hp
Definition: unit.h:148
int fuel
Definition: unit.h:150
struct extra_type * changed_from_target
Definition: unit.h:167
bool stay
Definition: unit.h:202
enum direction8 facing
Definition: unit.h:138
struct extra_type * activity_target
Definition: unit.h:161
int activity_count
Definition: unit.h:159
struct unit_order * list
Definition: unit.h:195
enum unit_activity changed_from
Definition: unit.h:165
struct player * nationality
Definition: unit.h:140
bool repeat
Definition: unit.h:193
QString name
Definition: unit.h:143
int action_turn
Definition: unit.h:204
int homecity
Definition: unit.h:142
bool paradropped
Definition: unit.h:171
bool done_moving
Definition: unit.h:178
struct goods_type * carrying
Definition: unit.h:183
struct tile * goto_tile
Definition: unit.h:152
struct unit::@75 orders
struct tile * action_decision_tile
Definition: unit.h:200
const struct unit_type * utype
Definition: unit.h:135
int veteran
Definition: unit.h:149
int changed_from_count
Definition: unit.h:166
struct player * owner
Definition: unit.h:139
enum server_side_agent ssa_controller
Definition: unit.h:169
enum universals_n kind
Definition: fc_types.h:740
int yes
Definition: voteinfo.h:26
int num_voters
Definition: voteinfo.h:29
bool passed
Definition: voteinfo.h:31
int abstain
Definition: voteinfo.h:28
bool resolved
Definition: voteinfo.h:30
int vote_no
Definition: voteinfo.h:21
int no
Definition: voteinfo.h:27
enum unit_activity act
Definition: workertask.h:17
struct tile * ptile
Definition: workertask.h:16
struct extra_type * tgt
Definition: workertask.h:18
struct civ_map map
Definition: world_object.h:21
struct music_style * music_style_by_number(int id)
Return music style of given id.
Definition: style.cpp:158
void styles_alloc(int count)
Initialise styles structures.
Definition: style.cpp:30
struct nation_style * style_by_number(int id)
Return style of given id.
Definition: style.cpp:74
void music_styles_alloc(int count)
Initialise music styles structures.
Definition: style.cpp:121
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
Definition: support.cpp:412
size_t fc_strlcat(char *dest, const char *src, size_t n)
fc_strlcat() provides utf-8 version of (non-standard) function strlcat() It is intended as more user-...
Definition: support.cpp:448
#define sz_strlcpy(dest, src)
Definition: support.h:140
#define fc_strdup(str)
Definition: support.h:111
void team_add_player(struct player *pplayer, struct team *pteam)
Set a player to a team.
Definition: team.cpp:438
int team_count()
Return the current number of teams.
Definition: team.cpp:354
struct team * team_new(struct team_slot *tslot)
Creates a new team for the slot.
Definition: team.cpp:294
struct team_slot * team_slot_by_number(int team_id)
Return the possibly unused and uninitialized team slot.
Definition: team.cpp:157
void team_slot_set_defined_name(struct team_slot *tslot, const char *team_name)
Set the name defined in the ruleset for this slot.
Definition: team.cpp:272
void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt)
Sets user defined name for tech flag.
Definition: tech.cpp:378
struct tech_class * tech_class_by_number(const int idx)
Return the tech_class for the given index.
Definition: tech.cpp:304
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
Definition: tech.cpp:94
Tech_type_id advance_count()
Return the number of advances/technologies.
Definition: tech.cpp:68
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:85
#define A_FUTURE
Definition: tech.h:39
#define A_NEVER
Definition: tech.h:44
#define advance_index_iterate_end
Definition: tech.h:226
tech_req
Definition: tech.h:104
@ AR_TWO
Definition: tech.h:104
@ AR_ROOT
Definition: tech.h:104
@ AR_ONE
Definition: tech.h:104
#define A_NONE
Definition: tech.h:36
#define A_LAST
Definition: tech.h:38
#define advance_index_iterate(_start, _index)
Definition: tech.h:221
Terrain_type_id terrain_count()
Return the number of terrains.
Definition: terrain.cpp:93
struct terrain * terrain_by_number(const Terrain_type_id type)
Return the terrain for the given terrain index.
Definition: terrain.cpp:128
const char * terrain_rule_name(const struct terrain *pterrain)
Return the (untranslated) rule name of the terrain.
Definition: terrain.cpp:184
struct resource_type * resource_type_init(struct extra_type *pextra)
Initialize resource_type structure.
Definition: terrain.cpp:209
void set_user_terrain_flag_name(enum terrain_flag_id id, const char *name, const char *helptxt)
Sets user defined name for terrain flag.
Definition: terrain.cpp:673
#define MAX_RESOURCE_TYPES
Definition: terrain.h:61
#define MAX_NUM_TERRAINS
Definition: terrain.h:58
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Set the given terrain at the specified tile.
Definition: tile.cpp:114
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Set the owner of a tile (may be nullptr).
Definition: tile.cpp:58
bool tile_set_label(struct tile *ptile, const char *label)
Sets label for tile.
Definition: tile.cpp:1104
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Set the given resource at the specified tile.
Definition: tile.cpp:355
void tile_set_worked(struct tile *ptile, struct city *pcity)
Set the city/worker on the tile (may be nullptr).
Definition: tile.cpp:96
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_worked(_tile)
Definition: tile.h:97
#define tile_resource(_tile)
Definition: tile.h:84
known_type
Definition: tile.h:28
@ TILE_KNOWN_UNSEEN
Definition: tile.h:30
@ TILE_UNKNOWN
Definition: tile.h:29
@ TILE_KNOWN_SEEN
Definition: tile.h:31
#define tile_list_iterate(tile_list, ptile)
Definition: tile.h:65
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_list_iterate_end
Definition: tile.h:67
#define tile_owner(_tile)
Definition: tile.h:78
bool tilespec_reread(const QString &name, bool game_fully_initialized)
Read a new tilespec in from scratch.
Definition: tilespec.cpp:916
void tileset_setup_unit_type(struct tileset *t, struct unit_type *ut)
Set unit_type sprite value; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:2847
const char * tileset_basename(const struct tileset *t)
Return the name of the given tileset.
Definition: tilespec.cpp:331
void tileset_setup_government(struct tileset *t, struct government *gov)
Set government sprite value; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:3007
void tileset_setup_specialist_type(struct tileset *t, Specialist_type_id id)
Setup the graphics for specialist types.
Definition: tilespec.cpp:2423
void tileset_setup_tile_type(struct tileset *t, const struct terrain *pterrain)
Set tile_type sprite values; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:2995
void tileset_player_init(struct tileset *t, struct player *pplayer)
Setup tiles for one player using the player color.
Definition: tilespec.cpp:3708
bool unit_drawn_with_city_outline(const struct unit *punit, bool check_focus)
Indicate whether a unit is to be drawn with a surrounding city outline under current conditions.
Definition: tilespec.cpp:3116
void tileset_setup_impr_type(struct tileset *t, struct impr_type *pimprove)
Set improvement_type sprite value; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:2879
void tileset_setup_tech_type(struct tileset *t, struct advance *padvance)
Set tech_type sprite value; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:2895
void tileset_setup_city_tiles(struct tileset *t, int style)
Set city tiles sprite values; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:3188
void tileset_setup_extra(struct tileset *t, struct extra_type *pextra)
Set extra sprite values; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:2937
void finish_loading_sprites(struct tileset *t)
Frees any internal buffers which are created by load_sprite.
Definition: tilespec.cpp:2698
void tileset_error(struct tileset *t, QtMsgType level, const char *format,...)
Called when ever there's problem in ruleset/tileset compatibility.
Definition: tilespec.cpp:291
help_item * tileset_help(const struct tileset *t)
Creates the help item for the given tileset.
Definition: tilespec.cpp:3859
void tilespec_reread_frozen_refresh(const QString &name)
Read a new tilespec in from scratch.
Definition: tilespec.cpp:1091
void tileset_setup_nation_flag(struct tileset *t, struct nation_type *nation)
Set nation flag sprite value; should only happen after tilespec_load_tiles().
Definition: tilespec.cpp:3020
void tileset_ruleset_reset(struct tileset *t)
Reset tileset data specific to ruleset.
Definition: tilespec.cpp:3740
#define MAX_NUM_CITIZEN_SPRITES
Definition: tilespec.h:46
struct goods_type * goods_by_number(Goods_type_id id)
Return goods type of given id.
int city_num_trade_routes(const struct city *pcity)
Return number of trade route city has.
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Get trade route settings related to type.
trade_route_type
Definition: traderoutes.h:30
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Load pcargo onto ptrans.
Definition: unit.cpp:2123
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
bool unit_transport_unload(struct unit *pcargo)
Unload pcargo from ptrans.
Definition: unit.cpp:2144
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Returns the list of cargo units.
Definition: unit.cpp:2199
void unit_virtual_destroy(struct unit *punit)
Free the memory used by virtual unit.
Definition: unit.cpp:1588
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Create a virtual unit skeleton.
Definition: unit.cpp:1490
void unit_tile_set(struct unit *punit, struct tile *ptile)
Set the tile location of the unit.
Definition: unit.cpp:1200
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
#define unit_tile(_pu)
Definition: unit.h:371
@ FOCUS_AVAIL
Definition: unit.h:46
@ FOCUS_WAIT
Definition: unit.h:46
@ ORDER_PERFORM_ACTION
Definition: unit.h:41
#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
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
Definition: unittype.cpp:1283
void set_unit_class_caches(struct unit_class *pclass)
Set caches for unit class.
Definition: unittype.cpp:2349
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
struct unit_type * utype_by_number(const Unit_type_id id)
Return a pointer for the unit type struct for the given unit type id.
Definition: unittype.cpp:103
void set_unit_move_type(struct unit_class *puclass)
Set move_type for unit class.
Definition: unittype.cpp:2504
void set_unit_type_caches(struct unit_type *ptype)
Set caches for unit types.
Definition: unittype.cpp:2408
struct veteran_system * veteran_system_new(int count)
Allocate new veteran system structure with given veteran level count.
Definition: unittype.cpp:2281
void veteran_system_definition(struct veteran_system *vsystem, int level, const char *vlist_name, int vlist_power, int vlist_move, int vlist_raise, int vlist_wraise)
Fill veteran level in given veteran system with given information.
Definition: unittype.cpp:2310
void unit_type_action_cache_set(struct unit_type *ptype)
Cache if any action may be possible for a unit of the type putype given the property tested for.
Definition: unittype.cpp:710
struct unit_class * uclass_by_number(const Unit_Class_id id)
Returns unit class pointer for an ID value.
Definition: unittype.cpp:2129
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Sets user defined name for unit class flag.
Definition: unittype.cpp:1493
const char * unit_name_translation(const struct unit *punit)
Return the (translated) name of the unit.
Definition: unittype.cpp:1265
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Sets user defined name for unit flag.
Definition: unittype.cpp:1556
#define UCF_LAST_USER_FLAG
Definition: unittype.h:97
hut_behavior
Definition: unittype.h:113
#define unit_class_iterate(_p)
Definition: unittype.h:823
#define UTYF_LAST_USER_FLAG
Definition: unittype.h:302
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define U_LAST
Definition: unittype.h:31
#define unit_class_iterate_end
Definition: unittype.h:829
#define unit_type_iterate_end
Definition: unittype.h:791
void players_dialog_update(void)
void put_nuke_mushroom_pixmaps(struct tile *ptile)
Animate the nuke explosion at map(x, y).
bool tile_visible_mapcanvas(struct tile *ptile)
Return TRUE iff the given map position has a tile visible on the map canvas.
void mapdeco_init()
Called when we receive map dimensions.
void refresh_tile_mapcanvas(const tile *ptile, bool full_refresh)
Refreshes a single tile on the map canvas.
void animate_unit_explosion(const tile *location)
Draws an explosion animation on the given sprite.
void refresh_city_mapcanvas(struct city *pcity, struct tile *ptile, bool full_refresh)
Refreshes a single city on the map canvas.
void update_city_description(struct city *pcity)
Update the city description for the given city.
void refresh_unit_mapcanvas(struct unit *punit, struct tile *ptile, bool full_refresh)
Refreshes a single unit on the map canvas.
void link_marks_decrease_turn_counters()
Clear all visible links.
void decrease_unit_hp_smooth(struct unit *punit0, int hp0, struct unit *punit1, int hp1)
This function is called to decrease a unit's HP smoothly in battle when combat_animation is turned on...
enum topo_comp_lvl tileset_map_topo_compatible(int topology_id, struct tileset *tset)
Are the topology and tileset compatible?
void update_map_canvas_visible()
Schedules an update of (only) the visible part of the map at the next unqueue_mapview_update().
@ TOPO_INCOMP_HARD
void close_intel_dialog(struct player *p)
Close an intelligence dialog for the given player.
void update_intel_dialog(struct player *p)
Update the intelligence dialog for the given player.
#define vision_layer_iterate(v)
Definition: vision.h:72
#define vision_layer_iterate_end
Definition: vision.h:77
void voteinfo_queue_delayed_remove(int vote_no)
Remove the vote with number 'vote_no' after a small amount of time so that the user can see that it w...
Definition: voteinfo.cpp:46
struct voteinfo * voteinfo_queue_find(int vote_no)
Find the voteinfo record corresponding to the given vote number.
Definition: voteinfo.cpp:144
void voteinfo_queue_add(int vote_no, const char *user, const char *desc, int percent_required, int flags)
Create a new voteinfo record and place it in the queue.
Definition: voteinfo.cpp:117
void voteinfo_gui_update(void)
Refresh all vote related GUI widgets.
#define worker_task_list_iterate(tasklist, ptask)
Definition: workertask.h:27
#define worker_task_list_iterate_end
Definition: workertask.h:29
void worklist_copy(struct worklist *dst, const struct worklist *src)
Copy contents from worklist src to worklist dst.
Definition: worklist.cpp:103
void worklist_init(struct worklist *pwl)
Initialize a worklist to be empty.
Definition: worklist.cpp:32