Freeciv21
Develop your civilization from humble roots to a global empire
rssanity.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 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 // utility
15 #include "deprecations.h"
16 #include "registry_ini.h"
17 
18 // common
19 #include "achievements.h"
20 #include "actions.h"
21 #include "effects.h"
22 #include "game.h"
23 #include "government.h"
24 #include "movement.h"
25 #include "nation.h"
26 #include "road.h"
27 #include "server_settings.h"
28 #include "specialist.h"
29 #include "style.h"
30 #include "tech.h"
31 
32 // server
33 #include "ruleset.h"
34 #include "settings.h"
35 
36 #include "rssanity.h"
37 
41 static bool sanity_check_metadata()
42 {
43  if (game.ruleset_summary != nullptr
44  && qstrlen(game.ruleset_summary) > MAX_LEN_CONTENT) {
45  qCritical("Too long ruleset summary. It can be only %d bytes long. "
46  "Put longer explanations to ruleset description.",
48  return false;
49  }
50 
51  return true;
52 }
53 
57 static bool nation_has_initial_tech(const nation_type *pnation,
58  struct advance *tech)
59 {
60  int i;
61 
62  // See if it's given as global init tech
63  for (i = 0;
65  i++) {
66  if (game.rgame.global_init_techs[i] == advance_number(tech)) {
67  return true;
68  }
69  }
70 
71  // See if it's given as national init tech
72  for (i = 0; i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
73  i++) {
74  if (pnation->init_techs[i] == advance_number(tech)) {
75  return true;
76  }
77  }
78 
79  return false;
80 }
81 
86 static bool sanity_check_setting_is_seen(struct setting *pset)
87 {
88  return setting_is_visible_at_level(pset, ALLOW_INFO);
89 }
90 
95 static bool sanity_check_setting_is_game_rule(struct setting *pset)
96 {
97  if ((setting_category(pset) == SSET_INTERNAL
98  || setting_category(pset) == SSET_NETWORK)
99  // White list for SSET_INTERNAL and SSET_NETWORK settings.
100  && !(pset == setting_by_name("phasemode")
101  || pset == setting_by_name("timeout")
102  || pset == setting_by_name("timeaddenemymove")
103  || pset == setting_by_name("unitwaittime")
104  || pset == setting_by_name("victories"))) {
105  /* The given server setting is a server operator related setting (like
106  * the compression type of savegames), not a game rule. */
107  return false;
108  }
109 
110  if (pset == setting_by_name("naturalcitynames")) {
111  // This setting is about "look", not rules.
112  return false;
113  }
114 
115  return true;
116 }
117 
123 {
125  struct setting *pset;
126 
127  /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
128  * the server setting id. */
129  id = static_cast<server_setting_id>(ssetval);
131 
132  if (server_setting_type_get(id) != SST_BOOL) {
133  // Not supported yet.
134  return false;
135  }
136 
137  pset = setting_by_number(id);
138 
139  return (sanity_check_setting_is_seen(pset)
141 }
142 
149 static bool sanity_check_req_individual(struct requirement *preq,
150  const char *list_for)
151 {
152  switch (preq->source.kind) {
153  case VUT_IMPROVEMENT:
154  /* This check corresponds to what is_req_active() will support.
155  * It can't be done in req_from_str(), as we may not have
156  * loaded all building information at that time. */
157  {
158  const struct impr_type *pimprove = preq->source.value.building;
159 
160  if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
161  qCritical("%s: World-ranged requirement not supported for "
162  "%s (only great wonders supported)",
163  list_for, improvement_name_translation(pimprove));
164  return false;
165  } else if (preq->range > REQ_RANGE_TRADEROUTE
166  && !is_wonder(pimprove)) {
167  qCritical("%s: %s-ranged requirement not supported for "
168  "%s (only wonders supported)",
169  list_for, req_range_name(preq->range),
170  improvement_name_translation(pimprove));
171  return false;
172  }
173  }
174  break;
175  case VUT_MINCALFRAG:
176  /* Currently [calendar] is loaded after some requirements are
177  * parsed, so we can't do this in universal_value_from_str(). */
178  if (game.calendar.calendar_fragments < 1) {
179  qCritical("%s: MinCalFrag requirement used in ruleset without "
180  "calendar fragments",
181  list_for);
182  return false;
183  } else if (preq->source.value.mincalfrag
184  >= game.calendar.calendar_fragments) {
185  qCritical("%s: MinCalFrag requirement %d out of range (max %d in "
186  "this ruleset)",
187  list_for, preq->source.value.mincalfrag,
188  game.calendar.calendar_fragments - 1);
189  return false;
190  }
191  break;
192  case VUT_SERVERSETTING:
193  /* There is currently no way to check a server setting's category and
194  * access level that works in both the client and the server. */
195  {
197  struct setting *pset;
198 
201  pset = setting_by_number(id);
202 
203  if (!sanity_check_setting_is_seen(pset)) {
204  qCritical("%s: ServerSetting requirement %s isn't visible enough "
205  "to appear in a requirement. Everyone should be able to "
206  "see the value of a server setting that appears in a "
207  "requirement.",
208  list_for, server_setting_name_get(id));
209  return false;
210  }
211 
213  /* This is a server operator related setting (like the compression
214  * type of savegames), not a game rule. */
215  qCritical("%s: ServerSetting requirement setting %s isn't about a "
216  "game rule.",
217  list_for, server_setting_name_get(id));
218  return false;
219  }
220  }
221  break;
222  default:
223  /* No other universals have checks that can't be done at ruleset
224  * load time. See req_from_str(). */
225  break;
226  }
227  return true;
228 }
229 
233 static bool sanity_check_req_set(int reqs_of_type[],
234  int local_reqs_of_type[],
235  struct requirement *preq, bool conjunctive,
236  int max_tiles, const char *list_for)
237 {
238  int rc;
239 
240  fc_assert_ret_val(universals_n_is_valid(preq->source.kind), false);
241 
242  if (!sanity_check_req_individual(preq, list_for)) {
243  return false;
244  }
245 
246  if (!conjunctive) {
247  // All the checks below are only meaningful for conjunctive lists.
248  // FIXME: we could add checks suitable for disjunctive lists.
249  return true;
250  }
251 
252  // Add to counter for positive requirements.
253  if (preq->present) {
254  reqs_of_type[preq->source.kind]++;
255  }
256  rc = reqs_of_type[preq->source.kind];
257 
258  if (preq->range == REQ_RANGE_LOCAL && preq->present) {
259  local_reqs_of_type[preq->source.kind]++;
260 
261  switch (preq->source.kind) {
262  case VUT_TERRAINCLASS:
263  if (local_reqs_of_type[VUT_TERRAIN] > 0) {
264  qCritical("%s: Requirement list has both local terrain and "
265  "terrainclass requirement",
266  list_for);
267  return false;
268  }
269  break;
270  case VUT_TERRAIN:
271  if (local_reqs_of_type[VUT_TERRAINCLASS] > 0) {
272  qCritical("%s: Requirement list has both local terrain and "
273  "terrainclass requirement",
274  list_for);
275  return false;
276  }
277  break;
278  default:
279  break;
280  }
281  }
282 
283  if (rc > 1 && preq->present) {
284  // Multiple requirements of the same type
285  switch (preq->source.kind) {
286  case VUT_GOVERNMENT:
287  case VUT_UTYPE:
288  case VUT_UCLASS:
289  case VUT_ACTION:
290  case VUT_ACTIVITY:
291  case VUT_OTYPE:
292  case VUT_SPECIALIST:
293  case VUT_MINSIZE: // Breaks nothing, but has no sense either
294  case VUT_MINFOREIGNPCT:
295  case VUT_MINMOVES: // Breaks nothing, but has no sense either
296  case VUT_MINVETERAN: // Breaks nothing, but has no sense either
297  case VUT_MINHP: // Breaks nothing, but has no sense either
298  case VUT_MINYEAR:
299  case VUT_MINCALFRAG:
300  case VUT_AI_LEVEL:
301  case VUT_TERRAINALTER: // Local range only
302  case VUT_STYLE:
303  case VUT_IMPR_GENUS:
304  case VUT_CITYSTATUS:
305  case VUT_VISIONLAYER:
306  case VUT_NINTEL:
307  /* There can be only one requirement of these types (with current
308  * range limitations)
309  * Requirements might be identical, but we consider multiple
310  * declarations error anyway. */
311 
312  qCritical("%s: Requirement list has multiple %s requirements",
313  list_for, universal_type_rule_name(&preq->source));
314  return false;
315  break;
316 
317  case VUT_TERRAIN:
318  // There can be only up to max_tiles requirements of these types
319  if (max_tiles != -1 && rc > max_tiles) {
320  qCritical("%s: Requirement list has more %s requirements than "
321  "can ever be fulfilled.",
322  list_for, universal_type_rule_name(&preq->source));
323  return false;
324  }
325  break;
326 
327  case VUT_TERRAINCLASS:
328  if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
329  qCritical("%s: Requirement list has more %s requirements than "
330  "can ever be fulfilled.",
331  list_for, universal_type_rule_name(&preq->source));
332  return false;
333  }
334  break;
335 
336  case VUT_AGE:
337  // There can be age of the city, unit, and player
338  if (rc > 3) {
339  qCritical("%s: Requirement list has more %s requirements than "
340  "can ever be fulfilled.",
341  list_for, universal_type_rule_name(&preq->source));
342  return false;
343  }
344  break;
345 
346  case VUT_MINTECHS:
347  // At ranges 'Player' and 'World'
348  if (rc > 2) {
349  qCritical("%s: Requirement list has more %s requirements than "
350  "can ever be fulfilled.",
351  list_for, universal_type_rule_name(&preq->source));
352  return false;
353  }
354  break;
355 
356  case VUT_SERVERSETTING:
357  // Can have multiple, since there are many settings.
358  case VUT_TOPO:
359  /* Can have multiple, since it's flag based (iso & wrapx & wrapy & hex)
360  */
361  case VUT_EXTRA:
362  /* Note that there can be more than 1 extra / tile. */
363  case VUT_MAXTILEUNITS:
364  /* Can require different numbers on e.g. local/adjacent tiles. */
365  case VUT_NATION:
366  /* Can require multiple nations at Team/Alliance/World range. */
367  case VUT_NATIONGROUP:
368  // Nations can be in multiple groups.
369  case VUT_NONE:
370  case VUT_ADVANCE:
371  case VUT_TECHFLAG:
372  case VUT_IMPROVEMENT:
373  case VUT_UNITSTATE:
374  case VUT_CITYTILE:
375  case VUT_GOOD:
376  // Can check different properties.
377  case VUT_UTFLAG:
378  case VUT_UCFLAG:
379  case VUT_TERRFLAG:
380  case VUT_BASEFLAG:
381  case VUT_ROADFLAG:
382  case VUT_EXTRAFLAG:
383  case VUT_NATIONALITY:
384  case VUT_MINCULTURE:
385  case VUT_ACHIEVEMENT:
386  case VUT_DIPLREL:
387  // Can have multiple requirements of these types
388  break;
389  case VUT_COUNT:
390  // Should never be in requirement vector
391  fc_assert(false);
392  return false;
393  break;
394  /* No default handling here, as we want compiler warning
395  * if new requirement type is added to enum and it's not handled
396  * here. */
397  }
398  }
399 
400  return true;
401 }
402 
419 static bool sanity_check_req_vec(const struct requirement_vector *preqs,
420  bool conjunctive, int max_tiles,
421  const char *list_for)
422 {
423  struct req_vec_problem *problem;
424  int reqs_of_type[VUT_COUNT];
425  int local_reqs_of_type[VUT_COUNT];
426 
427  // Initialize requirement counters
428  memset(reqs_of_type, 0, sizeof(reqs_of_type));
429  memset(local_reqs_of_type, 0, sizeof(local_reqs_of_type));
430 
431  requirement_vector_iterate(preqs, preq)
432  {
433  if (!sanity_check_req_set(reqs_of_type, local_reqs_of_type, preq,
434  conjunctive, max_tiles, list_for)) {
435  return false;
436  }
437  }
439 
440  problem =
442  if (problem != nullptr) {
443  qCritical("%s: %s.", list_for, problem->description);
444  req_vec_problem_free(problem);
445  return false;
446  }
447 
448  return true;
449 }
450 
454 static bool effect_list_sanity_cb(struct effect *peffect, void *data)
455 {
456  int one_tile = -1; /* TODO: Determine correct value from effect.
457  * -1 disables checking */
458 
459  if (peffect->type == EFT_ACTION_SUCCESS_TARGET_MOVE_COST) {
460  // Only unit targets can pay in move fragments.
461  requirement_vector_iterate(&peffect->reqs, preq)
462  {
463  if (preq->source.kind == VUT_ACTION) {
464  if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
465  /* TODO: support for ATK_UNITS could be added. That would require
466  * manually calling action_success_target_pay_mp() in each
467  * supported unit stack targeted action performer (like
468  * action_consequence_success() does) or to have the unit stack
469  * targeted actions return a list of targets. */
470  qCritical("The effect Action_Success_Target_Move_Cost has the"
471  " requirement {%s} but the action %s isn't"
472  " (single) unit targeted.",
473  qUtf8Printable(req_to_fstring(preq)),
474  universal_rule_name(&preq->source));
475  return false;
476  }
477  }
478  }
480  } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
481  // Only unit actors can pay in move fragments.
482  requirement_vector_iterate(&peffect->reqs, preq)
483  {
484  if (preq->source.kind == VUT_ACTION && preq->present) {
485  if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
486  qCritical("The effect Action_Success_Actor_Move_Cost has the"
487  " requirement {%s} but the action %s isn't"
488  " performed by a unit.",
489  qUtf8Printable(req_to_fstring(preq)),
490  universal_rule_name(&preq->source));
491  return false;
492  }
493  }
494  }
496  } else if (peffect->type == EFT_ACTION_ODDS_PCT) {
497  // Catch trying to set Action_Odds_Pct for non supported actions.
498  requirement_vector_iterate(&peffect->reqs, preq)
499  {
500  if (preq->source.kind == VUT_ACTION && preq->present) {
501  if (action_dice_roll_initial_odds(preq->source.value.action)
503  qCritical("The effect Action_Odds_Pct has the"
504  " requirement {%s} but the action %s doesn't"
505  " roll the dice to see if it fails.",
506  qUtf8Printable(req_to_fstring(preq)),
507  universal_rule_name(&preq->source));
508  return false;
509  }
510  }
511  }
513  }
514 
515  return sanity_check_req_vec(&peffect->reqs, true, one_tile,
516  effect_type_name(peffect->type));
517 }
518 
522 static bool rs_barbarian_units()
523 {
524  if (num_role_units(L_BARBARIAN) > 0) {
525  if (num_role_units(L_BARBARIAN_LEADER) == 0) {
526  qCCritical(ruleset_category, "No role barbarian leader units");
527  return false;
528  }
529  if (num_role_units(L_BARBARIAN_BUILD) == 0) {
530  qCCritical(ruleset_category, "No role barbarian build units");
531  return false;
532  }
533  if (num_role_units(L_BARBARIAN_BOAT) == 0) {
534  qCCritical(ruleset_category, "No role barbarian ship units");
535  return false;
536  } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
537  bool sea_capable = false;
538  struct unit_type *u = get_role_unit(L_BARBARIAN_BOAT, 0);
539 
540  terrain_type_iterate(pterr)
541  {
542  if (is_ocean(pterr)
543  && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
544  sea_capable = true;
545  break;
546  }
547  }
549 
550  if (!sea_capable) {
551  qCCritical(ruleset_category,
552  "Barbarian boat (%s) needs to be able to move at sea.",
553  utype_rule_name(u));
554  return false;
555  }
556  }
557  if (num_role_units(L_BARBARIAN_SEA) == 0) {
558  qCCritical(ruleset_category, "No role sea raider barbarian units");
559  return false;
560  }
561 
562  unit_type_iterate(ptype)
563  {
564  if (utype_has_role(ptype, L_BARBARIAN_BOAT)) {
565  if (ptype->transport_capacity <= 1) {
566  qCCritical(ruleset_category,
567  "Barbarian boat %s has no capacity for both "
568  "leader and at least one man.",
569  utype_rule_name(ptype));
570  return false;
571  }
572 
573  unit_type_iterate(pbarb)
574  {
575  if (utype_has_role(pbarb, L_BARBARIAN_SEA)
576  || utype_has_role(pbarb, L_BARBARIAN_SEA_TECH)
577  || utype_has_role(pbarb, L_BARBARIAN_LEADER)) {
578  if (!can_unit_type_transport(ptype, utype_class(pbarb))) {
579  qCCritical(ruleset_category,
580  "Barbarian boat %s cannot transport "
581  "barbarian cargo %s.",
582  utype_rule_name(ptype), utype_rule_name(pbarb));
583  return false;
584  }
585  }
586  }
588  }
589  }
591  }
592 
593  return true;
594 }
595 
599 static bool rs_common_units()
600 {
601  // Check some required flags and roles etc:
602  if (num_role_units(UTYF_SETTLERS) == 0) {
603  qCCritical(ruleset_category, "No flag Settler units");
604  return false;
605  }
606  if (num_role_units(L_START_EXPLORER) == 0) {
607  qCCritical(ruleset_category, "No role Start Explorer units");
608  }
609  if (num_role_units(L_FERRYBOAT) == 0) {
610  qCCritical(ruleset_category, "No role Ferryboat units");
611  }
612  if (num_role_units(L_FIRSTBUILD) == 0) {
613  qCCritical(ruleset_category, "No role Firstbuild units");
614  }
615 
616  if (num_role_units(L_FERRYBOAT) > 0) {
617  bool sea_capable = false;
618  struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
619 
620  terrain_type_iterate(pterr)
621  {
622  if (is_ocean(pterr)
623  && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
624  sea_capable = true;
625  break;
626  }
627  }
629 
630  if (!sea_capable) {
631  qCCritical(ruleset_category,
632  "Ferryboat (%s) needs to be able to move at sea.",
633  utype_rule_name(u));
634  return false;
635  }
636  }
637 
638  if (num_role_units(L_PARTISAN) == 0
639  && effect_cumulative_max(EFT_INSPIRE_PARTISANS, nullptr) > 0) {
640  qCCritical(ruleset_category, "Inspire_Partisans effect present, but no "
641  "units with partisan role.");
642  return false;
643  }
644 
645  return true;
646 }
647 
651 static bool rs_buildings()
652 {
653  // Special Genus
654  improvement_iterate(pimprove)
655  {
656  if (improvement_has_flag(pimprove, IF_GOLD)
657  && pimprove->genus != IG_SPECIAL) {
658  qCCritical(
659  ruleset_category,
660  "Gold producing improvement with genus other than \"Special\"");
661 
662  return false;
663  }
664  if (improvement_has_flag(pimprove, IF_DISASTER_PROOF)
665  && pimprove->genus != IG_IMPROVEMENT) {
666  qCCritical(
667  ruleset_category,
668  "Disasterproof improvement with genus other than \"Improvement\"");
669 
670  return false;
671  }
672  }
674 
675  return true;
676 }
677 
682 {
683  enum effect_type boolean_effects[] = {
684  EFT_ANY_GOVERNMENT, EFT_CAPITAL_CITY, EFT_ENABLE_NUKE,
685  EFT_ENABLE_SPACE, EFT_HAVE_EMBASSIES, EFT_NO_ANARCHY,
686  EFT_NUKE_PROOF, EFT_REVEAL_CITIES, EFT_REVEAL_MAP,
687  EFT_SIZE_UNLIMIT, EFT_SS_STRUCTURAL, EFT_SS_COMPONENT,
688  EFT_NO_UNHAPPY, EFT_RAPTURE_GROW, EFT_HAS_SENATE,
689  EFT_INSPIRE_PARTISANS, EFT_HAPPINESS_TO_GOLD, EFT_FANATICS,
690  EFT_NO_DIPLOMACY, EFT_GOV_CENTER, EFT_NOT_TECH_SOURCE,
691  EFT_VICTORY, EFT_HAVE_CONTACTS, EFT_COUNT};
692  int i;
693  bool ret = true;
694 
695  for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
696  if (effect_cumulative_min(boolean_effects[i], nullptr) < 0
697  && effect_cumulative_max(boolean_effects[i], nullptr) == 0) {
698  qCCritical(ruleset_category,
699  "Boolean effect %s can get disabled, but it can't get "
700  "enabled before that.",
701  effect_type_name(boolean_effects[i]));
702  ret = false;
703  }
704  }
705 
706  return ret;
707 }
708 
716 bool sanity_check_ruleset_data(bool ignore_retired)
717 {
718  int num_utypes;
719  int i;
720  bool ok = true; /* Store failures to variable instead of returning
721  * immediately so all errors get printed, not just first
722  * one. */
723  bool default_gov_failed = false;
724 
725  if (!sanity_check_metadata()) {
726  ok = false;
727  }
728 
729  if (game.info.tech_cost_style == TECH_COST_CIV1CIV2
730  && game.info.free_tech_method == FTM_CHEAPEST) {
731  qCCritical(ruleset_category,
732  "Cost based free tech method, but tech cost style "
733  "1 so all techs cost the same.");
734  ok = false;
735  }
736 
737  // Advances.
738  advance_iterate(A_FIRST, padvance)
739  {
740  for (i = AR_ONE; i < AR_SIZE; i++) {
741  const struct advance *preq;
742 
743  if (i == AR_ROOT) {
744  // Self rootreq is a feature.
745  continue;
746  }
747 
748  preq = advance_requires(padvance, tech_req(i));
749 
750  if (A_NEVER == preq) {
751  continue;
752  } else if (preq == padvance) {
753  qCCritical(ruleset_category, "Tech \"%s\" requires itself.",
754  advance_rule_name(padvance));
755  ok = false;
756  continue;
757  }
758 
759  advance_req_iterate(preq, preqreq)
760  {
761  if (preqreq == padvance) {
762  qCCritical(ruleset_category,
763  "Tech \"%s\" requires itself indirectly via \"%s\".",
764  advance_rule_name(padvance), advance_rule_name(preq));
765  ok = false;
766  }
767  }
769  }
770 
771  requirement_vector_iterate(&(padvance->research_reqs), preq)
772  {
773  if (preq->source.kind == VUT_ADVANCE) {
774  /* Don't allow this even if allowing changing reqs. Players will
775  * expect all tech reqs to appear in the client tech tree. That
776  * should be taken care of first. */
777  qCCritical(ruleset_category,
778  "Tech \"%s\" requires a tech in its research_reqs."
779  " This isn't supported yet. Please keep using req1"
780  " and req2 like before.",
781  advance_rule_name(padvance));
782  ok = false;
783  } else if (!is_req_unchanging(preq)) {
784  /* Only support unchanging requirements until the reachability code
785  * can handle it and the tech tree can display changing
786  * requirements. */
787  qCCritical(ruleset_category,
788  "Tech \"%s\" has the requirement %s in its"
789  " research_reqs. This requirement may change during"
790  " the game. Changing requirements aren't supported"
791  " yet.",
792  advance_rule_name(padvance),
793  qUtf8Printable(req_to_fstring(preq)));
794  ok = false;
795  }
796  }
798 
799  if (padvance->bonus_message != nullptr) {
800  if (!formats_match(padvance->bonus_message, "%s")) {
801  qCCritical(ruleset_category,
802  "Tech \"%s\" bonus message is not format with %%s for "
803  "a bonus tech name.",
804  advance_rule_name(padvance));
805  ok = false;
806  }
807  }
808  }
810 
812  qCCritical(ruleset_category,
813  "The government form %s reserved for revolution handling "
814  "has been set as "
815  "default_government.",
817  ok = false;
818  default_gov_failed = true;
819  }
820 
821  // Check that all players can have their initial techs
822  for (const auto &pnation : nations) {
823  int techi;
824 
825  // Check global initial techs
826  for (techi = 0; techi < MAX_NUM_TECH_LIST
827  && game.rgame.global_init_techs[techi] != A_LAST;
828  techi++) {
830  struct advance *a = valid_advance_by_number(tech);
831 
832  if (a == nullptr) {
833  qCCritical(ruleset_category,
834  "Tech %s does not exist, but is initial "
835  "tech for everyone.",
837  ok = false;
838  } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
839  && !nation_has_initial_tech(&pnation,
840  a->require[AR_ROOT])) {
841  // Nation has no root_req for tech
842  qCCritical(ruleset_category,
843  "Tech %s is initial for everyone, but %s has "
844  "no root_req for it.",
845  advance_rule_name(a), nation_rule_name(&pnation));
846  ok = false;
847  }
848  }
849 
850  // Check national initial techs
851  for (techi = 0;
852  techi < MAX_NUM_TECH_LIST && pnation.init_techs[techi] != A_LAST;
853  techi++) {
854  Tech_type_id tech = pnation.init_techs[techi];
855  struct advance *a = valid_advance_by_number(tech);
856 
857  if (a == nullptr) {
858  qCCritical(ruleset_category,
859  "Tech %s does not exist, but is tech for %s.",
861  nation_rule_name(&pnation));
862  ok = false;
863  } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
864  && !nation_has_initial_tech(&pnation,
865  a->require[AR_ROOT])) {
866  // Nation has no root_req for tech
867  qCCritical(ruleset_category,
868  "Tech %s is initial for %s, but they have "
869  "no root_req for it.",
870  advance_rule_name(a), nation_rule_name(&pnation));
871  ok = false;
872  }
873  }
874 
875  // Check national initial buildings
876  if (nation_barbarian_type(&pnation) != NOT_A_BARBARIAN
877  && pnation.init_buildings[0] != B_LAST) {
878  qCCritical(ruleset_category,
879  "Barbarian nation %s has init_buildings set but will "
880  "never see them",
881  nation_rule_name(&pnation));
882  }
883 
884  if (!default_gov_failed
885  && pnation.init_government == game.government_during_revolution) {
886  qCCritical(ruleset_category,
887  "The government form %s reserved for revolution "
888  "handling has been set as "
889  "initial government for %s.",
891  nation_rule_name(&pnation));
892  ok = false;
893  }
894  }
895 
896  // Check against unit upgrade loops
897  num_utypes = game.control.num_unit_types;
898  unit_type_iterate(putype)
899  {
900  int chain_length = 0;
901  const struct unit_type *upgraded = putype;
902 
903  while (upgraded != nullptr) {
904  upgraded = upgraded->obsoleted_by;
905  chain_length++;
906  if (chain_length > num_utypes) {
907  qCCritical(ruleset_category,
908  "There seems to be obsoleted_by loop in update "
909  "chain that starts from %s",
910  utype_rule_name(putype));
911  ok = false;
912  }
913  }
914  }
916 
917  /* Some unit type properties depend on other unit type properties to work
918  * properly. */
919  unit_type_iterate(putype)
920  {
921  /* "Spy" is a better "Diplomat". Until all the places that assume that
922  * "Diplomat" is set if "Spy" is set is changed this limitation must be
923  * kept. */
924  if (utype_has_flag(putype, UTYF_SPY)
925  && !utype_has_flag(putype, UTYF_DIPLOMAT)) {
926  qCCritical(ruleset_category,
927  "The unit type '%s' has the 'Spy' unit type flag but "
928  "not the 'Diplomat' unit type flag.",
929  utype_rule_name(putype));
930  ok = false;
931  }
932  }
934 
935  // Check that unit type fields are in range.
936  unit_type_iterate(putype)
937  {
938  if (putype->paratroopers_range < 0
939  || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
940  // Paradrop range is limited by the network protocol.
941  qCCritical(ruleset_category,
942  "The paratroopers_range of the unit type '%s' is %d. "
943  "That is out of range. Max range is %d.",
944  utype_rule_name(putype), putype->paratroopers_range,
946  ok = false;
947  }
948  }
950 
951  /* Check requirement sets against conflicting requirements.
952  * Effects use requirement lists */
954  qCCritical(ruleset_category,
955  "Effects have conflicting or invalid requirements!");
956  ok = false;
957  }
958 
960  ok = false;
961  }
962 
963  // Others use requirement vectors
964 
965  // Disasters
967  {
968  if (!sanity_check_req_vec(&pdis->reqs, true, -1,
969  disaster_rule_name(pdis))) {
970  qCCritical(ruleset_category,
971  "Disasters have conflicting or invalid requirements!");
972  ok = false;
973  }
974  }
976 
977  // Goods
978  goods_type_iterate(pgood)
979  {
980  if (!sanity_check_req_vec(&pgood->reqs, true, -1,
981  goods_rule_name(pgood))) {
982  qCCritical(ruleset_category,
983  "Goods have conflicting or invalid requirements!");
984  ok = false;
985  }
986  }
988 
989  // Buildings
990  improvement_iterate(pimprove)
991  {
992  if (!sanity_check_req_vec(&pimprove->reqs, true, -1,
993  improvement_rule_name(pimprove))) {
994  qCCritical(ruleset_category,
995  "Buildings have conflicting or invalid requirements!");
996  ok = false;
997  }
998  if (!sanity_check_req_vec(&pimprove->obsolete_by, false, -1,
999  improvement_rule_name(pimprove))) {
1000  qCCritical(ruleset_category,
1001  "Buildings have conflicting or invalid obsolescence req!");
1002  ok = false;
1003  }
1004  }
1006 
1007  // Governments
1008  for (const auto &pgov : governments) {
1009  if (!sanity_check_req_vec(&pgov.reqs, true, -1,
1010  government_rule_name(&pgov))) {
1011  qCCritical(ruleset_category,
1012  "Governments have conflicting or invalid requirements!");
1013  ok = false;
1014  }
1015  };
1016 
1017  // Specialists
1019  {
1020  struct specialist *psp = specialist_by_number(sp);
1021 
1022  if (!sanity_check_req_vec(&psp->reqs, true, -1,
1023  specialist_rule_name(psp))) {
1024  qCCritical(ruleset_category,
1025  "Specialists have conflicting or invalid requirements!");
1026  ok = false;
1027  }
1028  }
1030 
1031  // Extras
1032  extra_type_iterate(pextra)
1033  {
1034  if (!sanity_check_req_vec(&pextra->reqs, true, -1,
1035  extra_rule_name(pextra))) {
1036  qCCritical(ruleset_category,
1037  "Extras have conflicting or invalid requirements!");
1038  ok = false;
1039  }
1040  if (!sanity_check_req_vec(&pextra->rmreqs, true, -1,
1041  extra_rule_name(pextra))) {
1042  qCCritical(ruleset_category,
1043  "Extras have conflicting or invalid removal requirements!");
1044  ok = false;
1045  }
1046  if ((requirement_vector_size(&pextra->rmreqs) > 0)
1047  && !(pextra->rmcauses
1048  & (ERM_ENTER | ERM_CLEANPOLLUTION | ERM_CLEANFALLOUT
1049  | ERM_PILLAGE))) {
1050  qCWarning(ruleset_category,
1051  "Requirements for extra removal defined but not "
1052  "a valid remove cause!");
1053  }
1054  }
1056 
1057  // Roads
1058  extra_type_by_cause_iterate(EC_ROAD, pextra)
1059  {
1060  struct road_type *proad = extra_road_get(pextra);
1061 
1062  extra_type_list_iterate(proad->integrators, iextra)
1063  {
1064  struct road_type *iroad = extra_road_get(iextra);
1065  int pnbr = road_number(proad);
1066 
1067  if (pnbr != road_number(iroad) && !BV_ISSET(iroad->integrates, pnbr)) {
1068  // We don't support non-symmetric integrator relationships yet.
1069  qCCritical(ruleset_category,
1070  "Road '%s' integrates with '%s' but not vice versa!",
1071  extra_rule_name(pextra), extra_rule_name(iextra));
1072  ok = false;
1073  }
1074  }
1076  }
1078 
1079  // Bases
1080  extra_type_by_cause_iterate(EC_BASE, pextra)
1081  {
1082  int bfi;
1083  struct base_type *pbase = extra_base_get(pextra);
1084 
1085  if (ignore_retired) {
1086  // Base flags haven't been updated yet.
1087  break;
1088  }
1089 
1090  for (bfi = 0; bfi < BF_COUNT; bfi++) {
1091  if (!base_flag_is_retired(base_flag_id(bfi))) {
1092  // Still valid.
1093  continue;
1094  }
1095 
1096  if (BV_ISSET(pbase->flags, bfi)) {
1097  qCCritical(ruleset_category,
1098  "Base %s uses the retired base flag %s!",
1099  extra_name_translation(pextra),
1100  base_flag_id_name(base_flag_id(bfi)));
1101  }
1102  }
1103  }
1105 
1106  // City styles
1107  for (i = 0; i < game.control.styles_count; i++) {
1108  if (!sanity_check_req_vec(&city_styles[i].reqs, true, -1,
1109  city_style_rule_name(i))) {
1110  qCCritical(ruleset_category,
1111  "City styles have conflicting or invalid requirements!");
1112  ok = false;
1113  }
1114  }
1115 
1116  // Actions
1117  action_iterate(act)
1118  {
1119  struct action *paction = action_by_number(act);
1120 
1121  if (paction->min_distance < 0) {
1122  qCCritical(ruleset_category, "Action %s: negative min distance (%d).",
1123  action_id_rule_name(act), paction->min_distance);
1124  ok = false;
1125  }
1126 
1128  qCCritical(ruleset_category,
1129  "Action %s: min distance (%d) larger than "
1130  "any distance on a map can be (%d).",
1131  action_id_rule_name(act), paction->min_distance,
1133  ok = false;
1134  }
1135 
1136  if (paction->max_distance > ACTION_DISTANCE_MAX) {
1137  qCCritical(ruleset_category,
1138  "Action %s: max distance is %d. "
1139  "A map can't be that big.",
1140  action_id_rule_name(act), paction->max_distance);
1141  ok = false;
1142  }
1143 
1144  if (!action_distance_inside_max(paction, paction->min_distance)) {
1145  qCCritical(ruleset_category,
1146  "Action %s: min distance is %d but max distance is %d.",
1147  action_id_rule_name(act), paction->min_distance,
1148  paction->max_distance);
1149  ok = false;
1150  }
1151 
1152  action_iterate(blocker)
1153  {
1154  if (BV_ISSET(paction->blocked_by, blocker)
1155  && action_id_get_target_kind(blocker) == ATK_UNIT
1156  && action_id_get_target_kind(act) != ATK_UNIT) {
1157  /* Can't find an individual unit target to evaluate the blocking
1158  * action against. (A tile may have more than one individual
1159  * unit) */
1160  qCCritical(ruleset_category, "The action %s can't block %s.",
1161  action_id_rule_name(blocker), action_id_rule_name(act));
1162  ok = false;
1163  }
1164  }
1166 
1168  {
1169  if (!sanity_check_req_vec(&(enabler->actor_reqs), true, -1,
1170  "Action Enabler Actor Reqs")
1171  || !sanity_check_req_vec(&(enabler->target_reqs), true, -1,
1172  "Action Enabler Target Reqs")) {
1173  qCCritical(ruleset_category,
1174  "Action enabler for %s has conflicting or invalid "
1175  "requirements!",
1176  action_id_rule_name(act));
1177  ok = false;
1178  }
1179 
1180  if (action_id_get_target_kind(enabler->action) == ATK_SELF) {
1181  // Special test for self targeted actions.
1182 
1183  if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1184  /* Shouldn't have target requirements since the action doesn't
1185  * have a target. */
1186  qCCritical(ruleset_category,
1187  "An action enabler for %s has a target "
1188  "requirement vector. %s doesn't have a target.",
1190  ok = false;
1191  }
1192  }
1193 
1194  requirement_vector_iterate(&(enabler->target_reqs), preq)
1195  {
1196  if (preq->source.kind == VUT_DIPLREL
1197  && preq->range == REQ_RANGE_LOCAL) {
1198  /* A Local DiplRel requirement can be expressed as a requirement
1199  * in actor_reqs. Demand that it is there. This avoids breaking
1200  * code that reasons about actions. */
1201  qCCritical(ruleset_category,
1202  "Action enabler for %s has a local DiplRel "
1203  "requirement %s in target_reqs! Please read the "
1204  "section \"Requirement vector rules\" in "
1205  "doc/README.actions",
1206  action_id_rule_name(act),
1207  qUtf8Printable(req_to_fstring(preq)));
1208  ok = false;
1209  }
1210  }
1212 
1213  if (!ignore_retired) {
1214  /* Support for letting some of the following hard requirements be
1215  * implicit were retired in legacy Freeciv 3.0. Others were retired
1216  * later. Make sure that the opposite of each hard action requirement
1217  * blocks all its action enablers. */
1218 
1219  struct req_vec_problem *problem =
1221 
1222  if (problem != nullptr) {
1223  qCCritical(ruleset_category, "%s", problem->description);
1224  ok = false;
1225  }
1226 
1227  problem = action_enabler_suggest_improvement(enabler);
1228  if (problem != nullptr) {
1229  // There is a potential for improving this enabler.
1230  qCWarning(deprecations_category, "Enabler for action %s: %s",
1231  action_id_rule_name(act), problem->description);
1232  }
1233  }
1234  }
1236  }
1238 
1239  // Auto attack
1240  {
1241  struct action_auto_perf *auto_perf;
1242 
1244 
1245  action_auto_perf_actions_iterate(auto_perf, act_id)
1246  {
1247  struct action *paction = action_by_number(act_id);
1248 
1249  if (!(action_has_result(paction, ACTRES_CAPTURE_UNITS)
1250  || action_has_result(paction, ACTRES_BOMBARD)
1251  || action_has_result(paction, ACTRES_ATTACK))) {
1252  /* Only allow removing and changing the order of old auto
1253  * attack actions for now. Other actions need more testing and
1254  * fixing of issues caused by a worst case action probability of
1255  * 0%. */
1256  qCCritical(ruleset_category,
1257  "auto_attack: %s not supported in"
1258  " attack_actions.",
1259  action_rule_name(paction));
1260  ok = false;
1261  }
1262  }
1264  }
1265 
1266  // There must be basic city style for each nation style to start with
1267  styles_iterate(pstyle)
1268  {
1269  if (basic_city_style_for_style(pstyle) < 0) {
1270  qCCritical(ruleset_category,
1271  "There's no basic city style for nation style %s",
1272  style_rule_name(pstyle));
1273  ok = false;
1274  }
1275  }
1277 
1278  // Music styles
1279  music_styles_iterate(pmus)
1280  {
1281  if (!sanity_check_req_vec(&pmus->reqs, true, -1, "Music Style")) {
1282  qCCritical(ruleset_category,
1283  "Music Styles have conflicting or invalid requirements!");
1284  ok = false;
1285  }
1286  }
1288 
1289  terrain_type_iterate(pterr)
1290  {
1291  if (pterr->animal != nullptr) {
1292  if (!is_native_to_class(utype_class(pterr->animal), pterr, nullptr)) {
1293  qCCritical(ruleset_category,
1294  "%s has %s as animal to appear, but it's not native "
1295  "to the terrain.",
1296  terrain_rule_name(pterr), utype_rule_name(pterr->animal));
1297  ok = false;
1298  }
1299  }
1300  }
1302 
1303  // Check that all unit classes can exist somewhere
1304  unit_class_iterate(pclass)
1305  {
1306  if (!uclass_has_flag(pclass, UCF_BUILD_ANYWHERE)) {
1307  bool can_exist = false;
1308 
1309  terrain_type_iterate(pterr)
1310  {
1311  if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1312  can_exist = true;
1313  break;
1314  }
1315  }
1317 
1318  if (!can_exist) {
1319  extra_type_iterate(pextra)
1320  {
1321  if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1322  && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1323  can_exist = true;
1324  break;
1325  }
1326  }
1328  }
1329 
1330  if (!can_exist) {
1331  qCCritical(ruleset_category, "Unit class %s cannot exist anywhere.",
1332  uclass_rule_name(pclass));
1333  ok = false;
1334  }
1335  }
1336  }
1338 
1339  achievements_iterate(pach)
1340  {
1341  if (!pach->unique && pach->cons_msg == nullptr) {
1342  qCCritical(
1343  ruleset_category,
1344  "Achievement %s has no message for consecutive gainers though "
1345  "it's possible to be gained by multiple players",
1346  achievement_rule_name(pach));
1347  ok = false;
1348  }
1349  }
1351 
1352  if (game.server.ruledit.embedded_nations != nullptr) {
1353  int nati;
1354 
1355  for (nati = 0; nati < game.server.ruledit.embedded_nations_count;
1356  nati++) {
1357  struct nation_type *pnat =
1358  nation_by_rule_name(game.server.ruledit.embedded_nations[nati]);
1359 
1360  if (pnat == nullptr) {
1361  qCCritical(
1362  ruleset_category,
1363  "There's nation %s listed in embedded nations, but there's "
1364  "no such nation.",
1365  game.server.ruledit.embedded_nations[nati]);
1366  ok = false;
1367  }
1368  }
1369  }
1370 
1371  if (ok) {
1372  ok = rs_common_units();
1373  }
1374  if (ok) {
1375  ok = rs_barbarian_units();
1376  }
1377  if (ok) {
1378  ok = rs_buildings();
1379  }
1380 
1381  return ok;
1382 }
1383 
1390 {
1391  bool ok = true;
1392 
1393  extra_type_by_cause_iterate(EC_RESOURCE, pextra)
1394  {
1395  extra_type_by_cause_iterate(EC_RESOURCE, pextra2)
1396  {
1397  if (pextra != pextra2) {
1398  int idx = extra_index(pextra2);
1399 
1400  if (!BV_ISSET(pextra->conflicts, idx)) {
1401  log_debug("Autoconflicting resource %s with %s",
1402  extra_rule_name(pextra), extra_rule_name(pextra2));
1403  BV_SET(pextra->conflicts, extra_index(pextra2));
1404  }
1405  }
1406  }
1408  }
1410 
1411  // Hard coded action blocking.
1412  {
1413  const struct {
1414  const enum action_result blocked;
1415  const enum action_result blocker;
1416  } must_block[] = {
1417  /* Hard code that Help Wonder blocks Recycle Unit. This must be done
1418  * because caravan_shields makes it possible to avoid the
1419  * consequences of choosing to do Recycle Unit rather than having it
1420  * do Help Wonder.
1421  *
1422  * Explanation: Recycle Unit adds 50% of the shields used to produce
1423  * the unit to the production of the city where it is located. Help
1424  * Wonder adds 100%. If a unit that can do Help Wonder is recycled in
1425  * a city and the production later is changed to something that can
1426  * receive help from Help Wonder the remaining 50% of the shields are
1427  * added. This can be done because the city remembers them in
1428  * caravan_shields.
1429  *
1430  * If a unit that can do Help Wonder intentionally is recycled rather
1431  * than making it do Help Wonder its shields will still be
1432  * remembered. The target city that got 50% of the shields can
1433  * therefore get 100% of them by changing its production. This trick
1434  * makes the ability to select Recycle Unit when Help Wonder is legal
1435  * pointless. */
1436  {ACTRES_RECYCLE_UNIT, ACTRES_HELP_WONDER},
1437 
1438  /* Allowing regular disband when ACTION_HELP_WONDER or
1439  * ACTION_RECYCLE_UNIT is legal while ACTION_HELP_WONDER always
1440  * blocks ACTION_RECYCLE_UNIT doesn't work well with the force_*
1441  * semantics. Should move to the ruleset once it has blocked_by
1442  * semantics. */
1443  {ACTRES_DISBAND_UNIT, ACTRES_HELP_WONDER},
1444  {ACTRES_DISBAND_UNIT, ACTRES_RECYCLE_UNIT},
1445 
1446  /* Hard code that the ability to perform a regular attack blocks city
1447  * conquest. Is redundant as long as the requirement that the target
1448  * tile has no units remains hard coded. Kept "just in case" that
1449  * changes. */
1450  {ACTRES_CONQUER_CITY, ACTRES_ATTACK},
1451  };
1452 
1453  int i;
1454 
1455  for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1456  enum action_result blocked_result = must_block[i].blocked;
1457  enum action_result blocker_result = must_block[i].blocker;
1458 
1459  action_by_result_iterate(blocked, blocker_id, blocked_result)
1460  {
1461  action_by_result_iterate(blocker, blocked_id, blocker_result)
1462  {
1463  if (!action_would_be_blocked_by(blocked, blocker)) {
1464  qCDebug(ruleset_category, "Autoblocking %s with %s",
1465  action_rule_name(blocked), action_rule_name(blocker));
1466  BV_SET(blocked->blocked_by, blocker->id);
1467  }
1468  }
1470  }
1472  }
1473  }
1474 
1475  return ok;
1476 }
1477 
1482 {
1483  bool ok = true;
1484 
1485  if (num_role_units(L_BARBARIAN) == 0) {
1486  struct setting *pset = setting_by_name("barbarians");
1487 
1488  qCInfo(ruleset_category,
1489  ("Disabling 'barbarians' setting for lack of suitable "
1490  "unit types."));
1491  setting_lock_set(pset, false);
1492  if (!setting_enum_set(pset, "DISABLED", nullptr, nullptr, 0)) {
1493  ok = false;
1494  }
1495  setting_lock_set(pset, true);
1496  }
1497 
1498  return ok;
1499 }
const char * achievement_rule_name(struct achievement *pach)
Return untranslated name of this achievement type.
#define achievements_iterate_end
Definition: achievements.h:64
#define achievements_iterate(_ach_)
Definition: achievements.h:58
bool action_distance_inside_max(const struct action *action, const int distance)
Returns TRUE iff the specified distance between actor and target is sm,aller or equal to the max rang...
Definition: actions.cpp:1303
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Get the actor kind of an action.
Definition: actions.cpp:1188
const char * action_rule_name(const struct action *action)
Get the rule name of the action.
Definition: actions.cpp:1343
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Returns a suggestion to fix the specified action enabler or nullptr if no fix is found to be needed.
Definition: actions.cpp:2187
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Returns TRUE iff blocked will be illegal if blocker is legal.
Definition: actions.cpp:1326
int action_dice_roll_initial_odds(const struct action *paction)
Returns the initial odds of an action not failing its dice roll.
Definition: actions.cpp:5580
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Returns a suggestion to improve the specified action enabler or nullptr if nothing to improve is foun...
Definition: actions.cpp:2251
enum action_target_kind action_get_target_kind(const struct action *paction)
Get the target kind of an action.
Definition: actions.cpp:1198
bool action_has_result(const struct action *paction, enum action_result result)
Returns TRUE iff performing the specified action has the specified result.
Definition: actions.cpp:1248
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
const char * action_id_rule_name(action_id act_id)
Get the rule name of the action.
Definition: actions.cpp:1362
struct action_enabler_list * action_enablers_for_action(action_id action)
Get all enablers for an action in the current ruleset.
Definition: actions.cpp:1884
#define ACTION_DISTANCE_MAX
Definition: actions.h:281
#define ACTION_AUTO_MOVED_ADJ
Definition: actions.h:504
#define action_auto_perf_actions_iterate_end
Definition: actions.h:497
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition: actions.h:277
#define action_enabler_list_iterate_end
Definition: actions.h:376
#define action_by_result_iterate_end
Definition: actions.h:396
#define action_by_result_iterate(_paction_, _act_id_, _result_)
Definition: actions.h:387
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition: actions.h:494
#define action_iterate_end
Definition: actions.h:383
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition: actions.h:374
#define action_iterate(_act_)
Definition: actions.h:378
#define action_id_get_target_kind(act_id)
Definition: actions.h:522
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition: actions.h:739
bool base_flag_is_retired(enum base_flag_id flag)
Returns TRUE iff the given flag is retired.
Definition: base.cpp:78
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
struct citystyle * city_styles
Definition: city.cpp:78
const char * city_style_rule_name(const int style)
Return the (untranslated) rule name of the city style.
Definition: city.cpp:1651
#define MAX_LEN_CONTENT
Definition: connection.h:45
const char * disaster_rule_name(struct disaster_type *pdis)
Return untranslated name of this disaster type.
Definition: disaster.cpp:91
#define disaster_type_iterate(_p)
Definition: disaster.h:70
#define disaster_type_iterate_end
Definition: disaster.h:76
struct @19::@20 reqs
bool iterate_effect_cache(iec_cb cb, void *data)
Iterate through all the effects in cache, and call callback for each.
Definition: effects.cpp:1259
int effect_cumulative_max(enum effect_type type, struct universal *for_uni)
Get the maximum effect value in this ruleset for the universal (that is, the sum of all positive effe...
Definition: effects.cpp:307
int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
Get the minimum effect value in this ruleset for the universal (that is, the sum of all negative effe...
Definition: effects.cpp:336
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Check if extra has given flag.
Definition: extras.cpp:779
const char * extra_name_translation(const struct extra_type *pextra)
Return the (translated) name of the extra type.
Definition: extras.cpp:165
const char * extra_rule_name(const struct extra_type *pextra)
Return the (untranslated) rule name of the extra type.
Definition: extras.cpp:174
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_list_iterate(extralist, pextra)
Definition: extras.h:145
#define extra_type_iterate_end
Definition: extras.h:285
#define extra_index(_e_)
Definition: extras.h:163
#define extra_type_list_iterate_end
Definition: extras.h:147
#define extra_base_get(_e_)
Definition: extras.h:170
#define extra_road_get(_e_)
Definition: extras.h:171
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
int server_setting_id
Definition: fc_types.h:893
int Tech_type_id
Definition: fc_types.h:294
int ssetv
Definition: fc_types.h:560
#define MAX_NUM_TECH_LIST
Definition: fc_types.h:36
struct civ_game game
Definition: game.cpp:47
const char * government_rule_name(const struct government *pgovern)
Return the (untranslated) rule name of the government.
Definition: government.cpp:126
std::vector< government > governments
Definition: government.cpp:28
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
bool is_wonder(const struct impr_type *pimprove)
Returns whether improvement is some kind of wonder.
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Return TRUE if the impr has this flag otherwise FALSE.
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
#define B_LAST
Definition: improvement.h:33
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_debug(message,...)
Definition: log.h:65
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
This terrain is native to unit class.
Definition: movement.cpp:290
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Return TRUE iff transporter type has ability to transport transported class.
Definition: movement.cpp:698
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
std::vector< nation_type > nations
Definition: nation.cpp:38
struct nation_type * nation_by_rule_name(const char *name)
Returns the nation that has the given (untranslated) rule name (adjective).
Definition: nation.cpp:98
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Returns which kind of barbarians can use this nation.
Definition: nation.cpp:188
req_vec_num_in_item req_vec_vector_number(const void *parent_item, const struct requirement_vector *vec)
Returns the requirement vector number of the specified requirement vector in the specified requiremen...
bool is_req_unchanging(const struct requirement *req)
Return TRUE if this is an "unchanging" requirement.
struct req_vec_problem * req_vec_get_first_contradiction(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Returns the first self contradiction found in the specified requirement vector with suggested solutio...
const char * universal_type_rule_name(const struct universal *psource)
Return untranslated name of the universal source name.
QString req_to_fstring(const struct requirement *req)
Returns the given requirement as a formatted string ready for printing.
void req_vec_problem_free(struct req_vec_problem *issue)
De-allocates resources associated with the given requirement vector problem.
const char * universal_rule_name(const struct universal *psource)
Return the (untranslated) rule name of the universal.
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
Road_type_id road_number(const struct road_type *proad)
Return the road id.
Definition: road.cpp:23
static bool sanity_check_req_vec(const struct requirement_vector *preqs, bool conjunctive, int max_tiles, const char *list_for)
Sanity check requirement vector, including whether it's free of conflicting requirements.
Definition: rssanity.cpp:419
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Returns TRUE iff the given server setting and value combination is allowed to appear in ServerSetting...
Definition: rssanity.cpp:122
static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], struct requirement *preq, bool conjunctive, int max_tiles, const char *list_for)
Helper function for sanity_check_req_list() and sanity_check_req_vec()
Definition: rssanity.cpp:233
static bool sanity_check_setting_is_seen(struct setting *pset)
Returns TRUE iff the given server setting is visible enough to be allowed to appear in ServerSetting ...
Definition: rssanity.cpp:86
bool sanity_check_ruleset_data(bool ignore_retired)
Some more sanity checking once all rulesets are loaded.
Definition: rssanity.cpp:716
static bool nation_has_initial_tech(const nation_type *pnation, struct advance *tech)
Does nation have tech initially?
Definition: rssanity.cpp:57
static bool sanity_check_req_individual(struct requirement *preq, const char *list_for)
Sanity checks on a requirement in isolation.
Definition: rssanity.cpp:149
static bool rs_common_units()
Sanity check common unit types.
Definition: rssanity.cpp:599
bool autoadjust_ruleset_data()
Apply some automatic defaults to already loaded rulesets.
Definition: rssanity.cpp:1389
bool autolock_settings()
Set and lock settings that must have certain value.
Definition: rssanity.cpp:1481
static bool sanity_check_metadata()
Is non-rule data in ruleset sane?
Definition: rssanity.cpp:41
static bool rs_buildings()
Sanity check buildings.
Definition: rssanity.cpp:651
static bool sanity_check_boolean_effects()
Check that boolean effect types have sensible effects.
Definition: rssanity.cpp:681
static bool rs_barbarian_units()
Sanity check barbarian unit types.
Definition: rssanity.cpp:522
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Sanity check callback for iterating effects cache.
Definition: rssanity.cpp:454
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Returns TRUE iff the specified server setting is a game rule and therefore may appear in a requiremen...
Definition: rssanity.cpp:95
enum sset_type server_setting_type_get(server_setting_id id)
Returns the type of the server setting with the specified id.
server_setting_id ssetv_setting_get(ssetv enc)
Returns the server setting of the setting - value pair.
bool server_setting_exists(server_setting_id id)
Returns TRUE iff a server setting with the specified id exists.
const char * server_setting_name_get(server_setting_id id)
Returns the name of the server setting with the specified id.
enum sset_category setting_category(const struct setting *pset)
Access function for the setting category.
Definition: settings.cpp:3108
struct setting * setting_by_number(int id)
Returns the setting to the given id.
Definition: settings.cpp:3031
void setting_lock_set(struct setting *pset, bool lock)
Set the value for the lock of a setting.
Definition: settings.cpp:4288
struct setting * setting_by_name(const char *name)
Returns the setting to the given name.
Definition: settings.cpp:3039
bool setting_enum_set(struct setting *pset, const char *val, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Set the setting to 'val'.
Definition: settings.cpp:3720
bool setting_is_visible_at_level(const struct setting *pset, enum cmdlevel plevel)
Returns whether the specified server setting (option) can be seen by a caller with the specified acce...
Definition: settings.cpp:3217
bool formats_match(const char *format1, const char *format2)
Returns TRUE iff both formats are compatible (if 'format1' can be used instead 'format2' and reciproc...
Definition: shared.cpp:1621
#define ARRAY_SIZE(x)
Definition: shared.h:79
const char * specialist_rule_name(const struct specialist *sp)
Return the (untranslated) rule name of the specialist type.
Definition: specialist.cpp:142
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
int max_distance
Definition: actions.h:320
bv_actions blocked_by
Definition: actions.h:331
int min_distance
Definition: actions.h:320
Definition: tech.h:113
struct advance * require[AR_SIZE]
Definition: tech.h:120
Definition: base.h:43
bv_base_flags flags
Definition: base.h:51
struct civ_game::@28::@32 server
struct packet_ruleset_control control
Definition: game.h:74
char * ruleset_summary
Definition: game.h:75
int global_init_techs[MAX_NUM_TECH_LIST]
Definition: game.h:98
struct packet_game_info info
Definition: game.h:80
struct civ_game::@27 rgame
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
struct requirement_vector reqs
Definition: effects.h:340
enum effect_type type
Definition: effects.h:328
int init_techs[MAX_NUM_TECH_LIST]
Definition: nation.h:101
char description[500]
Definition: requirements.h:200
enum req_range range
Definition: requirements.h:69
struct universal source
Definition: requirements.h:68
Definition: road.h:54
struct extra_type_list * integrators
Definition: road.h:72
bv_roads integrates
Definition: road.h:66
struct requirement_vector reqs
Definition: specialist.h:32
const struct unit_type * obsoleted_by
Definition: unittype.h:494
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
const char * style_rule_name(const struct nation_style *pstyle)
Return the (untranslated) rule name of the style.
Definition: style.cpp:94
int basic_city_style_for_style(struct nation_style *pstyle)
Return basic city style representing nation style.
Definition: style.cpp:197
#define music_styles_iterate(_p)
Definition: style.h:68
#define music_styles_iterate_end
Definition: style.h:75
#define styles_iterate(_p)
Definition: style.h:40
#define styles_iterate_end
Definition: style.h:46
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Accessor for requirements.
Definition: tech.cpp:122
const char * advance_rule_name(const struct advance *padvance)
Return the (untranslated) rule name of the advance/technology.
Definition: tech.cpp:283
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
Definition: tech.cpp:94
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:154
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:85
#define A_NEVER
Definition: tech.h:44
#define advance_req_iterate(_goal, _padvance)
Definition: tech.h:262
tech_req
Definition: tech.h:104
@ AR_ROOT
Definition: tech.h:104
@ AR_ONE
Definition: tech.h:104
@ AR_SIZE
Definition: tech.h:104
#define advance_iterate(_start, _p)
Definition: tech.h:232
#define advance_req_iterate_end
Definition: tech.h:266
#define A_FIRST
Definition: tech.h:37
#define A_NONE
Definition: tech.h:36
#define advance_iterate_end
Definition: tech.h:238
#define A_LAST
Definition: tech.h:38
const char * terrain_rule_name(const struct terrain *pterrain)
Return the (untranslated) rule name of the terrain.
Definition: terrain.cpp:184
#define terrain_type_iterate(_p)
Definition: terrain.h:331
#define is_ocean(pterrain)
Definition: terrain.h:276
#define terrain_type_iterate_end
Definition: terrain.h:337
const char * goods_rule_name(struct goods_type *pgood)
Return untranslated name of this goods type.
#define goods_type_iterate_end
Definition: traderoutes.h:224
#define goods_type_iterate(_p)
Definition: traderoutes.h:218
int mincalfrag
Definition: fc_types.h:602
const struct impr_type * building
Definition: fc_types.h:579
ssetv ssetval
Definition: fc_types.h:626
const char * utype_rule_name(const struct unit_type *punittype)
Return the (untranslated) rule name of the unit type.
Definition: unittype.cpp:1274
bool utype_has_role(const struct unit_type *punittype, int role)
Return whether the given unit type has the role.
Definition: unittype.cpp:186
int num_role_units(int role)
How many unit types have specified role/flag.
Definition: unittype.cpp:1866
struct unit_type * get_role_unit(int role, int role_index)
Return index-th unit with specified role/flag.
Definition: unittype.cpp:1900
const char * uclass_rule_name(const struct unit_class *pclass)
Return the (untranslated) rule name of the unit class.
Definition: unittype.cpp:1333
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition: unittype.h:704
#define utype_class(_t_)
Definition: unittype.h:691
#define unit_class_iterate(_p)
Definition: unittype.h:823
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define UNIT_MAX_PARADROP_RANGE
Definition: unittype.h:45
#define uclass_index(_c_)
Definition: unittype.h:684
#define unit_class_iterate_end
Definition: unittype.h:829
#define unit_type_iterate_end
Definition: unittype.h:791