Freeciv21
Develop your civilization from humble roots to a global empire
governor.cpp
Go to the documentation of this file.
1 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
2  Copyright (c) 1996-2020 Freeciv21 & Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, 0R (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
11 
12 #include <QElapsedTimer>
13 
14 // utility
15 #include "bugs.h"
16 #include "fciconv.h"
17 
18 // common
19 #include "city.h"
20 #include "dataio.h"
21 #include "featured_text.h"
22 #include "nation.h"
23 #include "player.h"
24 #include "specialist.h"
25 // client
26 #include "attribute.h"
27 #include "citydlg_common.h"
28 #include "client_main.h"
29 #include "climisc.h"
30 
31 // include
32 #include "citydlg_g.h"
33 #include "cityrep_g.h"
34 #include "mapctrl_g.h"
35 
36 #include "governor.h"
37 
38 #define log_apply_result log_debug
39 #define log_handle_city log_debug
40 #define log_handle_city2 log_debug
41 #define log_results_are_equal log_debug
42 
43 #define SHOW_APPLY_RESULT_ON_SERVER_ERRORS false
44 #define ALWAYS_APPLY_AT_SERVER false
45 #define MAX_LEN_PRESET_NAME 80
46 #define SAVED_PARAMETER_SIZE 32
47 
48 #define CMA_NUM_PARAMS 5
49 
50 #define SPECLIST_TAG preset
51 #define SPECLIST_TYPE struct cma_preset
52 #include "speclist.h"
53 
54 static struct preset_list *preset_list = nullptr;
55 
56 struct cma_preset {
57  char *descr;
58  struct cm_parameter parameter;
59 };
60 
61 static struct {
64 
66 
67 // yolo class
68 class cma_yoloswag {
69 public:
70  cma_yoloswag();
72  void put_city_under_agent(struct city *pcity,
73  const struct cm_parameter *const parameter);
74  void release_city(struct city *pcity);
75  bool is_city_under_agent(const struct city *pcity,
76  struct cm_parameter *parameter);
77  bool get_parameter(enum attr_city attr, int city_id,
78  struct cm_parameter *parameter);
79  void set_parameter(enum attr_city attr, int city_id,
80  const struct cm_parameter *parameter);
81  void handle_city(struct city *pcity);
82  int get_request();
83  void result_came_from_server(int request);
84 
85 private:
86  struct city *check_city(int city_id, struct cm_parameter *parameter);
87  bool apply_result_on_server(struct city *pcity,
88  std::unique_ptr<cm_result> &&result);
89  std::unique_ptr<cm_result> cma_result_got;
91  struct city *xcity;
92 };
93 
94 // gimb means "governor is my bitch"
96 
97 // deletes governor
98 void governor::drop()
99 {
100  delete m_instance;
101  m_instance = nullptr;
102 }
103 
104 governor::~governor() = default;
105 
106 // instance for governor
108 {
109  if (m_instance == nullptr) {
110  m_instance = new governor;
111  }
112  return m_instance;
113 }
114 
115 // register new event and run it if hot
116 void governor::add_city_changed(struct city *pcity)
117 {
118  scity_changed.insert(pcity->id);
119  run();
120 };
121 
122 void governor::add_city_new(struct city *pcity)
123 {
124  scity_changed.insert(pcity->id);
125  run();
126 };
127 
128 void governor::add_city_remove(struct city *pcity)
129 {
130  scity_remove.insert(pcity->id);
131  run();
132 };
133 
134 // run all events
136 {
137  if (superhot < 1 || !client.conn.playing) {
138  return;
139  }
140 
141  // Remove deleted cities
142  for (auto id : scity_remove) {
143  attr_city_set(ATTR_CITY_CMAFE_PARAMETER, id, 0, nullptr);
144  attr_city_set(ATTR_CITY_CMA_PARAMETER, id, 0, nullptr);
145  }
146  scity_remove.clear();
147 
148  // Handle changed cities
149  for (auto id : scity_changed) {
151  // Might have been removed
152  if (city) {
153  gimb->handle_city(city);
154  }
155  }
156  scity_changed.clear();
157 
159 }
160 
161 inline bool operator==(const struct cm_result &result1,
162  const struct cm_result &result2)
163 {
164  if ((result1.disorder != result2.disorder)
165  || (result1.happy != result2.happy)) {
166  return false;
167  }
168 
170  {
171  if (result1.specialists[sp] != result2.specialists[sp]) {
172  return false;
173  }
174  }
176 
178  {
179  if (result1.surplus[ot] != result2.surplus[ot]) {
180  return false;
181  }
182  }
184 
185  fc_assert_ret_val(result1.city_radius_sq == result2.city_radius_sq, false);
186  city_map_iterate(result1.city_radius_sq, cindex, x, y)
187  {
188  if (is_city_center_index(cindex)) {
189  continue;
190  }
191 
192  if (result1.worker_positions[cindex]
193  != result2.worker_positions[cindex]) {
194  log_results_are_equal("worker_positions");
195  return false;
196  }
197  }
199 
200  return true;
201 }
202 
203 // yet another abstraction layer
204 int cities_results_request() { return gimb->get_request(); }
206 void cma_got_result(int citynr) { gimb->result_came_from_server(citynr); }
207 
208 // yolo constructor
210 {
211  last_request = -9999;
212  cma_result_got = nullptr;
213  xcity = nullptr;
214 }
215 
216 // cma results returned from server to check if everything is legit
217 void cma_yoloswag::result_came_from_server(int last_request_id)
218 {
219  struct city *pcity = xcity;
220  last_request = last_request_id;
221  bool success;
222 
223  if (last_request_id < 0) {
224  return;
225  }
226  if (last_request_id != 0) {
227  int city_id = pcity->id;
228 
229  if (pcity != check_city(city_id, nullptr)) {
230  qDebug("apply_result_on_server(city %d) !check_city()!", city_id);
231  return;
232  }
233  }
234 
235  // Return.
236  auto state_result = cm_result_new(pcity);
237  cm_result_from_main_map(state_result, pcity);
238 
239  success = (cma_result_got && *state_result == *cma_result_got);
240  if (!success) {
241 #if SHOW_APPLY_RESULT_ON_SERVER_ERRORS
242  qCritical("apply_result_on_server(city %d=\"%s\") no match!", pcity->id,
243  city_name_get(pcity));
244 
245  log_test("apply_result_on_server(city %d=\"%s\") have:", pcity->id,
246  city_name_get(pcity));
247  cm_print_city(pcity);
248  cm_print_result(state_result);
249 
250  log_test("apply_result_on_server(city %d=\"%s\") want:", pcity->id,
251  city_name_get(pcity));
253 #endif // SHOW_APPLY_RESULT_ON_SERVER_ERRORS
254  }
255  cma_result_got = nullptr;
256  log_apply_result("apply_result_on_server() return %d.", (int) success);
257  last_request = -9999;
258  xcity = nullptr;
259 }
260 
261 cma_yoloswag::~cma_yoloswag() = default;
262 
268  struct city *pcity, std::unique_ptr<cm_result> &&result)
269 {
270  int first_request_id = 0, last_request_id = 0, i;
272  struct tile *pcenter = city_tile(pcity);
273 
274  fc_assert_ret_val(result->found_a_valid, false);
275  auto current_state = cm_result_new(pcity);
276  cm_result_from_main_map(current_state, pcity);
277 
278  if (*current_state == *result && !ALWAYS_APPLY_AT_SERVER) {
279  stats.apply_result_ignored++;
280  return true;
281  }
282  // Do checks
283  if (city_size_get(pcity) != cm_result_citizens(result)) {
284  qCritical("apply_result_on_server(city %d=\"%s\") bad result!",
285  pcity->id, city_name_get(pcity));
286  cm_print_city(pcity);
287  cm_print_result(result);
288  return false;
289  }
290 
291  stats.apply_result_applied++;
292 
293  log_apply_result("apply_result_on_server(city %d=\"%s\")", pcity->id,
294  city_name_get(pcity));
295 
297 
298  // Remove all surplus workers
299  city_tile_iterate_skip_center(city_radius_sq, pcenter, ptile, idx, x, y)
300  {
301  if (tile_worked(ptile) == pcity && !result->worker_positions[idx]) {
302  log_apply_result("Removing worker at {%d,%d}.", x, y);
303 
304  last_request_id = dsend_packet_city_make_specialist(
305  &client.conn, pcity->id, ptile->index);
306  if (first_request_id == 0) {
307  first_request_id = last_request_id;
308  }
309  }
310  }
312 
313  // Change the excess non-default specialists to default.
315  {
316  if (sp == DEFAULT_SPECIALIST) {
317  continue;
318  }
319 
320  for (i = 0; i < pcity->specialists[sp] - result->specialists[sp]; i++) {
321  log_apply_result("Change specialist from %d to %d.", sp,
323  last_request_id =
325  if (first_request_id == 0) {
326  first_request_id = last_request_id;
327  }
328  }
329  }
331 
332  // now all surplus people are DEFAULT_SPECIALIST
333 
334  // Set workers
335  /* FIXME: This code assumes that any toggled worker will turn into a
336  * DEFAULT_SPECIALIST! */
337  city_tile_iterate_skip_center(city_radius_sq, pcenter, ptile, idx, x, y)
338  {
339  if (nullptr == tile_worked(ptile) && result->worker_positions[idx]) {
340  log_apply_result("Putting worker at {%d,%d}.", x, y);
341  fc_assert_action(city_can_work_tile(pcity, ptile), break);
342 
343  last_request_id = dsend_packet_city_make_worker(
344  &client.conn, pcity->id, ptile->index);
345  if (first_request_id == 0) {
346  first_request_id = last_request_id;
347  }
348  }
349  }
351 
352  /* Set all specialists except DEFAULT_SPECIALIST (all the unchanged
353  * ones remain as DEFAULT_SPECIALIST). */
355  {
356  if (sp == DEFAULT_SPECIALIST) {
357  continue;
358  }
359 
360  for (i = 0; i < result->specialists[sp] - pcity->specialists[sp]; i++) {
361  log_apply_result("Changing specialist from %d to %d.",
362  DEFAULT_SPECIALIST, sp);
363  last_request_id =
365  if (first_request_id == 0) {
366  first_request_id = last_request_id;
367  }
368  }
369  }
371 
372  if (last_request_id == 0 || ALWAYS_APPLY_AT_SERVER) {
373  /*
374  * If last_request is 0 no change request was send. But it also
375  * means that the results are different or the fc_results_are_equal()
376  * test at the start of the function would be true. So this
377  * means that the client has other results for the same
378  * allocation of citizen than the server. We just send a
379  * PACKET_CITY_REFRESH to bring them in sync.
380  */
381  first_request_id = dsend_packet_city_refresh(&client.conn, pcity->id);
382  last_request_id = first_request_id;
383  stats.refresh_forced++;
384  }
385 
387 
388  cma_result_got = std::move(result);
389  last_request = last_request_id;
390  xcity = pcity;
391  return true;
392 }
393 
395  struct city *pcity, const struct cm_parameter *const parameter)
396 {
397  log_debug("cma_put_city_under_agent(city %d=\"%s\")", pcity->id,
398  city_name_get(pcity));
400  cma_set_parameter(ATTR_CITY_CMA_PARAMETER, pcity->id, parameter);
401  governor::i()->add_city_changed(pcity);
402  log_debug("cma_put_city_under_agent: return");
403 }
404 
405 void cma_yoloswag::release_city(struct city *pcity)
406 {
407  attr_city_set(ATTR_CITY_CMA_PARAMETER, pcity->id, 0, nullptr);
408  refresh_city_dialog(pcity);
410 }
411 
412 bool cma_yoloswag::is_city_under_agent(const struct city *pcity,
413  struct cm_parameter *parameter)
414 {
415  struct cm_parameter my_parameter;
416 
418  &my_parameter)) {
419  return false;
420  }
421 
422  if (parameter) {
423  *parameter = my_parameter;
424  }
425  return true;
426 }
427 bool cma_yoloswag::get_parameter(enum attr_city attr, int city_id,
428  struct cm_parameter *parameter)
429 {
430  size_t len;
431  char buffer[SAVED_PARAMETER_SIZE];
432  struct data_in din;
433  int version, dummy;
434 
435  /* Changing this function is likely to break compatability with old
436  * savegames that store these values. Always add new parameters at the end.
437  */
438 
439  len = attr_city_get(attr, city_id, sizeof(buffer), buffer);
440  if (len == 0) {
441  return false;
442  }
443 
444  dio_input_init(&din, buffer, len);
445  fc_assert_ret_val(dio_get_uint8_raw(&din, &version), false);
446  fc_assert_ret_val(version == 2, false);
447 
448  /* Initialize the parameter (includes some AI-only fields that aren't
449  * touched below). */
450  cm_init_parameter(parameter);
451 
453  {
455  dio_get_sint16_raw(&din, &parameter->minimal_surplus[i]), false);
456  fc_assert_ret_val(dio_get_sint16_raw(&din, &parameter->factor[i]),
457  false);
458  }
460 
462  false);
463  fc_assert_ret_val(dio_get_uint8_raw(&din, &dummy),
464  false); // Dummy value; used to be factor_target.
466  false);
467 
468  // Optional fields
469  dio_get_bool8_raw(&din, &parameter->max_growth);
470  dio_get_bool8_raw(&din, &parameter->allow_disorder);
471  dio_get_bool8_raw(&din, &parameter->allow_specialists);
472 
473  return true;
474 }
475 
476 void cma_yoloswag::set_parameter(enum attr_city attr, int city_id,
477  const struct cm_parameter *parameter)
478 {
479  char buffer[SAVED_PARAMETER_SIZE];
480  struct raw_data_out dout;
481 
482  /* Changing this function is likely to break compatability with old
483  * savegames that store these values. */
484 
485  dio_output_init(&dout, buffer, sizeof(buffer));
486 
487  dio_put_uint8_raw(&dout, 2);
488 
490  {
491  dio_put_sint16_raw(&dout, parameter->minimal_surplus[i]);
492  dio_put_sint16_raw(&dout, parameter->factor[i]);
493  }
495 
496  dio_put_sint16_raw(&dout, parameter->happy_factor);
497  dio_put_uint8_raw(&dout, 0); // Dummy value; used to be factor_target.
498  dio_put_bool8_raw(&dout, parameter->require_happy);
499 
500  dio_put_bool8_raw(&dout, parameter->max_growth);
501  dio_put_bool8_raw(&dout, parameter->allow_disorder);
502  dio_put_bool8_raw(&dout, parameter->allow_specialists);
503 
505 
506  attr_city_set(attr, city_id, SAVED_PARAMETER_SIZE, buffer);
507 }
508 
513 struct city *cma_yoloswag::check_city(int city_id,
514  struct cm_parameter *parameter)
515 {
516  struct city *pcity = game_city_by_number(city_id);
517  struct cm_parameter dummy;
518 
519  if (!parameter) {
520  parameter = &dummy;
521  }
522 
523  if (!pcity
524  || !cma_get_parameter(ATTR_CITY_CMA_PARAMETER, city_id, parameter)) {
525  return nullptr;
526  }
527 
528  if (city_owner(pcity) != client.conn.playing) {
529  cma_release_city(pcity);
530  return nullptr;
531  }
532 
533  return pcity;
534 }
535 
541 void cma_yoloswag::handle_city(struct city *pcity)
542 {
543  auto result = cm_result_new(pcity);
544  bool handled;
545  int i, city_id = pcity->id;
546 
547  log_handle_city("handle_city(city %d=\"%s\") pos=(%d,%d) owner=%s",
548  pcity->id, city_name_get(pcity), TILE_XY(pcity->tile),
550 
551  log_handle_city2("START handle city %d=\"%s\"", pcity->id,
552  city_name_get(pcity));
553 
554  handled = false;
555  for (i = 0; i < 5; i++) {
556  struct cm_parameter parameter;
557 
558  log_handle_city2(" try %d", i);
559 
560  if (pcity != check_city(city_id, &parameter)) {
561  handled = true;
562  break;
563  }
564 
565  cm_query_result(pcity, &parameter, result, false);
566  if (!result->found_a_valid) {
567  log_handle_city2(" no valid found result");
568 
569  cma_release_city(pcity);
570 
571  create_event(city_tile(pcity), E_CITY_CMA_RELEASE, ftc_client,
572  _("The citizen governor can't fulfill the requirements "
573  "for %s. Passing back control."),
574  city_link(pcity));
575  handled = true;
576  break;
577  } else {
578  if (!apply_result_on_server(pcity, std::move(result))) {
579  log_handle_city2(" doesn't cleanly apply");
580  if (pcity == check_city(city_id, nullptr) && i == 0) {
581  create_event(city_tile(pcity), E_CITY_CMA_RELEASE, ftc_client,
582  _("The citizen governor has gotten confused dealing "
583  "with %s. You may want to have a look."),
584  city_link(pcity));
585  }
586  } else {
587  log_handle_city2(" ok");
588  // Everything ok
589  handled = true;
590  break;
591  }
592  result = nullptr;
593  }
594  }
595 
596  if (!handled) {
597  fc_assert_ret(pcity == check_city(city_id, nullptr));
598  log_handle_city2(" not handled");
599 
600  create_event(city_tile(pcity), E_CITY_CMA_RELEASE, ftc_client,
601  _("The citizen governor has gotten confused dealing "
602  "with %s. You may want to have a look."),
603  city_link(pcity));
604 
605  cma_release_city(pcity);
606 
607  qCInfo(bugs_category,
608  "handle_city() CMA: %s has changed multiple times.",
609  city_name_get(pcity));
610  }
611 
612  log_handle_city2("END handle city=(%d)", city_id);
613 }
614 
618 void cma_put_city_under_agent(struct city *pcity,
619  const struct cm_parameter *const parameter)
620 {
621  gimb->put_city_under_agent(pcity, parameter);
622 }
623 
627 void cma_release_city(struct city *pcity) { gimb->release_city(pcity); }
628 
632 bool cma_is_city_under_agent(const struct city *pcity,
633  struct cm_parameter *parameter)
634 {
635  return gimb->is_city_under_agent(pcity, parameter);
636 }
637 
645 bool cma_get_parameter(enum attr_city attr, int city_id,
646  struct cm_parameter *parameter)
647 {
648  return gimb->get_parameter(attr, city_id, parameter);
649 }
650 
654 void cma_set_parameter(enum attr_city attr, int city_id,
655  const struct cm_parameter *parameter)
656 {
657  gimb->set_parameter(attr, city_id, parameter);
658 }
659 
663 void cmafec_set_fe_parameter(struct city *pcity,
664  const struct cm_parameter *const parameter)
665 {
666  cma_set_parameter(ATTR_CITY_CMAFE_PARAMETER, pcity->id, parameter);
667 }
668 
673 void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
674 {
675  struct cm_parameter parameter;
676 
677  if (cma_is_city_under_agent(pcity, &parameter)) {
678  cm_copy_parameter(dest, &parameter);
679  } else {
680  // Create a dummy parameter to return.
681  cm_init_parameter(dest);
682  if (!cma_get_parameter(ATTR_CITY_CMAFE_PARAMETER, pcity->id, dest)) {
683  // We haven't seen this city before; store the dummy.
684  cmafec_set_fe_parameter(pcity, dest);
685  }
686  }
687 }
688 
692 void cmafec_preset_add(const char *descr_name, const cm_parameter *pparam)
693 {
694  struct cma_preset *ppreset = new cma_preset;
695 
696  if (preset_list == nullptr) {
697  preset_list = preset_list_new();
698  }
699 
700  cm_copy_parameter(&ppreset->parameter, pparam);
701  ppreset->descr = new char[MAX_LEN_PRESET_NAME];
702  (void) fc_strlcpy(ppreset->descr, descr_name, MAX_LEN_PRESET_NAME);
703  preset_list_prepend(preset_list, ppreset);
704 }
705 
709 void cmafec_preset_remove(int idx)
710 {
711  struct cma_preset *ppreset;
712 
713  fc_assert_ret(idx >= 0 && idx < cmafec_preset_num());
714 
715  ppreset = preset_list_get(preset_list, idx);
716  preset_list_remove(preset_list, ppreset);
717 
718  delete[] ppreset->descr;
719  delete ppreset;
720 }
721 
726 {
727  struct cma_preset *ppreset;
728 
729  fc_assert_ret_val(idx >= 0 && idx < cmafec_preset_num(), nullptr);
730 
731  ppreset = preset_list_get(preset_list, idx);
732  return ppreset->descr;
733 }
734 
739 {
740  struct cma_preset *ppreset;
741 
742  fc_assert_ret_val(idx >= 0 && idx < cmafec_preset_num(), nullptr);
743 
744  ppreset = preset_list_get(preset_list, idx);
745  return &ppreset->parameter;
746 }
747 
753  const struct cm_parameter *const parameter)
754 {
755  int i;
756 
757  for (i = 0; i < preset_list_size(preset_list); i++) {
758  struct cma_preset *ppreset = preset_list_get(preset_list, i);
759  if (ppreset->parameter == *parameter) {
760  return i;
761  }
762  }
763  return -1;
764 }
765 
769 int cmafec_preset_num() { return preset_list_size(preset_list); }
770 
774 const char *cmafec_get_short_descr_of_city(const struct city *pcity)
775 {
776  struct cm_parameter parameter;
777 
778  if (!cma_is_city_under_agent(pcity, &parameter)) {
779  return _("none");
780  } else {
781  return cmafec_get_short_descr(&parameter);
782  }
783 }
784 
789 const char *
790 cmafec_get_short_descr(const struct cm_parameter *const parameter)
791 {
792  int idx = cmafec_preset_get_index_of_parameter(parameter);
793 
794  if (idx == -1) {
795  return _("custom");
796  } else {
797  return cmafec_preset_get_descr(idx);
798  }
799 }
800 
805 {
806  int i;
807  struct cm_parameter parameters[CMA_NUM_PARAMS] = {
808  {// very happy
809  .minimal_surplus = {0, 0, 0, -20, 0, 0},
810  .require_happy = false,
811  .allow_disorder = false,
812  .allow_specialists = true,
813  .factor = {10, 5, 0, 4, 0, 4},
814  .happy_factor = 25},
815  {// prefer food
816  .minimal_surplus = {-20, 0, 0, -20, 0, 0},
817  .require_happy = false,
818  .allow_disorder = false,
819  .allow_specialists = true,
820  .factor = {25, 5, 0, 4, 0, 4},
821  .happy_factor = 0},
822  {// prefer prod
823  .minimal_surplus = {0, -20, 0, -20, 0, 0},
824  .require_happy = false,
825  .allow_disorder = false,
826  .allow_specialists = true,
827  .factor = {10, 25, 0, 4, 0, 4},
828  .happy_factor = 0},
829  {// prefer gold
830  .minimal_surplus = {0, 0, 0, -20, 0, 0},
831  .require_happy = false,
832  .allow_disorder = false,
833  .allow_specialists = true,
834  .factor = {10, 5, 0, 25, 0, 4},
835  .happy_factor = 0},
836  {// prefer science
837  .minimal_surplus = {0, 0, 0, -20, 0, 0},
838  .require_happy = false,
839  .allow_disorder = false,
840  .allow_specialists = true,
841  .factor = {10, 5, 0, 4, 0, 25},
842  .happy_factor = 0}};
843  const char *names[CMA_NUM_PARAMS] = {
844  N_("?cma:Very happy"), N_("?cma:Prefer food"),
845  N_("?cma:Prefer production"), N_("?cma:Prefer gold"),
846  N_("?cma:Prefer science")};
847 
848  for (i = CMA_NUM_PARAMS - 1; i >= 0; i--) {
849  cmafec_preset_add(Q_(names[i]), &parameters[i]);
850  }
851 }
size_t attr_city_get(enum attr_city what, int city_id, size_t max_data_length, void *data)
Get city related attribute.
Definition: attribute.cpp:410
void attr_city_set(enum attr_city what, int city_id, size_t data_length, const void *const data)
Set city related attribute.
Definition: attribute.cpp:401
attr_city
Definition: attribute.h:21
@ ATTR_CITY_CMAFE_PARAMETER
Definition: attribute.h:23
@ ATTR_CITY_CMA_PARAMETER
Definition: attribute.h:22
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
Definition: city.cpp:130
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Returns TRUE when a tile is available to be worked, or the city itself is currently working the tile ...
Definition: city.cpp:1392
citizens city_size_get(const struct city *pcity)
Get the city size.
Definition: city.cpp:1101
#define output_type_iterate(output)
Definition: city.h:764
#define city_map_iterate_end
Definition: city.h:148
#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 is_city_center_index(city_tile_index)
Definition: city.h:778
#define city_map_iterate(_radius_sq, _index, _x, _y)
Definition: city.h:144
#define output_type_iterate_end
Definition: city.h:771
int city_change_specialist(struct city *pcity, Specialist_type_id from, Specialist_type_id to)
Change a specialist in the given city.
void refresh_city_dialog(struct city *pcity)
void city_report_dialog_update_city(struct city *pcity)
int last_request
Definition: governor.cpp:90
struct city * xcity
Definition: governor.cpp:91
int get_request()
Definition: governor.cpp:205
void result_came_from_server(int request)
Definition: governor.cpp:217
bool apply_result_on_server(struct city *pcity, std::unique_ptr< cm_result > &&result)
Change the actual city setting to the given result.
Definition: governor.cpp:267
bool is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition: governor.cpp:412
void set_parameter(enum attr_city attr, int city_id, const struct cm_parameter *parameter)
Definition: governor.cpp:476
void put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Definition: governor.cpp:394
std::unique_ptr< cm_result > cma_result_got
Definition: governor.cpp:89
void handle_city(struct city *pcity)
The given city has changed.
Definition: governor.cpp:541
bool get_parameter(enum attr_city attr, int city_id, struct cm_parameter *parameter)
Definition: governor.cpp:427
void release_city(struct city *pcity)
Definition: governor.cpp:405
struct city * check_city(int city_id, struct cm_parameter *parameter)
Returns TRUE if the city is valid for CMA.
Definition: governor.cpp:513
static governor * m_instance
Definition: governor.h:36
void add_city_remove(struct city *pcity)
Definition: governor.cpp:128
int superhot
Definition: governor.h:39
std::set< int > scity_remove
Definition: governor.h:38
void add_city_changed(struct city *pcity)
Definition: governor.cpp:116
std::set< int > scity_changed
Definition: governor.h:37
governor()
Definition: governor.h:34
static governor * i()
Definition: governor.cpp:107
void add_city_new(struct city *pcity)
Definition: governor.cpp:122
void run()
Definition: governor.cpp:135
struct civclient client
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 cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Copy the parameter from the source to the destination field.
Definition: cm.cpp:2163
void cm_init_parameter(struct cm_parameter *dest)
Initialize the parameter to sane default values.
Definition: cm.cpp:2172
void cm_query_result(struct city *pcity, const struct cm_parameter *param, std::unique_ptr< cm_result > &result, bool negative_ok)
Wrapper that actually runs the branch & bound, and returns the best solution.
Definition: cm.cpp:2115
int cm_result_citizens(const std::unique_ptr< cm_result > &result)
Count the total number of citizens in the result.
Definition: cm.cpp:2246
void cm_result_from_main_map(std::unique_ptr< cm_result > &result, const struct city *pcity)
Copy the city's current setup into the cm result structure.
Definition: cm.cpp:2255
std::unique_ptr< cm_result > cm_result_new(struct city *pcity)
Create a new cm_result.
Definition: cm.cpp:330
void cm_print_result(const std::unique_ptr< cm_result > &result)
Print debugging information about a full CM result.
Definition: cm.cpp:2472
void cm_print_city(const struct city *pcity)
Debugging routines.
Definition: cm.cpp:2432
void connection_do_buffer(struct connection *pc)
Turn on buffering, using a counter so that calls may be nested.
Definition: connection.cpp:278
void connection_do_unbuffer(struct connection *pc)
Turn off buffering if internal counter of number of times buffering was turned on falls to zero,...
Definition: connection.cpp:290
void dio_put_bool8_raw(struct raw_data_out *dout, bool value)
Insert value 0 or 1 using 8 bits.
Definition: dataio_raw.cpp:346
void dio_output_init(struct raw_data_out *dout, void *destination, size_t dest_size)
Initializes the output to the given output buffer and the given buffer size.
Definition: dataio_raw.cpp:144
void dio_put_uint8_raw(struct raw_data_out *dout, int value)
Insert value using 8 bits.
Definition: dataio_raw.cpp:229
void dio_put_sint16_raw(struct raw_data_out *dout, int value)
Insert value using 16 bits.
Definition: dataio_raw.cpp:326
bool dio_get_sint16_raw(struct data_in *din, int *dest)
Take value from 16 bits.
Definition: dataio_raw.cpp:671
bool dio_get_uint8_raw(struct data_in *din, int *dest)
Receive uint8 value to dest.
Definition: dataio_raw.cpp:492
bool dio_get_bool8_raw(struct data_in *din, bool *dest)
Take boolean value from 8 bits.
Definition: dataio_raw.cpp:581
size_t dio_output_used(struct raw_data_out *dout)
Return the maximum number of bytes used.
Definition: dataio_raw.cpp:157
void dio_input_init(struct data_in *din, const void *src, size_t src_size)
Initializes the input to the given input buffer and the given number of valid input bytes.
Definition: dataio_raw.cpp:169
#define Q_(String)
Definition: fcintl.h:53
#define _(String)
Definition: fcintl.h:50
#define N_(String)
Definition: fcintl.h:52
const struct ft_color ftc_client
const char * city_link(const struct city *pcity)
Get a text link to a city.
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
#define ALWAYS_APPLY_AT_SERVER
Definition: governor.cpp:44
int refresh_forced
Definition: governor.cpp:62
int cities_results_request()
Definition: governor.cpp:204
const char * cmafec_get_short_descr_of_city(const struct city *pcity)
Return short description of city governor preset.
Definition: governor.cpp:774
#define log_handle_city
Definition: governor.cpp:39
void cmafec_set_fe_parameter(struct city *pcity, const struct cm_parameter *const parameter)
Sets the front-end parameter.
Definition: governor.cpp:663
bool operator==(const struct cm_result &result1, const struct cm_result &result2)
Definition: governor.cpp:161
static struct preset_list * preset_list
Definition: governor.cpp:54
#define CMA_NUM_PARAMS
Definition: governor.cpp:48
int cmafec_preset_num()
Returns the total number of presets.
Definition: governor.cpp:769
#define SAVED_PARAMETER_SIZE
Definition: governor.cpp:46
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Returns the indexed preset's parameter.
Definition: governor.cpp:738
#define log_results_are_equal
Definition: governor.cpp:41
#define log_handle_city2
Definition: governor.cpp:40
void cma_got_result(int citynr)
Definition: governor.cpp:206
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Check whether city is under governor control, and fill parameter if it is.
Definition: governor.cpp:632
void create_default_cma_presets()
Create default cma presets for a new user (or without configuration file)
Definition: governor.cpp:804
int apply_result_ignored
Definition: governor.cpp:62
char * cmafec_preset_get_descr(int idx)
Returns the indexed preset's description.
Definition: governor.cpp:725
void cma_put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Put city under governor control.
Definition: governor.cpp:618
int cmafec_preset_get_index_of_parameter(const struct cm_parameter *const parameter)
Returns the index of the preset which matches the given parameter.
Definition: governor.cpp:752
const char * cmafec_get_short_descr(const struct cm_parameter *const parameter)
Returns the description of the matching preset or "custom" if no preset could be found.
Definition: governor.cpp:790
void cmafec_preset_remove(int idx)
Removes a preset.
Definition: governor.cpp:709
int apply_result_applied
Definition: governor.cpp:62
bool cma_get_parameter(enum attr_city attr, int city_id, struct cm_parameter *parameter)
Get the parameter.
Definition: governor.cpp:645
#define MAX_LEN_PRESET_NAME
Definition: governor.cpp:45
void cma_release_city(struct city *pcity)
Release city from governor control.
Definition: governor.cpp:627
void cma_set_parameter(enum attr_city attr, int city_id, const struct cm_parameter *parameter)
Set attribute block for city from parameter.
Definition: governor.cpp:654
#define log_apply_result
Definition: governor.cpp:38
void cmafec_preset_add(const char *descr_name, const cm_parameter *pparam)
Adds a preset.
Definition: governor.cpp:692
static struct @122 stats
void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
Return the front-end parameter for the given city.
Definition: governor.cpp:673
#define fc_assert_ret(condition)
Definition: log.h:112
#define log_test
Definition: log.h:71
#define fc_assert(condition)
Definition: log.h:89
#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
void update_turn_done_button_state()
Update the turn done button state.
struct nation_type * nation_of_city(const struct city *pcity)
Return the nation of the player who owns the city.
Definition: nation.cpp:429
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
int len
Definition: packhand.cpp:127
struct city * player_city_by_number(const struct player *pplayer, int city_id)
If the specified player owns the city with the specified id, return pointer to the city struct.
Definition: player.cpp:1113
Q_GLOBAL_STATIC(QVector< QString >, future_name_translation)
#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
Definition: city.h:291
int id
Definition: city.h:296
int city_radius_sq
Definition: city.h:346
citizens specialists[SP_MAX]
Definition: city.h:305
struct tile * tile
Definition: city.h:293
struct connection conn
Definition: client_main.h:89
bool allow_disorder
Definition: cm.h:20
int factor[O_LAST]
Definition: cm.h:23
bool max_growth
Definition: cm.h:18
bool allow_specialists
Definition: cm.h:21
bool require_happy
Definition: cm.h:19
int minimal_surplus[O_LAST]
Definition: cm.h:17
int happy_factor
Definition: cm.h:24
Definition: cm.h:35
bool disorder
Definition: cm.h:37
int surplus[O_LAST]
Definition: cm.h:39
bool happy
Definition: cm.h:37
std::vector< bool > worker_positions
Definition: cm.h:42
int city_radius_sq
Definition: cm.h:41
citizens specialists[SP_MAX]
Definition: cm.h:43
struct cm_parameter parameter
Definition: governor.cpp:58
char * descr
Definition: governor.cpp:57
struct player * playing
Definition: connection.h:142
Definition: tile.h:42
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
#define tile_worked(_tile)
Definition: tile.h:97
#define TILE_XY(ptile)
Definition: tile.h:36