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,
65 _("Too long ruleset summary. It can be only %d bytes long. "
66 "Put longer explanations to ruleset description."),
68 return FALSE;
69 }
70
71 return TRUE;
72}
73
74/**********************************************************************/
77static bool nation_has_initial_tech(struct nation_type *pnation,
78 struct advance *tech)
79{
80 int i;
81
82 /* See if it's given as global init tech */
83 for (i = 0; i < MAX_NUM_TECH_LIST
86 return TRUE;
87 }
88 }
89
90 /* See if it's given as national init tech */
91 for (i = 0;
92 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
93 i++) {
94 if (pnation->init_techs[i] == advance_number(tech)) {
95 return TRUE;
96 }
97 }
98
99 return FALSE;
100}
101
102/**********************************************************************/
110
111/**********************************************************************/
116{
119 /* White list for SSET_INTERNAL and SSET_NETWORK settings. */
120 && !(pset == setting_by_name("phasemode")
121 || pset == setting_by_name("timeout")
122 || pset == setting_by_name("timeaddenemymove")
123 || pset == setting_by_name("unitwaittime")
124 || pset == setting_by_name("victories"))) {
125 /* The given server setting is a server operator related setting (like
126 * the compression type of savegames), not a game rule. */
127 return FALSE;
128 }
129
130 if (pset == setting_by_name("naturalcitynames")) {
131 /* This setting is about "look", not rules. */
132 return FALSE;
133 }
134
135 return TRUE;
136}
137
138/**********************************************************************/
143{
145 struct setting *pset;
146
147 /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
148 * the server setting id. */
149 id = (server_setting_id)ssetval;
151
153 /* Not supported yet. */
154 return FALSE;
155 }
156
158
161}
162
163/**********************************************************************/
170 struct requirement *preq,
171 const char *list_for)
172{
173 switch (preq->source.kind) {
174 case VUT_IMPROVEMENT:
175 case VUT_SITE:
176 /* This check corresponds to what is_req_active() will support.
177 * It can't be done in req_from_str(), as we may not have
178 * loaded all building information at that time. */
179 {
180 const struct impr_type *pimprove = preq->source.value.building;
181
182 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
183 ruleset_error(logger, LOG_ERROR,
184 _("%s: World-ranged requirement not supported for "
185 "%s (only great wonders supported)"), list_for,
187 return FALSE;
188 } else if (preq->range > REQ_RANGE_TRADE_ROUTE && !is_wonder(pimprove)) {
189 ruleset_error(logger, LOG_ERROR,
190 _("%s: %s-ranged requirement not supported for "
191 "%s (only wonders supported)"), list_for,
192 req_range_name(preq->range),
194 return FALSE;
195 }
196 }
197 break;
198 case VUT_MINCALFRAG:
199 /* Currently [calendar] is loaded after some requirements are
200 * parsed, so we can't do this in universal_value_from_str(). */
202 ruleset_error(logger, LOG_ERROR,
203 _("%s: MinCalFrag requirement used in ruleset without "
204 "calendar fragments"), list_for);
205 return FALSE;
206 } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) {
207 ruleset_error(logger, LOG_ERROR,
208 _("%s: MinCalFrag requirement %d out of range (max %d in "
209 "this ruleset)"), list_for, preq->source.value.mincalfrag,
211 return FALSE;
212 }
213 break;
215 /* There is currently no way to check a server setting's category and
216 * access level that works in both the client and the server. */
217 {
219 struct setting *pset;
220
221 id = ssetv_setting_get(preq->source.value.ssetval);
224
226 ruleset_error(logger, LOG_ERROR,
227 _("%s: ServerSetting requirement %s isn't visible enough "
228 "to appear in a requirement. Everyone should be able to "
229 "see the value of a server setting that appears in a "
230 "requirement."), list_for, server_setting_name_get(id));
231 return FALSE;
232 }
233
235 /* This is a server operator related setting (like the compression
236 * type of savegames), not a game rule. */
237 ruleset_error(logger, LOG_ERROR,
238 _("%s: ServerSetting requirement setting %s isn't about a "
239 "game rule."),
241 return FALSE;
242 }
243 }
244 break;
245 default:
246 /* No other universals have checks that can't be done at ruleset
247 * load time. See req_from_str(). */
248 break;
249 }
250 return TRUE;
251}
252
253/**********************************************************************/
257 int reqs_of_type[],
258 int local_reqs_of_type[],
259 int tile_reqs_of_type[],
260 struct requirement *preq, bool conjunctive,
261 int max_tiles, const char *list_for)
262{
263 int rc;
264
266
268 return FALSE;
269 }
270
271 if (!conjunctive) {
272 /* All the checks below are only meaningful for conjunctive lists. */
273 /* FIXME: we could add checks suitable for disjunctive lists. */
274 return TRUE;
275 }
276
277 /* Add to counter for positive requirements. */
278 if (preq->present) {
279 reqs_of_type[preq->source.kind]++;
280 }
281 rc = reqs_of_type[preq->source.kind];
282
283 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
284 local_reqs_of_type[preq->source.kind]++;
285
286 switch (preq->source.kind) {
287 case VUT_EXTRA:
288 if (local_reqs_of_type[VUT_EXTRA] > 1) {
289 ruleset_error(logger, LOG_ERROR,
290 _("%s: Requirement list has multiple local-ranged extra "
291 "requirements (did you mean to make them tile-ranged?)"),
292 list_for);
293 return FALSE;
294 }
295 break;
296 default:
297 break;
298 }
299 }
300
301 if (preq->range == REQ_RANGE_TILE && preq->present) {
302 tile_reqs_of_type[preq->source.kind]++;
303
304 switch (preq->source.kind) {
305 case VUT_TERRAINCLASS:
307 ruleset_error(logger, LOG_ERROR,
308 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
309 list_for);
310 return FALSE;
311 }
312 break;
313 case VUT_TERRAIN:
315 ruleset_error(logger, LOG_ERROR,
316 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
317 list_for);
318 return FALSE;
319 }
320 break;
321 case VUT_MINLATITUDE:
322 case VUT_MAXLATITUDE:
323 if (tile_reqs_of_type[preq->range] > 1) {
324 ruleset_error(logger, LOG_ERROR,
325 _("%s: Requirement list has duplicate %s requirement at Tile range"),
327 return FALSE;
328 }
329 break;
330 default:
331 break;
332 }
333 }
334
335 if (rc > 1 && preq->present) {
336 /* Multiple requirements of the same type */
337 switch (preq->source.kind) {
338 case VUT_GOVERNMENT:
339 case VUT_UTYPE:
340 case VUT_UCLASS:
341 case VUT_ACTION:
342 case VUT_ACTIVITY:
343 case VUT_OTYPE:
344 case VUT_SPECIALIST:
345 case VUT_MINSIZE: /* Breaks nothing, but has no sense either */
347 case VUT_MINMOVES: /* Breaks nothing, but has no sense either */
348 case VUT_MINVETERAN: /* Breaks nothing, but has no sense either */
349 case VUT_MINHP: /* Breaks nothing, but has no sense either */
350 case VUT_MINYEAR:
351 case VUT_MINCALFRAG:
352 case VUT_AI_LEVEL:
353 case VUT_TERRAINALTER: /* Local range only */
354 case VUT_STYLE:
355 case VUT_IMPR_GENUS:
356 case VUT_ORIGINAL_OWNER: /* City range -> only one original owner */
357 case VUT_FORM_AGE:
358 /* There can be only one requirement of these types (with current
359 * range limitations)
360 * Requirements might be identical, but we consider multiple
361 * declarations error anyway. */
362
363 ruleset_error(logger, LOG_ERROR,
364 _("%s: Requirement list has multiple %s requirements"),
366 return FALSE;
367 break;
368
369 case VUT_TERRAIN:
370 /* There can be only up to max_tiles requirements of these types */
371 if (max_tiles != -1 && rc > max_tiles) {
372 ruleset_error(logger, LOG_ERROR,
373 _("%s: Requirement list has more %s requirements than "
374 "can ever be fulfilled."), list_for,
376 return FALSE;
377 }
378 break;
379
380 case VUT_TERRAINCLASS:
381 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
382 ruleset_error(logger, LOG_ERROR,
383 _("%s: Requirement list has more %s requirements than "
384 "can ever be fulfilled."), list_for,
386 return FALSE;
387 }
388 break;
389
390 case VUT_AGE:
391 /* There can be age of the city, unit, and player */
392 if (rc > 3) {
393 ruleset_error(logger, LOG_ERROR,
394 _("%s: Requirement list has more %s requirements than "
395 "can ever be fulfilled."), list_for,
397 return FALSE;
398 }
399 break;
400
401 case VUT_MINTECHS:
402 /* At ranges 'Player' and 'World' */
403 if (rc > 2) {
404 ruleset_error(logger, LOG_ERROR,
405 _("%s: Requirement list has more %s requirements than "
406 "can ever be fulfilled."), list_for,
408 return FALSE;
409 }
410 break;
411
412 case VUT_COUNTER:
413 /* Can have multiple, since many counters (also of the same range)
414 * can meet checkpoint */
416 /* Can have multiple, since there are many settings. */
417 case VUT_TOPO:
418 /* Can have multiple, since it's flag based (iso & hex) */
419 case VUT_WRAP:
420 /* Can have multiple, since it's flag based (wrapx & wrapy) */
421 case VUT_EXTRA:
422 /* Note that there can be more than 1 extra / tile. */
423 case VUT_MAXTILEUNITS:
424 /* Can require different numbers on e.g. local/adjacent tiles. */
425 case VUT_NATION:
426 /* Can require multiple nations at Team/Alliance/World range. */
427 case VUT_NATIONGROUP:
428 /* Nations can be in multiple groups. */
429 case VUT_NONE:
430 case VUT_ADVANCE:
431 case VUT_TECHFLAG:
432 case VUT_IMPROVEMENT:
433 case VUT_SITE:
434 case VUT_UNITSTATE:
435 case VUT_CITYTILE:
436 case VUT_GOOD:
437 /* Can check different properties. */
438 case VUT_UTFLAG:
439 case VUT_UCFLAG:
440 case VUT_TERRFLAG:
441 case VUT_ROADFLAG:
442 case VUT_EXTRAFLAG:
443 case VUT_IMPR_FLAG:
444 case VUT_PLAYER_FLAG:
445 case VUT_PLAYER_STATE:
446 case VUT_NATIONALITY:
447 case VUT_MINCULTURE:
448 case VUT_ACHIEVEMENT:
449 case VUT_DIPLREL:
450 case VUT_DIPLREL_TILE:
454 /* Can have multiple requirements of these types */
455 case VUT_MINLATITUDE:
456 case VUT_MAXLATITUDE:
457 /* Can have multiple requirements at different ranges.
458 * TODO: Compare to number of legal ranges? */
459 break;
460 case VUT_CITYSTATUS:
461 /* Could check "CITYS_LAST * number of ranges" ? */
462 break;
463 case VUT_COUNT:
464 /* Should never be in requirement vector */
466 return FALSE;
467 break;
468 /* No default handling here, as we want compiler warning
469 * if new requirement type is added to enum and it's not handled
470 * here. */
471 }
472 }
473
474 return TRUE;
475}
476
477/**********************************************************************/
494 const struct requirement_vector *preqs,
495 bool conjunctive, int max_tiles,
496 const char *list_for)
497{
498 struct req_vec_problem *problem;
502
503 /* Initialize requirement counters */
504 memset(reqs_of_type, 0, sizeof(reqs_of_type));
506
511 return FALSE;
512 }
514
516 if (problem != NULL) {
517 ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description);
519 return FALSE;
520 }
521
522 return TRUE;
523}
524
525typedef struct {
526 struct {
527 bool effect_present[EFT_COUNT];
528 } base_effects;
530} els_data;
531
532/**********************************************************************/
535static bool effect_list_sanity_cb(struct effect *peffect, void *data)
536{
537 int one_tile = -1; /* TODO: Determine correct value from effect.
538 * -1 disables checking */
539 els_data *els = (els_data *)data;
540 struct astring astr;
541 int i;
542
543 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
544 if (peffect->type == req_base_effects[i]) {
545 els->base_effects.effect_present[peffect->type] = TRUE;
546 break;
547 }
548 }
549 for (i = 0; req_base_effects_3_2[i] != EFT_COUNT; i++) {
550 if (peffect->type == req_base_effects_3_2[i]) {
551 els->base_effects.effect_present[peffect->type] = TRUE;
552 break;
553 }
554 }
555
557 /* Only unit targets can pay in move fragments. */
559 if (preq->source.kind == VUT_ACTION) {
560 if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
561 /* TODO: support for ATK_UNITS could be added. That would require
562 * manually calling action_success_target_pay_mp() in each
563 * supported unit stack targeted action performer (like
564 * action_consequence_success() does) or to have the unit stack
565 * targeted actions return a list of targets. */
566 ruleset_error(els->logger, LOG_ERROR,
567 _("The effect Action_Success_Target_Move_Cost has the"
568 " requirement {%s} but the action %s isn't"
569 " (single) unit targeted."),
571 universal_rule_name(&preq->source));
572 astr_free(&astr);
573 return FALSE;
574 }
575 }
577 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
578 /* Only unit actors can pay in move fragments. */
580 if (preq->source.kind == VUT_ACTION && preq->present) {
581 if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
582 ruleset_error(els->logger, LOG_ERROR,
583 _("The effect Action_Success_Actor_Move_Cost has the"
584 " requirement {%s} but the action %s isn't"
585 " performed by a unit."),
587 universal_rule_name(&preq->source));
588 astr_free(&astr);
589 return FALSE;
590 }
591 }
593 } else if (peffect->type == EFT_ACTION_ODDS_PCT
594 || peffect->type == EFT_ACTION_RESIST_PCT) {
595 /* Catch trying to set Action_Odds_Pct for non supported actions. */
597 if (preq->source.kind == VUT_ACTION && preq->present) {
598 if (action_dice_roll_initial_odds(preq->source.value.action)
600 ruleset_error(els->logger, LOG_ERROR,
601 _("The effect %s has the"
602 " requirement {%s} but the action %s doesn't"
603 " roll the dice to see if it fails."),
606 universal_rule_name(&preq->source));
607 astr_free(&astr);
608 return FALSE;
609 }
610 }
612 }
613
614 if (!sanity_check_req_vec(els->logger, &peffect->reqs, TRUE, one_tile,
615 effect_type_name(peffect->type))) {
616 ruleset_error(els->logger, LOG_ERROR,
617 _("Effects have conflicting or invalid requirements!"));
618
619 return FALSE;
620 }
621
622 return TRUE;
623}
624
625/**********************************************************************/
629{
630 if (num_role_units(L_BARBARIAN) > 0) {
632 ruleset_error(logger, LOG_ERROR, _("No role barbarian leader units"));
633 return FALSE;
634 }
636 ruleset_error(logger, LOG_ERROR, _("No role barbarian build units"));
637 return FALSE;
638 }
640 ruleset_error(logger, LOG_ERROR, _("No role barbarian ship units"));
641 return FALSE;
642 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
643 bool sea_capable = FALSE;
645
647 if (is_ocean(pterr)
648 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
650 break;
651 }
653
654 if (!sea_capable) {
655 ruleset_error(logger, LOG_ERROR,
656 _("Barbarian boat (%s) needs to be able to move at sea."),
657 utype_rule_name(u));
658 return FALSE;
659 }
660 }
662 ruleset_error(logger, LOG_ERROR, _("No role sea raider barbarian units"));
663 return FALSE;
664 }
665
668 if (ptype->transport_capacity <= 1) {
669 ruleset_error(logger, LOG_ERROR,
670 _("Barbarian boat %s has no capacity for both "
671 "leader and at least one man."),
673 return FALSE;
674 }
675
681 ruleset_error(logger, LOG_ERROR,
682 _("Barbarian boat %s cannot transport "
683 "barbarian cargo %s."),
686 return FALSE;
687 }
688 }
690 }
692 }
693
694 return TRUE;
695}
696
697/**********************************************************************/
701{
702 /* Check some required flags and roles etc: */
703 if (num_role_units(UTYF_SETTLERS) == 0) {
704 ruleset_error(logger, LOG_ERROR, _("No flag Settler units"));
705 return FALSE;
706 }
708 ruleset_error(logger, LOG_ERROR, _("No role Start Explorer units"));
709 return FALSE;
710 }
711 if (num_role_units(L_FERRYBOAT) == 0) {
712 ruleset_error(logger, LOG_ERROR, _("No role Ferryboat units"));
713 return FALSE;
714 }
715 if (num_role_units(L_FIRSTBUILD) == 0) {
716 ruleset_error(logger, LOG_ERROR, _("No role Firstbuild units"));
717 return FALSE;
718 }
719
720 if (num_role_units(L_FERRYBOAT) > 0) {
721 bool sea_capable = FALSE;
722 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
723
725 if (is_ocean(pterr)
726 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
728 break;
729 }
731
732 if (!sea_capable) {
733 ruleset_error(logger, LOG_ERROR,
734 _("Ferryboat (%s) needs to be able to move at sea."),
735 utype_rule_name(u));
736 return FALSE;
737 }
738 }
739
740 if (num_role_units(L_PARTISAN) == 0
742 ruleset_error(logger, LOG_ERROR,
743 _("Inspire_Partisans effect present, "
744 "but no units with partisan role."));
745 return FALSE;
746 }
747
749 bool cargo = FALSE;
750
752 if (BV_ISSET(ptype->cargo, uclass_index(pclass))) {
753 cargo = TRUE;
754 break;
755 }
757
758 if (ptype->transport_capacity > 0) {
759 if (!cargo) {
760 ruleset_error(logger, LOG_ERROR,
761 _("%s has transport capacity %d, but no cargo types."),
762 utype_rule_name(ptype), ptype->transport_capacity);
763 return FALSE;
764 }
765 } else if (cargo) {
766 ruleset_error(logger, LOG_ERROR,
767 _("%s has cargo types, but no transport capacity."),
769 return FALSE;
770 }
772
773 return TRUE;
774}
775
776/**********************************************************************/
780{
781 /* Special Genus */
783 if (improvement_has_flag(pimprove, IF_GOLD)
784 && pimprove->genus != IG_CONVERT) {
785 ruleset_error(logger, LOG_ERROR,
786 _("Gold producing improvement %s with genus other than \"Convert\""),
787 improvement_rule_name(pimprove));
788
789 return FALSE;
790 }
792 && pimprove->genus != IG_IMPROVEMENT) {
793 ruleset_error(logger, LOG_ERROR,
794 _("Disasterproof improvement %s with genus other than \"Improvement\""),
795 improvement_rule_name(pimprove));
796
797 return FALSE;
798 }
799 if (pimprove->genus != IG_SPECIAL
805 RPT_POSSIBLE, FALSE))) {
806 ruleset_error(logger, LOG_ERROR,
807 _("Space part %s with genus other than \"Special\""),
808 improvement_rule_name(pimprove));
809 return FALSE;
810 }
811
812 if (!is_building_sellable(pimprove) && pimprove->upkeep != 0) {
813 ruleset_error(logger, LOG_ERROR,
814 _("%s is a nonsellable building with a nonzero upkeep value"),
815 improvement_rule_name(pimprove));
816 return FALSE;
817 }
819
820 return TRUE;
821}
822
823/**********************************************************************/
827{
828 enum effect_type boolean_effects[] =
829 {
853 };
854 int i;
855 bool ret = TRUE;
856
857 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
860 ruleset_error(logger, LOG_ERROR,
861 _("Boolean effect %s can get disabled, but it can't get "
862 "enabled before that."),
864 ret = FALSE;
865 }
866 }
867
868 return ret;
869}
870
871/**********************************************************************/
879{
880 int num_utypes;
881 int i;
882 bool ok = TRUE; /* Store failures to variable instead of returning
883 * immediately so all errors get printed, not just first
884 * one. */
888 rs_conversion_logger logger = ((compat != NULL) ? compat->log_cb : NULL);
889
890 if (!sanity_check_metadata(logger)) {
891 ok = FALSE;
892 }
893
896 ruleset_error(logger, LOG_ERROR,
897 _("Cost based free tech method, but tech cost style "
898 "\"Civ I|II\" so all techs cost the same."));
899 ok = FALSE;
900 }
901
902 /* Advances. */
904 for (i = AR_ONE; i < AR_SIZE; i++) {
905 const struct advance *preq;
906
907 if (i == AR_ROOT) {
908 /* Self rootreq is a feature. */
909 continue;
910 }
911
913
914 if (A_NEVER == preq) {
915 continue;
916 } else if (preq == padvance) {
917 ruleset_error(logger, LOG_ERROR, _("Tech \"%s\" requires itself."),
919 ok = FALSE;
920 continue;
921 }
922
924 if (preqreq == padvance) {
925 ruleset_error(logger, LOG_ERROR,
926 _("Tech \"%s\" requires itself indirectly via \"%s\"."),
929 ok = FALSE;
930 }
932 }
933
934 requirement_vector_iterate(&(padvance->research_reqs), preq) {
935 if (preq->source.kind == VUT_ADVANCE) {
936 /* Don't allow this even if allowing changing reqs. Players will
937 * expect all tech reqs to appear in the client tech tree. That
938 * should be taken care of first. */
939 ruleset_error(logger, LOG_ERROR,
940 _("Tech \"%s\" requires a tech in its research_reqs."
941 " This isn't supported yet. Please keep using req1"
942 " and req2 like before."),
944 ok = FALSE;
946 /* If we get an obsolete improvement before the game,
947 * almost surely it is going to become not obsolete later.
948 * This check must catch it. */) {
949 struct astring astr;
950
951 /* Only support unchanging requirements until the reachability code
952 * can handle it and the tech tree can display changing
953 * requirements. */
954 ruleset_error(logger, LOG_ERROR,
955 _("Tech \"%s\" has the requirement %s in its"
956 " research_reqs. This requirement may change during"
957 " the game. Changing requirements aren't supported"
958 " yet."),
961 astr_free(&astr);
962 ok = FALSE;
963 }
965
966 if (padvance->bonus_message != NULL) {
967 if (!formats_match(padvance->bonus_message, "%s")) {
968 ruleset_error(logger, LOG_ERROR,
969 _("Tech \"%s\" bonus message is not format with %%s "
970 "for a bonus tech name."),
972 ok = FALSE;
973 }
974 }
976
978 ruleset_error(logger, LOG_ERROR,
979 _("The government form %s reserved for revolution handling "
980 "has been set as default_government."),
982 ok = FALSE;
984 }
985
986 /* Check that all players can have their initial techs */
988 int techi;
989
990 /* Check global initial techs */
991 for (techi = 0; techi < MAX_NUM_TECH_LIST
994 struct advance *a = valid_advance_by_number(tech);
995
996 if (a == NULL) {
997 ruleset_error(logger, LOG_ERROR,
998 _("Tech %s does not exist, but is initial "
999 "tech for everyone."),
1001 ok = FALSE;
1002 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1003 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1004 /* Nation has no root_req for tech */
1005 ruleset_error(logger, LOG_ERROR,
1006 _("Tech %s is initial for everyone, but %s has "
1007 "no root_req for it."),
1009 nation_rule_name(pnation));
1010 ok = FALSE;
1011 }
1012 }
1013
1014 /* Check national initial techs */
1015 for (techi = 0;
1016 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
1017 techi++) {
1018 Tech_type_id tech = pnation->init_techs[techi];
1019 struct advance *a = valid_advance_by_number(tech);
1020
1021 if (a == NULL) {
1022 ruleset_error(logger, LOG_ERROR,
1023 _("Tech %s does not exist, but is initial tech for %s."),
1025 nation_rule_name(pnation));
1026 ok = FALSE;
1027 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1028 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1029 /* Nation has no root_req for tech */
1030 ruleset_error(logger, LOG_ERROR,
1031 _("Tech %s is initial for %s, but they have "
1032 "no root_req for it."),
1034 nation_rule_name(pnation));
1035 ok = FALSE;
1036 }
1037 }
1038
1039 /* Check national initial buildings */
1041 && pnation->init_buildings[0] != B_LAST) {
1042 ruleset_error(logger, LOG_ERROR,
1043 _("Barbarian nation %s has init_buildings set but will "
1044 "never see them"), nation_rule_name(pnation));
1045 }
1046
1047 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
1048 ruleset_error(logger, LOG_ERROR,
1049 _("The government form %s reserved for revolution "
1050 "handling has been set as initial government for %s."),
1052 nation_rule_name(pnation));
1053 ok = FALSE;
1054 }
1056
1057 /* Check against unit upgrade loops */
1060 int chain_length = 0;
1061 const struct unit_type *upgraded = putype;
1062
1063 while (upgraded != NULL && !obsoleted_by_loop) {
1065 chain_length++;
1066 if (chain_length > num_utypes) {
1067 ruleset_error(logger, LOG_ERROR,
1068 _("There seems to be obsoleted_by loop in update "
1069 "chain that starts from %s"),
1071 ok = FALSE;
1073 }
1074 }
1076
1077 /* Some unit type properties depend on other unit type properties to work
1078 * properly. */
1080 /* "Spy" is a better "Diplomat". Until all the places that assume that
1081 * "Diplomat" is set if "Spy" is set is changed this limitation must be
1082 * kept. */
1085 ruleset_error(logger, LOG_ERROR,
1086 _("The unit type '%s' has the 'Spy' unit type flag but "
1087 "not the 'Diplomat' unit type flag."),
1089 ok = FALSE;
1090 }
1092
1093 /* Check that unit type fields are in range. */
1095 if (putype->paratroopers_range < 0
1096 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
1097 /* Paradrop range is limited by the network protocol. */
1098 ruleset_error(logger, LOG_ERROR,
1099 _("The paratroopers_range of the unit type '%s' is %d. "
1100 "That is out of range. Max range is %d."),
1102 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
1103 ok = FALSE;
1104 }
1105 /* never fires if game.scenario.prevent_new_cities is TRUE */
1106 if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE)
1108 ruleset_error(logger, LOG_ERROR,
1109 _("Unit type '%s' would build size %d cities. "
1110 "City sizes must be from 1 to %d."),
1111 utype_rule_name(putype), putype->city_size,
1113 ok = FALSE;
1114 }
1116
1117 memset(&els, 0, sizeof(els));
1118 els.logger = logger;
1119
1120 /* Check requirement sets against conflicting requirements.
1121 * For effects check also other sanity in the same iteration */
1123 ok = FALSE;
1124 }
1125
1126 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
1127 if (!els.base_effects.effect_present[req_base_effects[i]]) {
1128 ruleset_error(logger, LOG_ERROR,
1129 _("There is no base %s effect."),
1131 ok = FALSE;
1132 }
1133 }
1134 for (i = 0; req_base_effects_3_2[i] != EFT_COUNT; i++) {
1135 if (!els.base_effects.effect_present[req_base_effects_3_2[i]]) {
1137
1138 if (compat != NULL && compat->compat_mode && compat->version < RSFORMAT_3_2) {
1139 log_deprecation("There is no base %s effect.", ename);
1140 if (compat->log_cb != NULL) {
1141 char buf[512];
1142
1143 fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename);
1144 compat->log_cb(buf);
1145 }
1146 } else {
1147 ruleset_error(logger, LOG_ERROR,
1148 _("There is no base %s effect."), ename);
1149 ok = FALSE;
1150 }
1151 }
1152 }
1153
1154 if (!sanity_check_boolean_effects(logger)) {
1155 ok = FALSE;
1156 }
1157
1158 /* Others use requirement vectors */
1159
1160 /* Disasters */
1162 if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1,
1164 ruleset_error(logger, LOG_ERROR,
1165 _("Disasters have conflicting or invalid requirements!"));
1166 ok = FALSE;
1167 }
1169
1170 /* Goods */
1172 if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1,
1174 ruleset_error(logger, LOG_ERROR,
1175 _("Goods have conflicting or invalid requirements!"));
1176 ok = FALSE;
1177 }
1179
1180 /* Buildings */
1182 if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1,
1183 improvement_rule_name(pimprove))) {
1184 ruleset_error(logger, LOG_ERROR,
1185 _("Buildings have conflicting or invalid requirements!"));
1186 ok = FALSE;
1187 }
1188 if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1,
1189 improvement_rule_name(pimprove))) {
1190 ruleset_error(logger, LOG_ERROR,
1191 _("Buildings have conflicting or invalid obsolescence req!"));
1192 ok = FALSE;
1193 }
1195
1196 /* Governments */
1198 if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1,
1200 ruleset_error(logger, LOG_ERROR,
1201 _("Governments have conflicting or invalid requirements!"));
1202 ok = FALSE;
1203 }
1205
1206 /* Specialists */
1208 if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1,
1209 specialist_rule_name(psp))) {
1210 ruleset_error(logger, LOG_ERROR,
1211 _("Specialists have conflicting or invalid requirements!"));
1212 ok = FALSE;
1213 }
1215
1216 /* Extras */
1218 if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1,
1219 extra_rule_name(pextra))) {
1220 ruleset_error(logger, LOG_ERROR,
1221 _("Extras have conflicting or invalid requirements!"));
1222 ok = FALSE;
1223 }
1224 if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1,
1225 extra_rule_name(pextra))) {
1226 ruleset_error(logger, LOG_ERROR,
1227 _("Extras have conflicting or invalid removal requirements!"));
1228 ok = FALSE;
1229 }
1230 if ((requirement_vector_size(&pextra->rmreqs) > 0)
1231 && !(pextra->rmcauses
1232 & (ERM_ENTER | ERM_CLEAN | ERM_PILLAGE))) {
1233 ruleset_error(logger, LOG_WARN,
1234 _("Requirements for extra removal defined but not "
1235 "a valid remove cause!"));
1236 }
1238
1239 /* Roads */
1241 struct road_type *proad = extra_road_get(pextra);
1242
1243 extra_type_list_iterate(proad->integrators, iextra) {
1245 int pnbr = road_number(proad);
1246
1247 if (pnbr != road_number(iroad)
1248 && !BV_ISSET(iroad->integrates, pnbr)) {
1249 /* We don't support non-symmetric integrator relationships yet. */
1250 ruleset_error(logger, LOG_ERROR,
1251 _("Road '%s' integrates with '%s' but not vice versa!"),
1252 extra_rule_name(pextra),
1254 ok = FALSE;
1255 }
1258
1259 /* City styles */
1260 for (i = 0; i < game.control.num_city_styles; i++) {
1261 if (!sanity_check_req_vec(logger, &city_styles[i].reqs, TRUE, -1,
1263 ruleset_error(logger, LOG_ERROR,
1264 _("City styles have conflicting or invalid requirements!"));
1265 ok = FALSE;
1266 }
1267 }
1268
1269 /* Actions */
1270 action_iterate(act) {
1271 struct action *paction = action_by_number(act);
1272
1273 if (!actres_legal_target_kind(paction->result, paction->target_kind)) {
1274 ruleset_error(logger, LOG_ERROR,
1275 _("Action \"%s\": unsupported target kind %s."),
1277 action_target_kind_name(paction->target_kind));
1278 ok = FALSE;
1279 }
1280
1281 if (paction->min_distance < 0) {
1282 ruleset_error(logger, LOG_ERROR,
1283 _("Action %s: negative min distance (%d)."),
1284 action_id_rule_name(act), paction->min_distance);
1285 ok = FALSE;
1286 }
1287
1288 if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) {
1289 ruleset_error(logger, LOG_ERROR,
1290 _("Action %s: min distance (%d) larger than "
1291 "any distance on a map can be (%d)."),
1292 action_id_rule_name(act), paction->min_distance,
1294 ok = FALSE;
1295 }
1296
1297 if (paction->max_distance > ACTION_DISTANCE_MAX) {
1298 ruleset_error(logger, LOG_ERROR,
1299 _("Action %s: max distance is %d. "
1300 "A map can't be that big."),
1301 action_id_rule_name(act), paction->max_distance);
1302 ok = FALSE;
1303 }
1304
1305 if (!action_distance_inside_max(paction, paction->min_distance)) {
1306 ruleset_error(logger, LOG_ERROR,
1307 _("Action %s: min distance is %d but max distance is %d."),
1309 paction->min_distance, paction->max_distance);
1310 ok = FALSE;
1311 }
1312
1313 action_iterate(blocker) {
1314 if (BV_ISSET(paction->blocked_by, blocker)
1315 && action_id_get_target_kind(blocker) == ATK_UNIT
1317 /* Can't find an individual unit target to evaluate the blocking
1318 * action against. (A tile may have more than one individual
1319 * unit) */
1320 ruleset_error(logger, LOG_ERROR,
1321 _("The action %s can't block %s."),
1322 action_id_rule_name(blocker),
1323 action_id_rule_name(act));
1324 ok = FALSE;
1325 }
1327
1329 if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1,
1330 "Action Enabler Actor Reqs")
1331 || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1,
1332 "Action Enabler Target Reqs")) {
1333 ruleset_error(logger, LOG_ERROR,
1334 _("Action enabler for %s has conflicting or invalid "
1335 "requirements!"), action_id_rule_name(act));
1336 ok = FALSE;
1337 }
1338
1340 /* Special test for self targeted actions. */
1341
1342 if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1343 /* Shouldn't have target requirements since the action doesn't
1344 * have a target. */
1345 ruleset_error(logger, LOG_ERROR,
1346 _("An action enabler for %s has a target "
1347 "requirement vector. %s doesn't have a target."),
1349 action_id_rule_name(act));
1350 ok = FALSE;
1351 }
1352 }
1353
1354 requirement_vector_iterate(&(enabler->target_reqs), preq) {
1355 if (preq->source.kind == VUT_DIPLREL
1356 && preq->range == REQ_RANGE_LOCAL) {
1357 struct astring astr;
1358
1359 /* A Local DiplRel requirement can be expressed as a requirement
1360 * in actor_reqs. Demand that it is there. This avoids breaking
1361 * code that reasons about actions. */
1362 ruleset_error(logger, LOG_ERROR,
1363 _("Action enabler for %s has a local DiplRel "
1364 "requirement %s in target_reqs! Please read the "
1365 "section \"Requirement vector rules\" in "
1366 "doc/README.actions"),
1369 astr_free(&astr);
1370 ok = FALSE;
1371 }
1373
1374 if (compat == NULL || !compat->compat_mode
1375 || compat->version >= RSFORMAT_3_2) {
1376 /* Support for letting some of the following hard requirements be
1377 * implicit were retired in Freeciv 3.0. Others were retired later.
1378 * Make sure that the opposite of each hard action requirement
1379 * blocks all its action enablers. */
1380
1381 struct req_vec_problem *problem
1383
1384 if (problem != NULL) {
1385 ruleset_error(logger, LOG_ERROR, "%s", problem->description);
1387 ok = FALSE;
1388 }
1389
1391 if (problem != NULL) {
1392 /* There is a potential for improving this enabler. */
1393 log_deprecation("%s", problem->description);
1395 }
1396 }
1398
1400 /* The action performer, action_dice_roll_initial_odds() and the
1401 * action probability calculation in action_prob() must probably all
1402 * be updated to add a new action here. */
1419 ruleset_error(logger, LOG_ERROR,
1420 _("diplchance_initial_odds: \"%s\" not supported."),
1422 ok = FALSE;
1423 }
1424
1425 if (BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER)
1426 && BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)) {
1427 ruleset_error(logger, LOG_ERROR,
1428 _("%s both enters and frightens a hut at the same time."),
1430 ok = FALSE;
1431 }
1433
1434 /* Auto attack */
1435 {
1437
1439
1441 struct action *paction = action_by_number(act_id);
1442
1447 /* Only allow removing and changing the order of old auto
1448 * attack actions for now. Other actions need more testing and
1449 * fixing of issues caused by a worst case action probability of
1450 * 0%. */
1451 ruleset_error(logger, LOG_ERROR,
1452 _("auto_attack: %s not supported in"
1453 " attack_actions."),
1455 ok = FALSE;
1456 }
1458 }
1459
1460 /* There must be basic city style for each nation style to start with */
1463 ruleset_error(logger, LOG_ERROR,
1464 _("There's no basic city style for nation style %s"),
1466 ok = FALSE;
1467 }
1469
1470 /* Music styles */
1472 if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) {
1473 ruleset_error(logger, LOG_ERROR,
1474 _("Music Styles have conflicting or invalid requirements!"));
1475 ok = FALSE;
1476 }
1478
1480 if (pterr->animal != NULL) {
1481 if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) {
1482 ruleset_error(logger, LOG_ERROR,
1483 _("%s has %s as animal to appear, but it's not native to the terrain."),
1485 ok = FALSE;
1486 }
1487 }
1488
1490 (void) freq;
1492 ruleset_error(logger, LOG_ERROR,
1493 _("%s has %s as a resource, but it's not a resource extra."),
1495 ok = FALSE;
1496 }
1499
1500 /* Check that all unit classes can exist somewhere */
1503 bool can_exist = FALSE;
1504
1506 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1507 can_exist = TRUE;
1508 break;
1509 }
1511
1512 if (!can_exist) {
1514 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1515 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1516 can_exist = TRUE;
1517 break;
1518 }
1520 }
1521
1522 if (!can_exist) {
1523 ruleset_error(logger, LOG_ERROR,
1524 _("Unit class %s cannot exist anywhere."),
1526 ok = FALSE;
1527 }
1528 }
1530
1532 if (!pach->unique && pach->cons_msg == NULL) {
1533 ruleset_error(logger, LOG_ERROR,
1534 _("Achievement %s has no message for consecutive gainers though "
1535 "it's possible to be gained by multiple players"),
1537 ok = FALSE;
1538 }
1540
1542 int nati;
1543
1545 struct nation_type *pnat
1547
1548 if (pnat == NULL) {
1549 ruleset_error(logger, LOG_ERROR,
1550 _("There's nation %s listed in embedded nations, but there's "
1551 "no such nation."),
1553 ok = FALSE;
1554 }
1555 }
1556 }
1557
1558 if (ok) {
1559 ok = rs_common_units(logger);
1560 }
1561 if (ok) {
1562 ok = rs_barbarian_units(logger);
1563 }
1564 if (ok) {
1565 ok = rs_buildings(logger);
1566 }
1567
1568 return ok;
1569}
1570
1571/**********************************************************************/
1577{
1578 bool ok = TRUE;
1579
1582 if (pextra != pextra2) {
1583 int idx = extra_index(pextra2);
1584
1585 if (!BV_ISSET(pextra->conflicts, idx)) {
1586 log_debug("Autoconflicting resource %s with %s",
1588 BV_SET(pextra->conflicts, extra_index(pextra2));
1589 }
1590 }
1593
1594 /* Hard coded action blocking. */
1595 {
1596 const struct {
1597 const enum action_result blocked;
1598 const enum action_result blocker;
1599 } must_block[] = {
1600 /* Hard code that Help Wonder blocks Disband Unit Recover. This must be done
1601 * because caravan_shields makes it possible to avoid the
1602 * consequences of choosing to do Disband Unit Recover rather than having it
1603 * do Help Wonder.
1604 *
1605 * Explanation: Disband Unit Recover adds 50% of the shields used to produce
1606 * the unit to the production of the city where it is located. Help
1607 * Wonder adds 100%. If a unit that can do Help Wonder is disbanded with
1608 * production recovery in a city and the production later is changed
1609 * to something that can receive help from Help Wonder the remaining 50%
1610 * of the shields are added. This can be done because the city remembers
1611 * them in caravan_shields.
1612 *
1613 * If a unit that can do Help Wonder intentionally is disbanded with recovery
1614 * rather than making it do Help Wonder its shields will still be
1615 * remembered. The target city that got 50% of the shields can
1616 * therefore get 100% of them by changing its production. This trick
1617 * makes the ability to select Disband Unit Recover when Help Wonder is legal
1618 * pointless. */
1620
1621 /* Allowing regular disband when ACTION_HELP_WONDER or
1622 * ACTION_DISBAND_UNIT_RECOVER is legal while ACTION_HELP_WONDER always
1623 * blocks ACTION_DISBAND_UNIT_RECOVER doesn't work well with the force_*
1624 * semantics. Should move to the ruleset once it has blocked_by
1625 * semantics. */
1628
1629 /* Hard code that the ability to perform a regular attack blocks city
1630 * conquest. Is redundant as long as the requirement that the target
1631 * tile has no units remains hard coded. Kept "just in case" that
1632 * changes. */
1634
1635 /* Hard code that the ability to perform a regular attack blocks
1636 * extras conquest. Is redundant as long as the requirement that the
1637 * target tile has no non-allied units remains hard coded. Kept "just
1638 * in case" that changes. */
1640
1641 /* Hard code that the ability to enter or frighten a hut blocks
1642 * regular disembarking. */
1646 };
1647
1648 int i;
1649
1650 for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1651 enum action_result blocked_result = must_block[i].blocked;
1652 enum action_result blocker_result = must_block[i].blocker;
1653
1656 if (!action_would_be_blocked_by(blocked, blocker)) {
1657 log_verbose("Autoblocking %s with %s",
1658 action_rule_name(blocked),
1659 action_rule_name(blocker));
1660 BV_SET(blocked->blocked_by, action_id(blocker));
1661 }
1664 }
1665 }
1666
1667 return ok;
1668}
1669
1670/**********************************************************************/
1674{
1675 bool ok = TRUE;
1676
1677 if (num_role_units(L_BARBARIAN) == 0) {
1678 struct setting *pset = setting_by_name("barbarians");
1679
1680 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
1681 "unit types."));
1683 if (!setting_enum_set(pset, "DISABLED", NULL, NULL, 0)) {
1684 ok = FALSE;
1685 }
1687 }
1688
1689 return ok;
1690}
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:1934
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1859
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:6421
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2679
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2745
const char * action_rule_name(const struct action *action)
Definition actions.c:1977
const char * action_id_rule_name(action_id act_id)
Definition actions.c:2000
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1957
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:6097
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1869
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2315
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:481
#define ACTION_DISTANCE_MAX
Definition actions.h:359
#define enabler_get_action(_enabler_)
Definition actions.h:433
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:611
#define action_auto_perf_actions_iterate_end
Definition actions.h:602
static struct action * action_by_number(action_id act_id)
Definition actions.h:635
#define action_enabler_list_re_iterate_end
Definition actions.h:447
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:355
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:443
#define action_has_result(_act_, _res_)
Definition actions.h:431
#define action_by_result_iterate_end
Definition actions.h:485
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition actions.h:599
#define action_iterate_end
Definition actions.h:465
#define action_has_result_safe(paction, result)
Definition actions.h:663
#define action_iterate(_act_)
Definition actions.h:461
#define action_id_get_target_kind(act_id)
Definition actions.h:652
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:929
bool actres_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actres.c:555
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:1765
static const struct city struct citystyle * city_styles
Definition city.c:84
#define MAX_CITY_SIZE
Definition city.h:106
char * incite_cost
Definition comments.c:75
#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:1070
int Tech_type_id
Definition fc_types.h:377
int ssetv
Definition fc_types.h:693
@ RPT_POSSIBLE
Definition fc_types.h:700
int action_id
Definition fc_types.h:389
#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:129
#define governments_re_active_iterate_end
Definition government.h:133
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:878
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:493
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Definition rssanity.c:142
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:256
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:826
static bool sanity_check_setting_is_seen(struct setting *pset)
Definition rssanity.c:106
static bool sanity_check_req_individual(rs_conversion_logger logger, struct requirement *preq, const char *list_for)
Definition rssanity.c:169
static bool rs_buildings(rs_conversion_logger logger)
Definition rssanity.c:779
static bool sanity_check_metadata(rs_conversion_logger logger)
Definition rssanity.c:59
bool autolock_settings(void)
Definition rssanity.c:1673
static bool rs_common_units(rs_conversion_logger logger)
Definition rssanity.c:700
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1576
static bool rs_barbarian_units(rs_conversion_logger logger)
Definition rssanity.c:628
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Definition rssanity.c:535
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Definition rssanity.c:115
static bool nation_has_initial_tech(struct nation_type *pnation, struct advance *tech)
Definition rssanity.c:77
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:105
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:4709
struct setting * setting_by_name(const char *name)
Definition settings.c:3306
struct setting * setting_by_number(int id)
Definition settings.c:3298
enum sset_category setting_category(const struct setting *pset)
Definition settings.c:3375
bool setting_enum_set(struct setting *pset, const char *val, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Definition settings.c:4019
void setting_ruleset_lock_set(struct setting *pset)
Definition settings.c:4689
bool setting_is_visible_at_level(const struct setting *pset, enum cmdlevel plevel)
Definition settings.c:3493
bool formats_match(const char *format1, const char *format2)
Definition shared.c:2445
#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:110
struct packet_game_info info
Definition game.h:89
char ** embedded_nations
Definition game.h:286
struct civ_game::@31::@35::@40 ruledit
struct civ_game::@31::@35 server
size_t embedded_nations_count
Definition game.h:287
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:529
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
bv_unit_classes cargo
Definition unittype.h:558
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:2965
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:867
#define utype_class(_t_)
Definition unittype.h:749
#define unit_class_iterate(_p)
Definition unittype.h:908
#define unit_class_re_active_iterate_end
Definition unittype.h:924
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_type_iterate(_p)
Definition unittype.h:855
#define unit_class_re_active_iterate(_p)
Definition unittype.h:920
#define UNIT_MAX_PARADROP_RANGE
Definition unittype.h:56
#define uclass_index(_c_)
Definition unittype.h:742
#define unit_class_iterate_end
Definition unittype.h:915
#define unit_type_iterate_end
Definition unittype.h:862
#define unit_type_re_active_iterate_end
Definition unittype.h:871