Freeciv-3.2
Loading...
Searching...
No Matches
rssanity.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "astring.h"
20#include "deprecations.h"
21
22/* common */
23#include "achievements.h"
24#include "actions.h"
25#include "effects.h"
26#include "game.h"
27#include "government.h"
28#include "map.h"
29#include "movement.h"
30#include "nation.h"
31#include "player.h"
32#include "specialist.h"
33#include "tech.h"
34
35/* server */
36#include "ruleset.h"
37#include "settings.h"
38
39#include "rssanity.h"
40
41/* These effects are always needed in the ruleset.
42 * First set are those that are mandatory even in compatibility mode. */
43enum effect_type req_base_effects[] =
44 {
47 };
48
49/* These have been made mandatory in freeciv-3.2 */
50enum effect_type req_base_effects_3_2[] =
51 {
54 };
55
56/**********************************************************************/
60{
63 ruleset_error(logger,
64 LOG_ERROR, "Too long ruleset summary. It can be only %d bytes long. "
65 "Put longer explanations to ruleset description.",
67 return FALSE;
68 }
69
70 return TRUE;
71}
72
73/**********************************************************************/
76static bool nation_has_initial_tech(struct nation_type *pnation,
77 struct advance *tech)
78{
79 int i;
80
81 /* See if it's given as global init tech */
82 for (i = 0; i < MAX_NUM_TECH_LIST
85 return TRUE;
86 }
87 }
88
89 /* See if it's given as national init tech */
90 for (i = 0;
91 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
92 i++) {
93 if (pnation->init_techs[i] == advance_number(tech)) {
94 return TRUE;
95 }
96 }
97
98 return FALSE;
99}
100
101/**********************************************************************/
109
110/**********************************************************************/
115{
118 /* White list for SSET_INTERNAL and SSET_NETWORK settings. */
119 && !(pset == setting_by_name("phasemode")
120 || pset == setting_by_name("timeout")
121 || pset == setting_by_name("timeaddenemymove")
122 || pset == setting_by_name("unitwaittime")
123 || pset == setting_by_name("victories"))) {
124 /* The given server setting is a server operator related setting (like
125 * the compression type of savegames), not a game rule. */
126 return FALSE;
127 }
128
129 if (pset == setting_by_name("naturalcitynames")) {
130 /* This setting is about "look", not rules. */
131 return FALSE;
132 }
133
134 return TRUE;
135}
136
137/**********************************************************************/
142{
144 struct setting *pset;
145
146 /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
147 * the server setting id. */
148 id = (server_setting_id)ssetval;
150
152 /* Not supported yet. */
153 return FALSE;
154 }
155
157
160}
161
162/**********************************************************************/
169 struct requirement *preq,
170 const char *list_for)
171{
172 switch (preq->source.kind) {
173 case VUT_IMPROVEMENT:
174 /* This check corresponds to what is_req_active() will support.
175 * It can't be done in req_from_str(), as we may not have
176 * loaded all building information at that time. */
177 {
178 const struct impr_type *pimprove = preq->source.value.building;
179
180 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
181 ruleset_error(logger, LOG_ERROR,
182 "%s: World-ranged requirement not supported for "
183 "%s (only great wonders supported)", list_for,
185 return FALSE;
186 } else if (preq->range > REQ_RANGE_TRADE_ROUTE && !is_wonder(pimprove)) {
187 ruleset_error(logger, LOG_ERROR,
188 "%s: %s-ranged requirement not supported for "
189 "%s (only wonders supported)", list_for,
190 req_range_name(preq->range),
192 return FALSE;
193 }
194 }
195 break;
196 case VUT_MINCALFRAG:
197 /* Currently [calendar] is loaded after some requirements are
198 * parsed, so we can't do this in universal_value_from_str(). */
200 ruleset_error(logger, LOG_ERROR,
201 "%s: MinCalFrag requirement used in ruleset without "
202 "calendar fragments", list_for);
203 return FALSE;
204 } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) {
205 ruleset_error(logger, LOG_ERROR,
206 "%s: MinCalFrag requirement %d out of range (max %d in "
207 "this ruleset)", list_for, preq->source.value.mincalfrag,
209 return FALSE;
210 }
211 break;
213 /* There is currently no way to check a server setting's category and
214 * access level that works in both the client and the server. */
215 {
217 struct setting *pset;
218
219 id = ssetv_setting_get(preq->source.value.ssetval);
222
224 ruleset_error(logger, LOG_ERROR,
225 "%s: ServerSetting requirement %s isn't visible enough "
226 "to appear in a requirement. Everyone should be able to "
227 "see the value of a server setting that appears in a "
228 "requirement.", list_for, server_setting_name_get(id));
229 return FALSE;
230 }
231
233 /* This is a server operator related setting (like the compression
234 * type of savegames), not a game rule. */
235 ruleset_error(logger, LOG_ERROR,
236 "%s: ServerSetting requirement setting %s isn't about a "
237 "game rule.",
239 return FALSE;
240 }
241 }
242 break;
243 default:
244 /* No other universals have checks that can't be done at ruleset
245 * load time. See req_from_str(). */
246 break;
247 }
248 return TRUE;
249}
250
251/**********************************************************************/
255 int reqs_of_type[],
256 int local_reqs_of_type[],
257 int tile_reqs_of_type[],
258 struct requirement *preq, bool conjunctive,
259 int max_tiles, const char *list_for)
260{
261 int rc;
262
264
266 return FALSE;
267 }
268
269 if (!conjunctive) {
270 /* All the checks below are only meaningful for conjunctive lists. */
271 /* FIXME: we could add checks suitable for disjunctive lists. */
272 return TRUE;
273 }
274
275 /* Add to counter for positive requirements. */
276 if (preq->present) {
277 reqs_of_type[preq->source.kind]++;
278 }
279 rc = reqs_of_type[preq->source.kind];
280
281 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
282 local_reqs_of_type[preq->source.kind]++;
283
284 switch (preq->source.kind) {
285 case VUT_EXTRA:
286 if (local_reqs_of_type[VUT_EXTRA] > 1) {
287 ruleset_error(logger, LOG_ERROR,
288 "%s: Requirement list has multiple local-ranged extra "
289 "requirements (did you mean to make them tile-ranged?)",
290 list_for);
291 return FALSE;
292 }
293 break;
294 default:
295 break;
296 }
297 }
298
299 if (preq->range == REQ_RANGE_TILE && preq->present) {
300 tile_reqs_of_type[preq->source.kind]++;
301
302 switch (preq->source.kind) {
303 case VUT_TERRAINCLASS:
305 ruleset_error(logger, LOG_ERROR,
306 "%s: Requirement list has both tile terrain and terrainclass requirement",
307 list_for);
308 return FALSE;
309 }
310 break;
311 case VUT_TERRAIN:
313 ruleset_error(logger, LOG_ERROR,
314 "%s: Requirement list has both tile terrain and terrainclass requirement",
315 list_for);
316 return FALSE;
317 }
318 break;
319 case VUT_MINLATITUDE:
320 case VUT_MAXLATITUDE:
321 if (tile_reqs_of_type[preq->range] > 1) {
322 ruleset_error(logger, LOG_ERROR,
323 "%s: Requirement list has duplicate %s requirement at Tile range",
325 return FALSE;
326 }
327 break;
328 default:
329 break;
330 }
331 }
332
333 if (rc > 1 && preq->present) {
334 /* Multiple requirements of the same type */
335 switch (preq->source.kind) {
336 case VUT_GOVERNMENT:
337 case VUT_UTYPE:
338 case VUT_UCLASS:
339 case VUT_ACTION:
340 case VUT_ACTIVITY:
341 case VUT_OTYPE:
342 case VUT_SPECIALIST:
343 case VUT_MINSIZE: /* Breaks nothing, but has no sense either */
345 case VUT_MINMOVES: /* Breaks nothing, but has no sense either */
346 case VUT_MINVETERAN: /* Breaks nothing, but has no sense either */
347 case VUT_MINHP: /* Breaks nothing, but has no sense either */
348 case VUT_MINYEAR:
349 case VUT_MINCALFRAG:
350 case VUT_AI_LEVEL:
351 case VUT_TERRAINALTER: /* Local range only */
352 case VUT_STYLE:
353 case VUT_IMPR_GENUS:
354 case VUT_ORIGINAL_OWNER: /* City range -> only one original owner */
355 case VUT_FORM_AGE:
356 /* There can be only one requirement of these types (with current
357 * range limitations)
358 * Requirements might be identical, but we consider multiple
359 * declarations error anyway. */
360
361 ruleset_error(logger, LOG_ERROR,
362 "%s: Requirement list has multiple %s requirements",
364 return FALSE;
365 break;
366
367 case VUT_TERRAIN:
368 /* There can be only up to max_tiles requirements of these types */
369 if (max_tiles != -1 && rc > max_tiles) {
370 ruleset_error(logger, LOG_ERROR,
371 "%s: Requirement list has more %s requirements than "
372 "can ever be fulfilled.", list_for,
374 return FALSE;
375 }
376 break;
377
378 case VUT_TERRAINCLASS:
379 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
380 ruleset_error(logger, LOG_ERROR,
381 "%s: Requirement list has more %s requirements than "
382 "can ever be fulfilled.", list_for,
384 return FALSE;
385 }
386 break;
387
388 case VUT_AGE:
389 /* There can be age of the city, unit, and player */
390 if (rc > 3) {
391 ruleset_error(logger, LOG_ERROR,
392 "%s: Requirement list has more %s requirements than "
393 "can ever be fulfilled.", list_for,
395 return FALSE;
396 }
397 break;
398
399 case VUT_MINTECHS:
400 /* At ranges 'Player' and 'World' */
401 if (rc > 2) {
402 ruleset_error(logger, LOG_ERROR,
403 "%s: Requirement list has more %s requirements than "
404 "can ever be fulfilled.", list_for,
406 return FALSE;
407 }
408 break;
409
410 case VUT_COUNTER:
411 /* Can have multiple, since many counters (also of the same range)
412 * can meet checkpoint */
414 /* Can have multiple, since there are many settings. */
415 case VUT_TOPO:
416 /* Can have multiple, since it's flag based (iso & hex) */
417 case VUT_WRAP:
418 /* Can have multiple, since it's flag based (wrapx & wrapy) */
419 case VUT_EXTRA:
420 /* Note that there can be more than 1 extra / tile. */
421 case VUT_MAXTILEUNITS:
422 /* Can require different numbers on e.g. local/adjacent tiles. */
423 case VUT_NATION:
424 /* Can require multiple nations at Team/Alliance/World range. */
425 case VUT_NATIONGROUP:
426 /* Nations can be in multiple groups. */
427 case VUT_NONE:
428 case VUT_ADVANCE:
429 case VUT_TECHFLAG:
430 case VUT_IMPROVEMENT:
431 case VUT_UNITSTATE:
432 case VUT_CITYTILE:
433 case VUT_GOOD:
434 /* Can check different properties. */
435 case VUT_UTFLAG:
436 case VUT_UCFLAG:
437 case VUT_TERRFLAG:
438 case VUT_ROADFLAG:
439 case VUT_EXTRAFLAG:
440 case VUT_IMPR_FLAG:
441 case VUT_PLAYER_FLAG:
442 case VUT_PLAYER_STATE:
443 case VUT_NATIONALITY:
444 case VUT_MINCULTURE:
445 case VUT_ACHIEVEMENT:
446 case VUT_DIPLREL:
447 case VUT_DIPLREL_TILE:
451 /* Can have multiple requirements of these types */
452 case VUT_MINLATITUDE:
453 case VUT_MAXLATITUDE:
454 /* Can have multiple requirements at different ranges.
455 * TODO: Compare to number of legal ranges? */
456 break;
457 case VUT_CITYSTATUS:
458 /* Could check "CITYS_LAST * number of ranges" ? */
459 break;
460 case VUT_COUNT:
461 /* Should never be in requirement vector */
463 return FALSE;
464 break;
465 /* No default handling here, as we want compiler warning
466 * if new requirement type is added to enum and it's not handled
467 * here. */
468 }
469 }
470
471 return TRUE;
472}
473
474/**********************************************************************/
491 const struct requirement_vector *preqs,
492 bool conjunctive, int max_tiles,
493 const char *list_for)
494{
495 struct req_vec_problem *problem;
499
500 /* Initialize requirement counters */
501 memset(reqs_of_type, 0, sizeof(reqs_of_type));
503
508 return FALSE;
509 }
511
513 if (problem != NULL) {
514 ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description);
516 return FALSE;
517 }
518
519 return TRUE;
520}
521
522typedef struct {
523 struct {
524 bool effect_present[EFT_COUNT];
525 } base_effects;
527} els_data;
528
529/**********************************************************************/
532static bool effect_list_sanity_cb(struct effect *peffect, void *data)
533{
534 int one_tile = -1; /* TODO: Determine correct value from effect.
535 * -1 disables checking */
536 els_data *els = (els_data *)data;
537 struct astring astr;
538 int i;
539
540 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
541 if (peffect->type == req_base_effects[i]) {
542 els->base_effects.effect_present[peffect->type] = TRUE;
543 break;
544 }
545 }
546 for (i = 0; req_base_effects_3_2[i] != EFT_COUNT; i++) {
547 if (peffect->type == req_base_effects_3_2[i]) {
548 els->base_effects.effect_present[peffect->type] = TRUE;
549 break;
550 }
551 }
552
554 /* Only unit targets can pay in move fragments. */
556 if (preq->source.kind == VUT_ACTION) {
557 if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
558 /* TODO: support for ATK_UNITS could be added. That would require
559 * manually calling action_success_target_pay_mp() in each
560 * supported unit stack targeted action performer (like
561 * action_consequence_success() does) or to have the unit stack
562 * targeted actions return a list of targets. */
563 ruleset_error(els->logger, LOG_ERROR,
564 "The effect Action_Success_Target_Move_Cost has the"
565 " requirement {%s} but the action %s isn't"
566 " (single) unit targeted.",
568 universal_rule_name(&preq->source));
569 astr_free(&astr);
570 return FALSE;
571 }
572 }
574 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
575 /* Only unit actors can pay in move fragments. */
577 if (preq->source.kind == VUT_ACTION && preq->present) {
578 if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
579 ruleset_error(els->logger, LOG_ERROR,
580 "The effect Action_Success_Actor_Move_Cost has the"
581 " requirement {%s} but the action %s isn't"
582 " performed by a unit.",
584 universal_rule_name(&preq->source));
585 astr_free(&astr);
586 return FALSE;
587 }
588 }
590 } else if (peffect->type == EFT_ACTION_ODDS_PCT
591 || peffect->type == EFT_ACTION_RESIST_PCT) {
592 /* Catch trying to set Action_Odds_Pct for non supported actions. */
594 if (preq->source.kind == VUT_ACTION && preq->present) {
595 if (action_dice_roll_initial_odds(preq->source.value.action)
597 ruleset_error(els->logger, LOG_ERROR,
598 "The effect %s has the"
599 " requirement {%s} but the action %s doesn't"
600 " roll the dice to see if it fails.",
603 universal_rule_name(&preq->source));
604 astr_free(&astr);
605 return FALSE;
606 }
607 }
609 }
610
611 if (!sanity_check_req_vec(els->logger, &peffect->reqs, TRUE, one_tile,
612 effect_type_name(peffect->type))) {
613 ruleset_error(els->logger, LOG_ERROR,
614 "Effects have conflicting or invalid requirements!");
615
616 return FALSE;
617 }
618
619 return TRUE;
620}
621
622/**********************************************************************/
626{
627 if (num_role_units(L_BARBARIAN) > 0) {
629 ruleset_error(logger, LOG_ERROR, "No role barbarian leader units");
630 return FALSE;
631 }
633 ruleset_error(logger, LOG_ERROR, "No role barbarian build units");
634 return FALSE;
635 }
637 ruleset_error(logger, LOG_ERROR, "No role barbarian ship units");
638 return FALSE;
639 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
640 bool sea_capable = FALSE;
642
644 if (is_ocean(pterr)
645 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
647 break;
648 }
650
651 if (!sea_capable) {
652 ruleset_error(logger, LOG_ERROR,
653 "Barbarian boat (%s) needs to be able to move at sea.",
654 utype_rule_name(u));
655 return FALSE;
656 }
657 }
659 ruleset_error(logger, LOG_ERROR, "No role sea raider barbarian units");
660 return FALSE;
661 }
662
665 if (ptype->transport_capacity <= 1) {
666 ruleset_error(logger, LOG_ERROR,
667 "Barbarian boat %s has no capacity for both "
668 "leader and at least one man.",
670 return FALSE;
671 }
672
678 ruleset_error(logger, LOG_ERROR,
679 "Barbarian boat %s cannot transport "
680 "barbarian cargo %s.",
683 return FALSE;
684 }
685 }
687 }
689 }
690
691 return TRUE;
692}
693
694/**********************************************************************/
698{
699 /* Check some required flags and roles etc: */
700 if (num_role_units(UTYF_SETTLERS) == 0) {
701 ruleset_error(logger, LOG_ERROR, "No flag Settler units");
702 return FALSE;
703 }
705 ruleset_error(logger, LOG_ERROR, "No role Start Explorer units");
706 return FALSE;
707 }
708 if (num_role_units(L_FERRYBOAT) == 0) {
709 ruleset_error(logger, LOG_ERROR, "No role Ferryboat units");
710 return FALSE;
711 }
712 if (num_role_units(L_FIRSTBUILD) == 0) {
713 ruleset_error(logger, LOG_ERROR, "No role Firstbuild units");
714 return FALSE;
715 }
716
717 if (num_role_units(L_FERRYBOAT) > 0) {
718 bool sea_capable = FALSE;
719 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
720
722 if (is_ocean(pterr)
723 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
725 break;
726 }
728
729 if (!sea_capable) {
730 ruleset_error(logger, LOG_ERROR,
731 "Ferryboat (%s) needs to be able to move at sea.",
732 utype_rule_name(u));
733 return FALSE;
734 }
735 }
736
737 if (num_role_units(L_PARTISAN) == 0
739 ruleset_error(logger, LOG_ERROR,
740 "Inspire_Partisans effect present, but no units with partisan role.");
741 return FALSE;
742 }
743
744 return TRUE;
745}
746
747/**********************************************************************/
751{
752 /* Special Genus */
754 if (improvement_has_flag(pimprove, IF_GOLD)
755 && pimprove->genus != IG_CONVERT) {
756 ruleset_error(logger, LOG_ERROR,
757 "Gold producing improvement %s with genus other than \"Convert\"",
758 improvement_rule_name(pimprove));
759
760 return FALSE;
761 }
763 && pimprove->genus != IG_IMPROVEMENT) {
764 ruleset_error(logger, LOG_ERROR,
765 "Disasterproof improvement %s with genus other than \"Improvement\"",
766 improvement_rule_name(pimprove));
767
768 return FALSE;
769 }
770 if (pimprove->genus != IG_SPECIAL
776 RPT_POSSIBLE, FALSE))) {
777 ruleset_error(logger, LOG_ERROR,
778 "Space part %s with genus other than \"Special\"",
779 improvement_rule_name(pimprove));
780 return FALSE;
781 }
782
783 if (!is_building_sellable(pimprove) && pimprove->upkeep != 0) {
784 ruleset_error(logger, LOG_ERROR,
785 "%s is a nonsellable building with a nonzero upkeep value",
786 improvement_rule_name(pimprove));
787 return FALSE;
788 }
790
791 return TRUE;
792}
793
794/**********************************************************************/
798{
799 enum effect_type boolean_effects[] =
800 {
824 };
825 int i;
826 bool ret = TRUE;
827
828 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
831 ruleset_error(logger, LOG_ERROR,
832 "Boolean effect %s can get disabled, but it can't get "
833 "enabled before that.", effect_type_name(boolean_effects[i]));
834 ret = FALSE;
835 }
836 }
837
838 return ret;
839}
840
841/**********************************************************************/
849{
850 int num_utypes;
851 int i;
852 bool ok = TRUE; /* Store failures to variable instead of returning
853 * immediately so all errors get printed, not just first
854 * one. */
858 rs_conversion_logger logger = ((compat != NULL) ? compat->log_cb : NULL);
859
860 if (!sanity_check_metadata(logger)) {
861 ok = FALSE;
862 }
863
866 ruleset_error(logger, LOG_ERROR,
867 "Cost based free tech method, but tech cost style "
868 "\"Civ I|II\" so all techs cost the same.");
869 ok = FALSE;
870 }
871
872 /* Advances. */
874 for (i = AR_ONE; i < AR_SIZE; i++) {
875 const struct advance *preq;
876
877 if (i == AR_ROOT) {
878 /* Self rootreq is a feature. */
879 continue;
880 }
881
883
884 if (A_NEVER == preq) {
885 continue;
886 } else if (preq == padvance) {
887 ruleset_error(logger, LOG_ERROR, "Tech \"%s\" requires itself.",
889 ok = FALSE;
890 continue;
891 }
892
894 if (preqreq == padvance) {
895 ruleset_error(logger, LOG_ERROR,
896 "Tech \"%s\" requires itself indirectly via \"%s\".",
899 ok = FALSE;
900 }
902 }
903
904 requirement_vector_iterate(&(padvance->research_reqs), preq) {
905 if (preq->source.kind == VUT_ADVANCE) {
906 /* Don't allow this even if allowing changing reqs. Players will
907 * expect all tech reqs to appear in the client tech tree. That
908 * should be taken care of first. */
909 ruleset_error(logger, LOG_ERROR,
910 "Tech \"%s\" requires a tech in its research_reqs."
911 " This isn't supported yet. Please keep using req1"
912 " and req2 like before.",
914 ok = FALSE;
916 /* If we get an obsolete improvement before the game,
917 * almost surely it is going to become not obsolete later.
918 * This check must catch it. */) {
919 struct astring astr;
920
921 /* Only support unchanging requirements until the reachability code
922 * can handle it and the tech tree can display changing
923 * requirements. */
924 ruleset_error(logger, LOG_ERROR,
925 "Tech \"%s\" has the requirement %s in its"
926 " research_reqs. This requirement may change during"
927 " the game. Changing requirements aren't supported"
928 " yet.",
931 astr_free(&astr);
932 ok = FALSE;
933 }
935
936 if (padvance->bonus_message != NULL) {
937 if (!formats_match(padvance->bonus_message, "%s")) {
938 ruleset_error(logger, LOG_ERROR,
939 "Tech \"%s\" bonus message is not format with %%s for a bonus tech name.",
941 ok = FALSE;
942 }
943 }
945
947 ruleset_error(logger, LOG_ERROR,
948 "The government form %s reserved for revolution handling has been set as "
949 "default_government.",
951 ok = FALSE;
953 }
954
955 /* Check that all players can have their initial techs */
957 int techi;
958
959 /* Check global initial techs */
960 for (techi = 0; techi < MAX_NUM_TECH_LIST
963 struct advance *a = valid_advance_by_number(tech);
964
965 if (a == NULL) {
966 ruleset_error(logger, LOG_ERROR,
967 "Tech %s does not exist, but is initial "
968 "tech for everyone.",
970 ok = FALSE;
971 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
972 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
973 /* Nation has no root_req for tech */
974 ruleset_error(logger, LOG_ERROR,
975 "Tech %s is initial for everyone, but %s has "
976 "no root_req for it.",
978 nation_rule_name(pnation));
979 ok = FALSE;
980 }
981 }
982
983 /* Check national initial techs */
984 for (techi = 0;
985 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
986 techi++) {
987 Tech_type_id tech = pnation->init_techs[techi];
988 struct advance *a = valid_advance_by_number(tech);
989
990 if (a == NULL) {
991 ruleset_error(logger, LOG_ERROR,
992 "Tech %s does not exist, but is tech for %s.",
994 nation_rule_name(pnation));
995 ok = FALSE;
996 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
997 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
998 /* Nation has no root_req for tech */
999 ruleset_error(logger, LOG_ERROR,
1000 "Tech %s is initial for %s, but they have "
1001 "no root_req for it.",
1003 nation_rule_name(pnation));
1004 ok = FALSE;
1005 }
1006 }
1007
1008 /* Check national initial buildings */
1010 && pnation->init_buildings[0] != B_LAST) {
1011 ruleset_error(logger, LOG_ERROR,
1012 "Barbarian nation %s has init_buildings set but will "
1013 "never see them", nation_rule_name(pnation));
1014 }
1015
1016 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
1017 ruleset_error(logger, LOG_ERROR,
1018 "The government form %s reserved for revolution handling has been set as "
1019 "initial government for %s.",
1021 nation_rule_name(pnation));
1022 ok = FALSE;
1023 }
1025
1026 /* Check against unit upgrade loops */
1029 int chain_length = 0;
1030 const struct unit_type *upgraded = putype;
1031
1032 while (upgraded != NULL && !obsoleted_by_loop) {
1034 chain_length++;
1035 if (chain_length > num_utypes) {
1036 ruleset_error(logger, LOG_ERROR,
1037 "There seems to be obsoleted_by loop in update "
1038 "chain that starts from %s", utype_rule_name(putype));
1039 ok = FALSE;
1041 }
1042 }
1044
1045 /* Some unit type properties depend on other unit type properties to work
1046 * properly. */
1048 /* "Spy" is a better "Diplomat". Until all the places that assume that
1049 * "Diplomat" is set if "Spy" is set is changed this limitation must be
1050 * kept. */
1053 ruleset_error(logger, LOG_ERROR,
1054 "The unit type '%s' has the 'Spy' unit type flag but "
1055 "not the 'Diplomat' unit type flag.",
1057 ok = FALSE;
1058 }
1060
1061 /* Check that unit type fields are in range. */
1063 if (putype->paratroopers_range < 0
1064 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
1065 /* Paradrop range is limited by the network protocol. */
1066 ruleset_error(logger, LOG_ERROR,
1067 "The paratroopers_range of the unit type '%s' is %d. "
1068 "That is out of range. Max range is %d.",
1070 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
1071 ok = FALSE;
1072 }
1073 /* never fires if game.scenario.prevent_new_cities is TRUE */
1074 if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE)
1076 ruleset_error(logger, LOG_ERROR,
1077 "Unit type '%s' would build size %d cities. "
1078 "City sizes must be from 1 to %d.",
1079 utype_rule_name(putype), putype->city_size,
1081 ok = FALSE;
1082 }
1084
1085 memset(&els, 0, sizeof(els));
1086 els.logger = logger;
1087
1088 /* Check requirement sets against conflicting requirements.
1089 * For effects check also other sanity in the same iteration */
1091 ok = FALSE;
1092 }
1093
1094 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
1095 if (!els.base_effects.effect_present[req_base_effects[i]]) {
1096 ruleset_error(logger, LOG_ERROR,
1097 "There is no base %s effect.",
1099 ok = FALSE;
1100 }
1101 }
1102 for (i = 0; req_base_effects_3_2[i] != EFT_COUNT; i++) {
1103 if (!els.base_effects.effect_present[req_base_effects_3_2[i]]) {
1105
1106 if (compat != NULL && compat->compat_mode && compat->version < RSFORMAT_3_2) {
1107 log_deprecation("There is no base %s effect.", ename);
1108 if (compat->log_cb != NULL) {
1109 char buf[512];
1110
1111 fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename);
1112 compat->log_cb(buf);
1113 }
1114 } else {
1115 ruleset_error(logger, LOG_ERROR,
1116 "There is no base %s effect.", ename);
1117 ok = FALSE;
1118 }
1119 }
1120 }
1121
1122 if (!sanity_check_boolean_effects(logger)) {
1123 ok = FALSE;
1124 }
1125
1126 /* Others use requirement vectors */
1127
1128 /* Disasters */
1130 if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1,
1132 ruleset_error(logger, LOG_ERROR,
1133 "Disasters have conflicting or invalid requirements!");
1134 ok = FALSE;
1135 }
1137
1138 /* Goods */
1140 if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1,
1142 ruleset_error(logger, LOG_ERROR,
1143 "Goods have conflicting or invalid requirements!");
1144 ok = FALSE;
1145 }
1147
1148 /* Buildings */
1150 if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1,
1151 improvement_rule_name(pimprove))) {
1152 ruleset_error(logger, LOG_ERROR,
1153 _("Buildings have conflicting or invalid requirements!"));
1154 ok = FALSE;
1155 }
1156 if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1,
1157 improvement_rule_name(pimprove))) {
1158 ruleset_error(logger, LOG_ERROR,
1159 _("Buildings have conflicting or invalid obsolescence req!"));
1160 ok = FALSE;
1161 }
1163
1164 /* Governments */
1166 if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1,
1168 ruleset_error(logger, LOG_ERROR,
1169 "Governments have conflicting or invalid requirements!");
1170 ok = FALSE;
1171 }
1173
1174 /* Specialists */
1176 if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1,
1177 specialist_rule_name(psp))) {
1178 ruleset_error(logger, LOG_ERROR,
1179 "Specialists have conflicting or invalid requirements!");
1180 ok = FALSE;
1181 }
1183
1184 /* Extras */
1186 if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1,
1187 extra_rule_name(pextra))) {
1188 ruleset_error(logger, LOG_ERROR,
1189 "Extras have conflicting or invalid requirements!");
1190 ok = FALSE;
1191 }
1192 if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1,
1193 extra_rule_name(pextra))) {
1194 ruleset_error(logger, LOG_ERROR,
1195 "Extras have conflicting or invalid removal requirements!");
1196 ok = FALSE;
1197 }
1198 if ((requirement_vector_size(&pextra->rmreqs) > 0)
1199 && !(pextra->rmcauses
1200 & (ERM_ENTER | ERM_CLEAN | ERM_PILLAGE))) {
1201 ruleset_error(logger, LOG_WARN,
1202 "Requirements for extra removal defined but not "
1203 "a valid remove cause!");
1204 }
1206
1207 /* Roads */
1209 struct road_type *proad = extra_road_get(pextra);
1210
1211 extra_type_list_iterate(proad->integrators, iextra) {
1213 int pnbr = road_number(proad);
1214
1215 if (pnbr != road_number(iroad)
1216 && !BV_ISSET(iroad->integrates, pnbr)) {
1217 /* We don't support non-symmetric integrator relationships yet. */
1218 ruleset_error(logger, LOG_ERROR,
1219 "Road '%s' integrates with '%s' but not vice versa!",
1220 extra_rule_name(pextra),
1222 ok = FALSE;
1223 }
1226
1227 /* City styles */
1228 for (i = 0; i < game.control.num_city_styles; i++) {
1229 if (!sanity_check_req_vec(logger, &city_styles[i].reqs, TRUE, -1,
1231 ruleset_error(logger, LOG_ERROR,
1232 "City styles have conflicting or invalid requirements!");
1233 ok = FALSE;
1234 }
1235 }
1236
1237 /* Actions */
1238 action_iterate(act) {
1239 struct action *paction = action_by_number(act);
1240
1241 if (!actres_legal_target_kind(paction->result, paction->target_kind)) {
1242 ruleset_error(logger, LOG_ERROR, "Action \"%s\": unsupported target kind %s.",
1244 action_target_kind_name(paction->target_kind));
1245 ok = FALSE;
1246 }
1247
1248 if (paction->min_distance < 0) {
1249 ruleset_error(logger, LOG_ERROR, "Action %s: negative min distance (%d).",
1250 action_id_rule_name(act), paction->min_distance);
1251 ok = FALSE;
1252 }
1253
1254 if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) {
1255 ruleset_error(logger, LOG_ERROR,
1256 "Action %s: min distance (%d) larger than "
1257 "any distance on a map can be (%d).",
1258 action_id_rule_name(act), paction->min_distance,
1260 ok = FALSE;
1261 }
1262
1263 if (paction->max_distance > ACTION_DISTANCE_MAX) {
1264 ruleset_error(logger, LOG_ERROR,
1265 "Action %s: max distance is %d. "
1266 "A map can't be that big.",
1267 action_id_rule_name(act), paction->max_distance);
1268 ok = FALSE;
1269 }
1270
1271 if (!action_distance_inside_max(paction, paction->min_distance)) {
1272 ruleset_error(logger, LOG_ERROR,
1273 "Action %s: min distance is %d but max distance is %d.",
1275 paction->min_distance, paction->max_distance);
1276 ok = FALSE;
1277 }
1278
1279 action_iterate(blocker) {
1280 if (BV_ISSET(paction->blocked_by, blocker)
1281 && action_id_get_target_kind(blocker) == ATK_UNIT
1283 /* Can't find an individual unit target to evaluate the blocking
1284 * action against. (A tile may have more than one individual
1285 * unit) */
1286 ruleset_error(logger, LOG_ERROR,
1287 "The action %s can't block %s.",
1288 action_id_rule_name(blocker),
1289 action_id_rule_name(act));
1290 ok = FALSE;
1291 }
1293
1295 if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1,
1296 "Action Enabler Actor Reqs")
1297 || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1,
1298 "Action Enabler Target Reqs")) {
1299 ruleset_error(logger, LOG_ERROR,
1300 "Action enabler for %s has conflicting or invalid "
1301 "requirements!", action_id_rule_name(act));
1302 ok = FALSE;
1303 }
1304
1306 /* Special test for self targeted actions. */
1307
1308 if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1309 /* Shouldn't have target requirements since the action doesn't
1310 * have a target. */
1311 ruleset_error(logger, LOG_ERROR,
1312 "An action enabler for %s has a target "
1313 "requirement vector. %s doesn't have a target.",
1315 action_id_rule_name(act));
1316 ok = FALSE;
1317 }
1318 }
1319
1320 requirement_vector_iterate(&(enabler->target_reqs), preq) {
1321 if (preq->source.kind == VUT_DIPLREL
1322 && preq->range == REQ_RANGE_LOCAL) {
1323 struct astring astr;
1324
1325 /* A Local DiplRel requirement can be expressed as a requirement
1326 * in actor_reqs. Demand that it is there. This avoids breaking
1327 * code that reasons about actions. */
1328 ruleset_error(logger, LOG_ERROR,
1329 "Action enabler for %s has a local DiplRel "
1330 "requirement %s in target_reqs! Please read the "
1331 "section \"Requirement vector rules\" in "
1332 "doc/README.actions",
1335 astr_free(&astr);
1336 ok = FALSE;
1337 }
1339
1340 if (compat == NULL || !compat->compat_mode
1341 || compat->version >= RSFORMAT_3_2) {
1342 /* Support for letting some of the following hard requirements be
1343 * implicit were retired in Freeciv 3.0. Others were retired later.
1344 * Make sure that the opposite of each hard action requirement
1345 * blocks all its action enablers. */
1346
1347 struct req_vec_problem *problem
1349
1350 if (problem != NULL) {
1351 ruleset_error(logger, LOG_ERROR, "%s", problem->description);
1353 ok = FALSE;
1354 }
1355
1357 if (problem != NULL) {
1358 /* There is a potential for improving this enabler. */
1359 log_deprecation("%s", problem->description);
1361 }
1362 }
1364
1366 /* The action performer, action_dice_roll_initial_odds() and the
1367 * action probability calculation in action_prob() must probably all
1368 * be updated to add a new action here. */
1385 ruleset_error(logger, LOG_ERROR,
1386 "diplchance_initial_odds: \"%s\" not supported.",
1388 ok = FALSE;
1389 }
1390
1391 if (BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER)
1392 && BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)) {
1393 ruleset_error(logger, LOG_ERROR,
1394 "%s both enters and frightens a hut at the same time.",
1396 ok = FALSE;
1397 }
1399
1400 /* Auto attack */
1401 {
1403
1405
1407 struct action *paction = action_by_number(act_id);
1408
1413 /* Only allow removing and changing the order of old auto
1414 * attack actions for now. Other actions need more testing and
1415 * fixing of issues caused by a worst case action probability of
1416 * 0%. */
1417 ruleset_error(logger, LOG_ERROR, "auto_attack: %s not supported in"
1418 " attack_actions.",
1420 ok = FALSE;
1421 }
1423 }
1424
1425 /* There must be basic city style for each nation style to start with */
1428 ruleset_error(logger, LOG_ERROR,
1429 "There's no basic city style for nation style %s",
1431 ok = FALSE;
1432 }
1434
1435 /* Music styles */
1437 if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) {
1438 ruleset_error(logger, LOG_ERROR,
1439 "Music Styles have conflicting or invalid requirements!");
1440 ok = FALSE;
1441 }
1443
1445 if (pterr->animal != NULL) {
1446 if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) {
1447 ruleset_error(logger, LOG_ERROR,
1448 "%s has %s as animal to appear, but it's not native to the terrain.",
1450 ok = FALSE;
1451 }
1452 }
1453
1455 (void) freq;
1457 ruleset_error(logger, LOG_ERROR,
1458 "%s has %s as a resource, but it's not a resource extra.",
1460 ok = FALSE;
1461 }
1464
1465 /* Check that all unit classes can exist somewhere */
1468 bool can_exist = FALSE;
1469
1471 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1472 can_exist = TRUE;
1473 break;
1474 }
1476
1477 if (!can_exist) {
1479 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1480 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1481 can_exist = TRUE;
1482 break;
1483 }
1485 }
1486
1487 if (!can_exist) {
1488 ruleset_error(logger, LOG_ERROR,
1489 "Unit class %s cannot exist anywhere.",
1491 ok = FALSE;
1492 }
1493 }
1495
1497 if (!pach->unique && pach->cons_msg == NULL) {
1498 ruleset_error(logger, LOG_ERROR,
1499 "Achievement %s has no message for consecutive gainers though "
1500 "it's possible to be gained by multiple players",
1502 ok = FALSE;
1503 }
1505
1507 int nati;
1508
1510 struct nation_type *pnat
1512
1513 if (pnat == NULL) {
1514 ruleset_error(logger, LOG_ERROR,
1515 "There's nation %s listed in embedded nations, but there's "
1516 "no such nation.",
1518 ok = FALSE;
1519 }
1520 }
1521 }
1522
1523 if (ok) {
1524 ok = rs_common_units(logger);
1525 }
1526 if (ok) {
1527 ok = rs_barbarian_units(logger);
1528 }
1529 if (ok) {
1530 ok = rs_buildings(logger);
1531 }
1532
1533 return ok;
1534}
1535
1536/**********************************************************************/
1542{
1543 bool ok = TRUE;
1544
1547 if (pextra != pextra2) {
1548 int idx = extra_index(pextra2);
1549
1550 if (!BV_ISSET(pextra->conflicts, idx)) {
1551 log_debug("Autoconflicting resource %s with %s",
1553 BV_SET(pextra->conflicts, extra_index(pextra2));
1554 }
1555 }
1558
1559 /* Hard coded action blocking. */
1560 {
1561 const struct {
1562 const enum action_result blocked;
1563 const enum action_result blocker;
1564 } must_block[] = {
1565 /* Hard code that Help Wonder blocks Disband Unit Recover. This must be done
1566 * because caravan_shields makes it possible to avoid the
1567 * consequences of choosing to do Disband Unit Recover rather than having it
1568 * do Help Wonder.
1569 *
1570 * Explanation: Disband Unit Recover adds 50% of the shields used to produce
1571 * the unit to the production of the city where it is located. Help
1572 * Wonder adds 100%. If a unit that can do Help Wonder is disbanded with
1573 * production recovery in a city and the production later is changed
1574 * to something that can receive help from Help Wonder the remaining 50%
1575 * of the shields are added. This can be done because the city remembers
1576 * them in caravan_shields.
1577 *
1578 * If a unit that can do Help Wonder intentionally is disbanded with recovery
1579 * rather than making it do Help Wonder its shields will still be
1580 * remembered. The target city that got 50% of the shields can
1581 * therefore get 100% of them by changing its production. This trick
1582 * makes the ability to select Disband Unit Recover when Help Wonder is legal
1583 * pointless. */
1585
1586 /* Allowing regular disband when ACTION_HELP_WONDER or
1587 * ACTION_DISBAND_UNIT_RECOVER is legal while ACTION_HELP_WONDER always
1588 * blocks ACTION_DISBAND_UNIT_RECOVER doesn't work well with the force_*
1589 * semantics. Should move to the ruleset once it has blocked_by
1590 * semantics. */
1593
1594 /* Hard code that the ability to perform a regular attack blocks city
1595 * conquest. Is redundant as long as the requirement that the target
1596 * tile has no units remains hard coded. Kept "just in case" that
1597 * changes. */
1599
1600 /* Hard code that the ability to perform a regular attack blocks
1601 * extras conquest. Is redundant as long as the requirement that the
1602 * target tile has no non-allied units remains hard coded. Kept "just
1603 * in case" that changes. */
1605
1606 /* Hard code that the ability to enter or frighten a hut blocks
1607 * regular disembarking. */
1611 };
1612
1613 int i;
1614
1615 for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1616 enum action_result blocked_result = must_block[i].blocked;
1617 enum action_result blocker_result = must_block[i].blocker;
1618
1621 if (!action_would_be_blocked_by(blocked, blocker)) {
1622 log_verbose("Autoblocking %s with %s",
1623 action_rule_name(blocked),
1624 action_rule_name(blocker));
1625 BV_SET(blocked->blocked_by, action_id(blocker));
1626 }
1629 }
1630 }
1631
1632 return ok;
1633}
1634
1635/**********************************************************************/
1639{
1640 bool ok = TRUE;
1641
1642 if (num_role_units(L_BARBARIAN) == 0) {
1643 struct setting *pset = setting_by_name("barbarians");
1644
1645 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
1646 "unit types."));
1648 if (!setting_enum_set(pset, "DISABLED", NULL, NULL, 0)) {
1649 ok = FALSE;
1650 }
1652 }
1653
1654 return ok;
1655}
const char * achievement_rule_name(struct achievement *pach)
#define achievements_re_active_iterate(_p)
#define achievements_re_active_iterate_end
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1925
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1850
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:6423
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2670
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2736
const char * action_rule_name(const struct action *action)
Definition actions.c:1968
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1991
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1948
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:6099
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1860
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2306
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:479
#define ACTION_DISTANCE_MAX
Definition actions.h:357
#define enabler_get_action(_enabler_)
Definition actions.h:431
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:609
#define action_auto_perf_actions_iterate_end
Definition actions.h:600
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
#define action_enabler_list_re_iterate_end
Definition actions.h:445
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:353
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:441
#define action_has_result(_act_, _res_)
Definition actions.h:429
#define action_by_result_iterate_end
Definition actions.h:483
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition actions.h:597
#define action_iterate_end
Definition actions.h:463
#define action_has_result_safe(paction, result)
Definition actions.h:661
#define action_iterate(_act_)
Definition actions.h:459
#define action_id_get_target_kind(act_id)
Definition actions.h:650
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:911
bool actres_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actres.c:558
void astr_free(struct astring *astr)
Definition astring.c:153
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
const char * city_style_rule_name(const int style)
Definition city.c:1757
static const struct city struct citystyle * city_styles
Definition city.c:83
#define MAX_CITY_SIZE
Definition city.h:106
char * incite_cost
Definition comments.c:74
#define MAX_LEN_CONTENT
Definition conn_types.h:32
#define log_deprecation(message,...)
const char * disaster_rule_name(struct disaster_type *pdis)
Definition disaster.c:105
#define disaster_type_re_active_iterate(_p)
Definition disaster.h:91
#define disaster_type_re_active_iterate_end
Definition disaster.h:94
int int id
Definition editgui_g.h:28
struct @21::@22 reqs
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1323
int get_potential_improvement_bonus(const struct impr_type *pimprove, const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type, bool consider_multipliers)
Definition effects.c:1204
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:388
int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
Definition effects.c:424
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:861
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define extra_type_re_active_iterate_end
Definition extras.h:329
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_re_active_iterate(_p)
Definition extras.h:325
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
int server_setting_id
Definition fc_types.h:1071
int Tech_type_id
Definition fc_types.h:380
int ssetv
Definition fc_types.h:696
@ RPT_POSSIBLE
Definition fc_types.h:703
int action_id
Definition fc_types.h:392
#define MAX_NUM_TECH_LIST
Definition fc_types.h:44
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:62
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
#define governments_re_active_iterate(_p)
Definition government.h:125
#define governments_re_active_iterate_end
Definition government.h:129
bool is_building_sellable(const struct impr_type *pimprove)
const char * improvement_rule_name(const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_re_active_iterate_end
#define improvement_re_active_iterate(_p)
#define B_LAST
Definition improvement.h:42
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
@ LOG_ERROR
Definition log.h:30
@ LOG_WARN
Definition log.h:31
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
Definition movement.c:342
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:868
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:121
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:211
#define nations_re_active_iterate_end
Definition nation.h:342
#define nations_re_active_iterate(_pnat_)
Definition nation.h:339
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
req_vec_num_in_item req_vec_vector_number(const void *parent_item, const struct requirement_vector *vec)
struct req_vec_problem * req_vec_suggest_repair(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
const char * universal_rule_name(const struct universal *psource)
void req_vec_problem_free(struct req_vec_problem *issue)
const char * universal_type_rule_name(const struct universal *psource)
enum req_unchanging_status is_req_unchanging(const struct req_context *context, const struct requirement *req)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
@ REQUCH_HACK
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
bool sanity_check_ruleset_data(struct rscompat_info *compat)
Definition rssanity.c:848
static bool sanity_check_req_vec(rs_conversion_logger logger, const struct requirement_vector *preqs, bool conjunctive, int max_tiles, const char *list_for)
Definition rssanity.c:490
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Definition rssanity.c:141
enum effect_type req_base_effects[]
Definition rssanity.c:43
static bool sanity_check_req_set(rs_conversion_logger logger, int reqs_of_type[], int local_reqs_of_type[], int tile_reqs_of_type[], struct requirement *preq, bool conjunctive, int max_tiles, const char *list_for)
Definition rssanity.c:254
enum effect_type req_base_effects_3_2[]
Definition rssanity.c:50
static bool sanity_check_boolean_effects(rs_conversion_logger logger)
Definition rssanity.c:797
static bool sanity_check_setting_is_seen(struct setting *pset)
Definition rssanity.c:105
static bool sanity_check_req_individual(rs_conversion_logger logger, struct requirement *preq, const char *list_for)
Definition rssanity.c:168
static bool rs_buildings(rs_conversion_logger logger)
Definition rssanity.c:750
static bool sanity_check_metadata(rs_conversion_logger logger)
Definition rssanity.c:59
bool autolock_settings(void)
Definition rssanity.c:1638
static bool rs_common_units(rs_conversion_logger logger)
Definition rssanity.c:697
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1541
static bool rs_barbarian_units(rs_conversion_logger logger)
Definition rssanity.c:625
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Definition rssanity.c:532
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Definition rssanity.c:114
static bool nation_has_initial_tech(struct nation_type *pnation, struct advance *tech)
Definition rssanity.c:76
void(* rs_conversion_logger)(const char *msg)
Definition ruleset.h:40
#define ruleset_error(logger, level, format,...)
Definition ruleset.h:57
#define RSFORMAT_3_2
Definition ruleset.h:36
static struct compatibility compat[]
Definition savecompat.c:110
const char * server_setting_name_get(server_setting_id id)
enum sset_type server_setting_type_get(server_setting_id id)
server_setting_id ssetv_setting_get(ssetv enc)
bool server_setting_exists(server_setting_id id)
void setting_ruleset_lock_clear(struct setting *pset)
Definition settings.c:4702
struct setting * setting_by_name(const char *name)
Definition settings.c:3299
struct setting * setting_by_number(int id)
Definition settings.c:3291
enum sset_category setting_category(const struct setting *pset)
Definition settings.c:3368
bool setting_enum_set(struct setting *pset, const char *val, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Definition settings.c:4012
void setting_ruleset_lock_set(struct setting *pset)
Definition settings.c:4682
bool setting_is_visible_at_level(const struct setting *pset, enum cmdlevel plevel)
Definition settings.c:3486
bool formats_match(const char *format1, const char *format2)
Definition shared.c:2442
#define ARRAY_SIZE(x)
Definition shared.h:85
const char * specialist_rule_name(const struct specialist *sp)
Definition specialist.c:146
#define specialist_type_re_active_iterate_end
Definition specialist.h:88
#define specialist_type_re_active_iterate(_p)
Definition specialist.h:83
struct advance * require[AR_SIZE]
Definition tech.h:132
struct packet_ruleset_control control
Definition game.h:83
char * ruleset_summary
Definition game.h:84
int global_init_techs[MAX_NUM_TECH_LIST]
Definition game.h:108
struct packet_game_info info
Definition game.h:89
char ** embedded_nations
Definition game.h:282
struct civ_game::@31::@35::@40 ruledit
struct civ_game::@31::@35 server
size_t embedded_nations_count
Definition game.h:283
struct civ_game::@30 rgame
struct packet_calendar_info calendar
Definition game.h:90
struct government * default_government
Definition game.h:93
struct government * government_during_revolution
Definition game.h:94
rs_conversion_logger logger
Definition rssanity.c:526
int init_techs[MAX_NUM_TECH_LIST]
Definition nation.h:122
enum free_tech_method free_tech_method
bv_actions diplchance_initial_odds
enum tech_cost_style tech_cost_style
const struct unit_type * obsoleted_by
Definition unittype.h:529
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:108
int basic_city_style_for_style(struct nation_style *pstyle)
Definition style.c:210
#define music_styles_re_active_iterate_end
Definition style.h:88
#define music_styles_re_active_iterate(_p)
Definition style.h:85
#define styles_re_active_iterate_end
Definition style.h:60
#define styles_re_active_iterate(_p)
Definition style.h:56
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Definition tech.c:136
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define advance_re_active_iterate(_p)
Definition tech.h:281
#define A_NEVER
Definition tech.h:51
#define advance_req_iterate(_goal, _padvance)
Definition tech.h:299
@ AR_ROOT
Definition tech.h:113
@ AR_ONE
Definition tech.h:111
@ AR_SIZE
Definition tech.h:114
#define advance_re_active_iterate_end
Definition tech.h:285
#define advance_req_iterate_end
Definition tech.h:303
#define A_NONE
Definition tech.h:43
#define A_LAST
Definition tech.h:45
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
#define terrain_re_active_iterate_end
Definition terrain.h:388
#define is_ocean(pterrain)
Definition terrain.h:301
#define terrain_re_active_iterate(_p)
Definition terrain.h:384
#define terrain_resources_iterate_end
Definition terrain.h:401
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:392
const char * goods_rule_name(struct goods_type *pgood)
#define goods_type_re_active_iterate_end
#define goods_type_re_active_iterate(_p)
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2951
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2253
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:199
int num_role_units(int role)
Definition unittype.c:2203
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1641
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
#define unit_type_re_active_iterate(_p)
Definition unittype.h:864
#define utype_class(_t_)
Definition unittype.h:749
#define unit_class_re_active_iterate_end
Definition unittype.h:921
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_class_re_active_iterate(_p)
Definition unittype.h:917
#define UNIT_MAX_PARADROP_RANGE
Definition unittype.h:56
#define uclass_index(_c_)
Definition unittype.h:742
#define unit_type_re_active_iterate_end
Definition unittype.h:868