Freeciv-3.3
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 "ruleload.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 {
48 };
49
50/* These have been made mandatory in freeciv-3.3 */
51enum effect_type req_base_effects_3_3[] =
52 {
53 /* None yet */
55 };
56
57/**********************************************************************/
61{
64 ruleset_error(logger,
66 _("Too long ruleset summary. It can be only %d bytes long. "
67 "Put longer explanations to ruleset description."),
69 return FALSE;
70 }
71
72 return TRUE;
73}
74
75/**********************************************************************/
78static bool nation_has_initial_tech(struct nation_type *pnation,
79 struct advance *tech)
80{
81 int i;
82
83 /* See if it's given as global init tech */
84 for (i = 0; i < MAX_NUM_TECH_LIST
87 return TRUE;
88 }
89 }
90
91 /* See if it's given as national init tech */
92 for (i = 0;
93 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
94 i++) {
95 if (pnation->init_techs[i] == advance_number(tech)) {
96 return TRUE;
97 }
98 }
99
100 return FALSE;
101}
102
103/**********************************************************************/
111
112/**********************************************************************/
117{
120 /* White list for SSET_INTERNAL and SSET_NETWORK settings. */
121 && !(pset == setting_by_name("phasemode")
122 || pset == setting_by_name("timeout")
123 || pset == setting_by_name("timeaddenemymove")
124 || pset == setting_by_name("unitwaittime")
125 || pset == setting_by_name("victories"))) {
126 /* The given server setting is a server operator related setting (like
127 * the compression type of savegames), not a game rule. */
128 return FALSE;
129 }
130
131 if (pset == setting_by_name("naturalcitynames")) {
132 /* This setting is about "look", not rules. */
133 return FALSE;
134 }
135
136 return TRUE;
137}
138
139/**********************************************************************/
144{
146 struct setting *pset;
147
148 /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
149 * the server setting id. */
150 id = (server_setting_id)ssetval;
152
154 /* Not supported yet. */
155 return FALSE;
156 }
157
159
162}
163
164/**********************************************************************/
171 struct requirement *preq,
172 const char *list_for)
173{
174 switch (preq->source.kind) {
175 case VUT_IMPROVEMENT:
176 case VUT_SITE:
177 /* This check corresponds to what is_req_active() will support.
178 * It can't be done in req_from_str(), as we may not have
179 * loaded all building information at that time. */
180 {
181 const struct impr_type *pimprove = preq->source.value.building;
182
183 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
184 ruleset_error(logger, LOG_ERROR,
185 _("%s: World-ranged requirement not supported for "
186 "%s (only great wonders supported)"), list_for,
188 return FALSE;
189 } else if (preq->range > REQ_RANGE_TRADE_ROUTE && !is_wonder(pimprove)) {
190 ruleset_error(logger, LOG_ERROR,
191 _("%s: %s-ranged requirement not supported for "
192 "%s (only wonders supported)"), list_for,
193 req_range_name(preq->range),
195 return FALSE;
196 }
197 }
198 break;
199 case VUT_MINCALFRAG:
200 /* Currently [calendar] is loaded after some requirements are
201 * parsed, so we can't do this in universal_value_from_str(). */
203 ruleset_error(logger, LOG_ERROR,
204 _("%s: MinCalFrag requirement used in ruleset without "
205 "calendar fragments"), list_for);
206 return FALSE;
207 } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) {
208 ruleset_error(logger, LOG_ERROR,
209 _("%s: MinCalFrag requirement %d out of range (max %d in "
210 "this ruleset)"), list_for, preq->source.value.mincalfrag,
212 return FALSE;
213 }
214 break;
216 /* There is currently no way to check a server setting's category and
217 * access level that works in both the client and the server. */
218 {
220 struct setting *pset;
221
222 id = ssetv_setting_get(preq->source.value.ssetval);
225
227 ruleset_error(logger, LOG_ERROR,
228 _("%s: ServerSetting requirement %s isn't visible enough "
229 "to appear in a requirement. Everyone should be able to "
230 "see the value of a server setting that appears in a "
231 "requirement."), list_for, server_setting_name_get(id));
232 return FALSE;
233 }
234
236 /* This is a server operator related setting (like the compression
237 * type of savegames), not a game rule. */
238 ruleset_error(logger, LOG_ERROR,
239 _("%s: ServerSetting requirement setting %s isn't about a "
240 "game rule."),
242 return FALSE;
243 }
244 }
245 break;
246 default:
247 /* No other universals have checks that can't be done at ruleset
248 * load time. See req_from_str(). */
249 break;
250 }
251 return TRUE;
252}
253
254/**********************************************************************/
258 int reqs_of_type[],
259 int local_reqs_of_type[],
260 int tile_reqs_of_type[],
261 struct requirement *preq, bool conjunctive,
262 int max_tiles, const char *list_for)
263{
264 int rc;
265
267
269 return FALSE;
270 }
271
272 if (!conjunctive) {
273 /* All the checks below are only meaningful for conjunctive lists. */
274 /* FIXME: we could add checks suitable for disjunctive lists. */
275 return TRUE;
276 }
277
278 /* Add to counter for positive requirements. */
279 if (preq->present) {
280 reqs_of_type[preq->source.kind]++;
281 }
282 rc = reqs_of_type[preq->source.kind];
283
284 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
285 local_reqs_of_type[preq->source.kind]++;
286
287 switch (preq->source.kind) {
288 case VUT_EXTRA:
289 if (local_reqs_of_type[VUT_EXTRA] > 1) {
290 ruleset_error(logger, LOG_ERROR,
291 _("%s: Requirement list has multiple local-ranged extra "
292 "requirements (did you mean to make them tile-ranged?)"),
293 list_for);
294 return FALSE;
295 }
296 break;
297 default:
298 break;
299 }
300 }
301
302 if (preq->range == REQ_RANGE_TILE && preq->present) {
303 tile_reqs_of_type[preq->source.kind]++;
304
305 switch (preq->source.kind) {
306 case VUT_TERRAINCLASS:
308 ruleset_error(logger, LOG_ERROR,
309 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
310 list_for);
311 return FALSE;
312 }
313 break;
314 case VUT_TERRAIN:
316 ruleset_error(logger, LOG_ERROR,
317 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
318 list_for);
319 return FALSE;
320 }
321 break;
322 case VUT_MINLATITUDE:
323 case VUT_MAXLATITUDE:
324 if (tile_reqs_of_type[preq->range] > 1) {
325 ruleset_error(logger, LOG_ERROR,
326 _("%s: Requirement list has duplicate %s requirement at Tile range"),
328 return FALSE;
329 }
330 break;
331 default:
332 break;
333 }
334 }
335
336 if (rc > 1 && preq->present) {
337 /* Multiple requirements of the same type */
338 switch (preq->source.kind) {
339 case VUT_GOVERNMENT:
340 case VUT_ACTION:
341 case VUT_ACTIVITY:
342 case VUT_OTYPE:
343 case VUT_SPECIALIST:
344 case VUT_MINSIZE: /* Breaks nothing, but has no sense either */
345 case VUT_MINCITIES:
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 case VUT_MAX_DISTANCE_SQ: /* Breaks nothing, but has no sense either */
359 /* There can be only one requirement of these types (with current
360 * range limitations)
361 * Requirements might be identical, but we consider multiple
362 * declarations error anyway. */
363
364 ruleset_error(logger, LOG_ERROR,
365 _("%s: Requirement list has multiple %s requirements"),
367 return FALSE;
368 break;
369
370 case VUT_TERRAIN:
371 /* There can be only up to max_tiles requirements of these types */
372 if (max_tiles != -1 && rc > max_tiles) {
373 ruleset_error(logger, LOG_ERROR,
374 _("%s: Requirement list has more %s requirements than "
375 "can ever be fulfilled."), list_for,
377 return FALSE;
378 }
379 break;
380
381 case VUT_TERRAINCLASS:
382 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
383 ruleset_error(logger, LOG_ERROR,
384 _("%s: Requirement list has more %s requirements than "
385 "can ever be fulfilled."), list_for,
387 return FALSE;
388 }
389 break;
390
391 case VUT_AGE:
392 /* There can be age of the city, unit, and player */
393 if (rc > 3) {
394 ruleset_error(logger, LOG_ERROR,
395 _("%s: Requirement list has more %s requirements than "
396 "can ever be fulfilled."), list_for,
398 return FALSE;
399 }
400 break;
401
402 case VUT_MINTECHS:
403 /* At ranges 'Player' and 'World' */
404 if (rc > 2) {
405 ruleset_error(logger, LOG_ERROR,
406 _("%s: Requirement list has more %s requirements than "
407 "can ever be fulfilled."), list_for,
409 return FALSE;
410 }
411 break;
412
413 case VUT_COUNTER:
414 /* Can have multiple, since many counters (also of the same range)
415 * can meet checkpoint */
417 /* Can have multiple, since there are many settings. */
418 case VUT_TOPO:
419 /* Can have multiple, since it's flag based (iso & hex) */
420 case VUT_WRAP:
421 /* Can have multiple, since it's flag based (wrapx & wrapy) */
422 case VUT_EXTRA:
423 /* Note that there can be more than 1 extra / tile. */
424 case VUT_MAXTILEUNITS:
425 /* Can require different numbers on e.g. local/adjacent tiles. */
426 case VUT_NATION:
427 /* Can require multiple nations at Team/Alliance/World range. */
428 case VUT_NATIONGROUP:
429 /* Nations can be in multiple groups. */
430 case VUT_NONE:
431 case VUT_ADVANCE:
432 case VUT_TECHFLAG:
433 case VUT_IMPROVEMENT:
434 case VUT_SITE:
435 case VUT_UNITSTATE:
436 case VUT_CITYTILE:
437 case VUT_GOOD:
438 case VUT_UTYPE:
439 case VUT_UCLASS:
440 case VUT_TILE_REL:
441 /* Can check different properties. */
442 case VUT_UTFLAG:
443 case VUT_UCFLAG:
444 case VUT_TERRFLAG:
445 case VUT_ROADFLAG:
446 case VUT_EXTRAFLAG:
447 case VUT_IMPR_FLAG:
448 case VUT_PLAYER_FLAG:
449 case VUT_PLAYER_STATE:
450 case VUT_NATIONALITY:
451 case VUT_MINCULTURE:
452 case VUT_ACHIEVEMENT:
453 case VUT_DIPLREL:
454 case VUT_DIPLREL_TILE:
458 /* Can have multiple requirements of these types */
459 case VUT_MINLATITUDE:
460 case VUT_MAXLATITUDE:
462 /* Can have multiple requirements at different ranges.
463 * TODO: Compare to number of legal ranges? */
464 break;
465 case VUT_CITYSTATUS:
466 /* Could check "CITYS_LAST * number of ranges" ? */
467 break;
468 case VUT_COUNT:
469 /* Should never be in requirement vector */
471 return FALSE;
472 break;
473 /* No default handling here, as we want compiler warning
474 * if new requirement type is added to enum and it's not handled
475 * here. */
476 }
477 }
478
479 return TRUE;
480}
481
482/**********************************************************************/
499 const struct requirement_vector *preqs,
500 bool conjunctive, int max_tiles,
501 const char *list_for)
502{
503 struct req_vec_problem *problem;
507
508 /* Initialize requirement counters */
509 memset(reqs_of_type, 0, sizeof(reqs_of_type));
511
516 return FALSE;
517 }
519
521 if (problem != NULL) {
522 ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description);
524 return FALSE;
525 }
526
527 return TRUE;
528}
529
530typedef struct {
531 struct {
532 bool effect_present[EFT_COUNT];
533 } base_effects;
535} els_data;
536
537/**********************************************************************/
540static bool effect_list_sanity_cb(struct effect *peffect, void *data)
541{
542 int one_tile = -1; /* TODO: Determine correct value from effect.
543 * -1 disables checking */
544 els_data *els = (els_data *)data;
545 struct astring astr;
546 int i;
547
548 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
549 if (peffect->type == req_base_effects[i]) {
550 els->base_effects.effect_present[peffect->type] = TRUE;
551 break;
552 }
553 }
554 for (i = 0; req_base_effects_3_3[i] != EFT_COUNT; i++) {
555 if (peffect->type == req_base_effects_3_3[i]) {
556 els->base_effects.effect_present[peffect->type] = TRUE;
557 break;
558 }
559 }
560
562 /* Only unit targets can pay in move fragments. */
564 if (preq->source.kind == VUT_ACTION) {
565 if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
566 /* TODO: support for ATK_STACK could be added. That would require
567 * manually calling action_success_target_pay_mp() in each
568 * supported unit stack targeted action performer (like
569 * action_consequence_success() does) or to have the unit stack
570 * targeted actions return a list of targets. */
571 ruleset_error(els->logger, LOG_ERROR,
572 _("The effect Action_Success_Target_Move_Cost has the"
573 " requirement {%s} but the action %s isn't"
574 " (single) unit targeted."),
576 universal_rule_name(&preq->source));
577 astr_free(&astr);
578 return FALSE;
579 }
580 }
582 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
583 /* Only unit actors can pay in move fragments. */
585 if (preq->source.kind == VUT_ACTION && preq->present) {
586 if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
587 ruleset_error(els->logger, LOG_ERROR,
588 _("The effect Action_Success_Actor_Move_Cost has the"
589 " requirement {%s} but the action %s isn't"
590 " performed by a unit."),
592 universal_rule_name(&preq->source));
593 astr_free(&astr);
594 return FALSE;
595 }
596 }
598 } else if (peffect->type == EFT_ACTION_ODDS_PCT
599 || peffect->type == EFT_ACTION_RESIST_PCT) {
600 /* Catch trying to set Action_Odds_Pct for non supported actions. */
602 if (preq->source.kind == VUT_ACTION && preq->present) {
603 if (action_dice_roll_initial_odds(preq->source.value.action)
605 ruleset_error(els->logger, LOG_ERROR,
606 _("The effect %s has the"
607 " requirement {%s} but the action %s doesn't"
608 " roll the dice to see if it fails."),
611 universal_rule_name(&preq->source));
612 astr_free(&astr);
613 return FALSE;
614 }
615 }
617 }
618
619 if (!sanity_check_req_vec(els->logger, &peffect->reqs, TRUE, one_tile,
620 effect_type_name(peffect->type))) {
621 ruleset_error(els->logger, LOG_ERROR,
622 _("Effects have conflicting or invalid requirements!"));
623
624 return FALSE;
625 }
626
627 return TRUE;
628}
629
630/**********************************************************************/
634{
635 if (num_role_units(L_BARBARIAN) > 0) {
637 ruleset_error(logger, LOG_ERROR, _("No role barbarian leader units"));
638 return FALSE;
639 }
641 ruleset_error(logger, LOG_ERROR, _("No role barbarian build units"));
642 return FALSE;
643 }
645 ruleset_error(logger, LOG_ERROR, _("No role barbarian ship units"));
646 return FALSE;
647 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
648 bool sea_capable = FALSE;
650
652 if (is_ocean(pterr)
653 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
655 break;
656 }
658
659 if (!sea_capable) {
660 ruleset_error(logger, LOG_ERROR,
661 _("Barbarian boat (%s) needs to be able to move at sea."),
662 utype_rule_name(u));
663 return FALSE;
664 }
665 }
667 ruleset_error(logger, LOG_ERROR, _("No role sea raider barbarian units"));
668 return FALSE;
669 }
670
673 if (ptype->transport_capacity <= 1) {
674 ruleset_error(logger, LOG_ERROR,
675 _("Barbarian boat %s has no capacity for both "
676 "leader and at least one man."),
678 return FALSE;
679 }
680
686 ruleset_error(logger, LOG_ERROR,
687 _("Barbarian boat %s cannot transport "
688 "barbarian cargo %s."),
691 return FALSE;
692 }
693 }
695 }
697 }
698
699 return TRUE;
700}
701
702/**********************************************************************/
706{
707 /* Check some required flags and roles etc: */
708 if (num_role_units(UTYF_WORKERS) == 0) {
709 ruleset_error(logger, LOG_ERROR, _("No flag Worker units"));
710 return FALSE;
711 }
713 ruleset_error(logger, LOG_ERROR, _("No role Start Explorer units"));
714 return FALSE;
715 }
716 if (num_role_units(L_FERRYBOAT) == 0) {
717 ruleset_error(logger, LOG_ERROR, _("No role Ferryboat units"));
718 return FALSE;
719 }
720 if (num_role_units(L_FIRSTBUILD) == 0) {
721 ruleset_error(logger, LOG_ERROR, _("No role Firstbuild units"));
722 return FALSE;
723 }
724
725 if (num_role_units(L_FERRYBOAT) > 0) {
726 bool sea_capable = FALSE;
727 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
728
730 if (is_ocean(pterr)
731 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
733 break;
734 }
736
737 if (!sea_capable) {
738 ruleset_error(logger, LOG_ERROR,
739 _("Ferryboat (%s) needs to be able to move at sea."),
740 utype_rule_name(u));
741 return FALSE;
742 }
743 }
744
745 if (num_role_units(L_PARTISAN) == 0
747 ruleset_error(logger, LOG_ERROR,
748 _("Inspire_Partisans effect present, "
749 "but no units with partisan role."));
750 return FALSE;
751 }
752
754 bool cargo = FALSE;
755
757 if (BV_ISSET(ptype->cargo, uclass_index(pclass))) {
758 cargo = TRUE;
759 break;
760 }
762
763 if (ptype->transport_capacity > 0) {
764 if (!cargo) {
765 ruleset_error(logger, LOG_ERROR,
766 _("%s has transport capacity %d, but no cargo types."),
767 utype_rule_name(ptype), ptype->transport_capacity);
768 return FALSE;
769 }
770 } else if (cargo) {
771 ruleset_error(logger, LOG_ERROR,
772 _("%s has cargo types, but no transport capacity."),
774 return FALSE;
775 }
777
778 return TRUE;
779}
780
781/**********************************************************************/
785{
786 /* Special Genus */
788 if (improvement_has_flag(pimprove, IF_GOLD)) {
789 if (pimprove->genus != IG_CONVERT) {
790 ruleset_error(logger, LOG_ERROR,
791 _("Gold producing improvement %s with genus other than \"Convert\""),
792 improvement_rule_name(pimprove));
793
794 return FALSE;
795 }
796 if (improvement_has_flag(pimprove, IF_INFRA)) {
797 ruleset_error(logger, LOG_ERROR,
798 _("The same improvement has both \"Gold\" and \"Infra\" flags"));
799 return FALSE;
800 }
801 } else if (improvement_has_flag(pimprove, IF_INFRA)) {
802 if (pimprove->genus != IG_CONVERT) {
803 ruleset_error(logger, LOG_ERROR,
804 _("Infrapoints producing improvement %s with genus other than \"Convert\""),
805 improvement_rule_name(pimprove));
806
807 return FALSE;
808 }
809 } else if (pimprove->genus == IG_CONVERT) {
810 ruleset_error(logger, LOG_ERROR,
811 _("Improvement %s with no conversion target with genus \"Convert\""),
812 improvement_rule_name(pimprove));
813 return FALSE;
814 }
815
817 && pimprove->genus != IG_IMPROVEMENT) {
818 ruleset_error(logger, LOG_ERROR,
819 _("Disasterproof improvement %s with genus other than \"Improvement\""),
820 improvement_rule_name(pimprove));
821
822 return FALSE;
823 }
824 if (pimprove->genus != IG_SPECIAL
830 RPT_POSSIBLE, FALSE))) {
831 ruleset_error(logger, LOG_ERROR,
832 _("Space part %s with genus other than \"Special\""),
833 improvement_rule_name(pimprove));
834 return FALSE;
835 }
836
837 if (!is_building_sellable(pimprove) && pimprove->upkeep != 0) {
838 ruleset_error(logger, LOG_ERROR,
839 _("%s is a nonsellable building with a nonzero upkeep value"),
840 improvement_rule_name(pimprove));
841 return FALSE;
842 }
844
845 return TRUE;
846}
847
848/**********************************************************************/
852{
853 enum effect_type boolean_effects[] =
854 {
878 };
879 int i;
880 bool ret = TRUE;
881
882 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
885 ruleset_error(logger, LOG_ERROR,
886 _("Boolean effect %s can get disabled, but it can't get "
887 "enabled before that."),
889 ret = FALSE;
890 }
891 }
892
893 return ret;
894}
895
896/**********************************************************************/
904{
905 int num_utypes;
906 int i;
907 bool ok = TRUE; /* Store failures to variable instead of returning
908 * immediately so all errors get printed, not just first
909 * one. */
913 rs_conversion_logger logger = ((compat != NULL) ? compat->log_cb : NULL);
914
915 if (!sanity_check_metadata(logger)) {
916 ok = FALSE;
917 }
918
921 ruleset_error(logger, LOG_ERROR,
922 _("Cost based free tech method, but tech cost style "
923 "\"Civ I|II\" so all techs cost the same."));
924 ok = FALSE;
925 }
926
927 /* Advances. */
929 for (i = AR_ONE; i < AR_SIZE; i++) {
930 const struct advance *preq;
931
932 if (i == AR_ROOT) {
933 /* Self rootreq is a feature. */
934 continue;
935 }
936
938
939 if (A_NEVER == preq) {
940 continue;
941 } else if (preq == padvance) {
942 ruleset_error(logger, LOG_ERROR, _("Tech \"%s\" requires itself."),
944 ok = FALSE;
945 continue;
946 }
947
949 if (preqreq == padvance) {
950 ruleset_error(logger, LOG_ERROR,
951 _("Tech \"%s\" requires itself indirectly via \"%s\"."),
954 ok = FALSE;
955 }
957 }
958
959 requirement_vector_iterate(&(padvance->research_reqs), preq) {
960 if (preq->source.kind == VUT_ADVANCE) {
961 /* Don't allow this even if allowing changing reqs. Players will
962 * expect all tech reqs to appear in the client tech tree. That
963 * should be taken care of first. */
964 ruleset_error(logger, LOG_ERROR,
965 _("Tech \"%s\" requires a tech in its research_reqs."
966 " This isn't supported yet. Please keep using req1"
967 " and req2 like before."),
969 ok = FALSE;
971 /* If we get an obsolete improvement before the game,
972 * almost surely it is going to become not obsolete later.
973 * This check must catch it. */) {
974 struct astring astr;
975
976 /* Only support unchanging requirements until the reachability code
977 * can handle it and the tech tree can display changing
978 * requirements. */
979 ruleset_error(logger, LOG_ERROR,
980 _("Tech \"%s\" has the requirement %s in its"
981 " research_reqs. This requirement may change during"
982 " the game. Changing requirements aren't supported"
983 " yet."),
986 astr_free(&astr);
987 ok = FALSE;
988 }
990
991 if (padvance->bonus_message != NULL) {
992 if (!formats_match(padvance->bonus_message, "%s")) {
993 ruleset_error(logger, LOG_ERROR,
994 _("Tech \"%s\" bonus message is not format with %%s "
995 "for a bonus tech name."),
997 ok = FALSE;
998 }
999 }
1001
1003 ruleset_error(logger, LOG_ERROR,
1004 _("The government form %s reserved for revolution handling "
1005 "has been set as default_government."),
1007 ok = FALSE;
1009 }
1010
1011 /* Check that all players can have their initial techs */
1012 nations_re_active_iterate(pnation) {
1013 int techi;
1014
1015 /* Check global initial techs */
1016 for (techi = 0; techi < MAX_NUM_TECH_LIST
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 "
1024 "tech for everyone."),
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 everyone, but %s has "
1032 "no root_req for it."),
1034 nation_rule_name(pnation));
1035 ok = FALSE;
1036 }
1037 }
1038
1039 /* Check national initial techs */
1040 for (techi = 0;
1041 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
1042 techi++) {
1043 Tech_type_id tech = pnation->init_techs[techi];
1044 struct advance *a = valid_advance_by_number(tech);
1045
1046 if (a == NULL) {
1047 ruleset_error(logger, LOG_ERROR,
1048 _("Tech %s does not exist, but is initial tech for %s."),
1050 nation_rule_name(pnation));
1051 ok = FALSE;
1052 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1053 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1054 /* Nation has no root_req for tech */
1055 ruleset_error(logger, LOG_ERROR,
1056 _("Tech %s is initial for %s, but they have "
1057 "no root_req for it."),
1059 nation_rule_name(pnation));
1060 ok = FALSE;
1061 }
1062 }
1063
1064 /* Check national initial buildings */
1066 && pnation->init_buildings[0] != B_LAST) {
1067 ruleset_error(logger, LOG_ERROR,
1068 _("Barbarian nation %s has init_buildings set but will "
1069 "never see them"), nation_rule_name(pnation));
1070 }
1071
1072 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
1073 ruleset_error(logger, LOG_ERROR,
1074 _("The government form %s reserved for revolution "
1075 "handling has been set as initial government for %s."),
1077 nation_rule_name(pnation));
1078 ok = FALSE;
1079 }
1081
1082 /* Check against unit upgrade loops */
1085 int chain_length = 0;
1086 const struct unit_type *upgraded = putype;
1087
1088 while (upgraded != NULL && !obsoleted_by_loop) {
1090 chain_length++;
1091 if (chain_length > num_utypes) {
1092 ruleset_error(logger, LOG_ERROR,
1093 _("There seems to be obsoleted_by loop in update "
1094 "chain that starts from %s"),
1096 ok = FALSE;
1098 }
1099 }
1101
1102 /* Some unit type properties depend on other unit type properties to work
1103 * properly. */
1105 /* "Spy" is a better "Diplomat". Until all the places that assume that
1106 * "Diplomat" is set if "Spy" is set is changed this limitation must be
1107 * kept. */
1110 ruleset_error(logger, LOG_ERROR,
1111 _("The unit type '%s' has the 'Spy' unit type flag but "
1112 "not the 'Diplomat' unit type flag."),
1114 ok = FALSE;
1115 }
1117
1118 /* Check that unit type fields are in range. */
1120 if (putype->paratroopers_range < 0
1121 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
1122 /* Paradrop range is limited by the network protocol. */
1123 ruleset_error(logger, LOG_ERROR,
1124 _("The paratroopers_range of the unit type '%s' is %d. "
1125 "That is out of range. Max range is %d."),
1127 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
1128 ok = FALSE;
1129 }
1130 /* never fires if game.scenario.prevent_new_cities is TRUE */
1131 if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE)
1133 ruleset_error(logger, LOG_ERROR,
1134 _("Unit type '%s' would build size %d cities. "
1135 "City sizes must be from 1 to %d."),
1136 utype_rule_name(putype), putype->city_size,
1138 ok = FALSE;
1139 }
1141
1142 memset(&els, 0, sizeof(els));
1143 els.logger = logger;
1144
1145 /* Check requirement sets against conflicting requirements.
1146 * For effects check also other sanity in the same iteration */
1148 ok = FALSE;
1149 }
1150
1151 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
1152 if (!els.base_effects.effect_present[req_base_effects[i]]) {
1153 ruleset_error(logger, LOG_ERROR,
1154 _("There is no base %s effect."),
1156 ok = FALSE;
1157 }
1158 }
1159 for (i = 0; req_base_effects_3_3[i] != EFT_COUNT; i++) {
1160 if (!els.base_effects.effect_present[req_base_effects_3_3[i]]) {
1162
1163 if (compat != NULL && compat->compat_mode && compat->version < RSFORMAT_3_3) {
1164 log_deprecation("There is no base %s effect.", ename);
1165 if (compat->log_cb != NULL) {
1166 char buf[512];
1167
1168 fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename);
1169 compat->log_cb(buf);
1170 }
1171 } else {
1172 ruleset_error(logger, LOG_ERROR,
1173 _("There is no base %s effect."), ename);
1174 ok = FALSE;
1175 }
1176 }
1177 }
1178
1179 if (!sanity_check_boolean_effects(logger)) {
1180 ok = FALSE;
1181 }
1182
1183 /* Others use requirement vectors */
1184
1185 /* Disasters */
1187 if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1,
1189 ruleset_error(logger, LOG_ERROR,
1190 _("Disasters have conflicting or invalid requirements!"));
1191 ok = FALSE;
1192 }
1194
1195 /* Goods */
1197 if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1,
1199 ruleset_error(logger, LOG_ERROR,
1200 _("Goods have conflicting or invalid requirements!"));
1201 ok = FALSE;
1202 }
1204
1205 /* Buildings */
1207 if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1,
1208 improvement_rule_name(pimprove))) {
1209 ruleset_error(logger, LOG_ERROR,
1210 _("Buildings have conflicting or invalid requirements!"));
1211 ok = FALSE;
1212 }
1213 if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1,
1214 improvement_rule_name(pimprove))) {
1215 ruleset_error(logger, LOG_ERROR,
1216 _("Buildings have conflicting or invalid obsolescence req!"));
1217 ok = FALSE;
1218 }
1220
1221 /* Governments */
1223 if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1,
1225 ruleset_error(logger, LOG_ERROR,
1226 _("Governments have conflicting or invalid requirements!"));
1227 ok = FALSE;
1228 }
1230
1231 /* Specialists */
1233 if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1,
1234 specialist_rule_name(psp))) {
1235 ruleset_error(logger, LOG_ERROR,
1236 _("Specialists have conflicting or invalid requirements!"));
1237 ok = FALSE;
1238 }
1240
1241 /* Extras */
1243 if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1,
1244 extra_rule_name(pextra))) {
1245 ruleset_error(logger, LOG_ERROR,
1246 _("Extras have conflicting or invalid requirements!"));
1247 ok = FALSE;
1248 }
1249 if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1,
1250 extra_rule_name(pextra))) {
1251 ruleset_error(logger, LOG_ERROR,
1252 _("Extras have conflicting or invalid removal requirements!"));
1253 ok = FALSE;
1254 }
1255 if ((requirement_vector_size(&pextra->rmreqs) > 0)
1256 && !(pextra->rmcauses
1257 & (ERM_ENTER | ERM_CLEAN | ERM_PILLAGE))) {
1258 ruleset_error(logger, LOG_WARN,
1259 _("Requirements for extra removal defined but not "
1260 "a valid remove cause!"));
1261 }
1263
1264 /* Roads */
1266 struct road_type *proad = extra_road_get(pextra);
1267
1268 extra_type_list_iterate(proad->integrators, iextra) {
1270 int pnbr = road_number(proad);
1271
1272 if (pnbr != road_number(iroad)
1273 && !BV_ISSET(iroad->integrates, pnbr)) {
1274 /* We don't support non-symmetric integrator relationships yet. */
1275 ruleset_error(logger, LOG_ERROR,
1276 _("Road '%s' integrates with '%s' but not vice versa!"),
1277 extra_rule_name(pextra),
1279 ok = FALSE;
1280 }
1283
1284 /* City styles */
1285 for (i = 0; i < game.control.num_city_styles; i++) {
1286 if (!sanity_check_req_vec(logger, &city_styles[i].reqs, TRUE, -1,
1288 ruleset_error(logger, LOG_ERROR,
1289 _("City styles have conflicting or invalid requirements!"));
1290 ok = FALSE;
1291 }
1292 }
1293
1294 /* Actions */
1295 action_iterate(act) {
1296 struct action *paction = action_by_number(act);
1297
1298 if (!actres_legal_target_kind(paction->result, paction->target_kind)) {
1299 ruleset_error(logger, LOG_ERROR,
1300 _("Action \"%s\": unsupported target kind %s."),
1302 action_target_kind_name(paction->target_kind));
1303 ok = FALSE;
1304 }
1305
1306 if (paction->min_distance < 0) {
1307 ruleset_error(logger, LOG_ERROR,
1308 _("Action %s: negative min distance (%d)."),
1309 action_id_rule_name(act), paction->min_distance);
1310 ok = FALSE;
1311 }
1312
1313 if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) {
1314 ruleset_error(logger, LOG_ERROR,
1315 _("Action %s: min distance (%d) larger than "
1316 "any distance on a map can be (%d)."),
1317 action_id_rule_name(act), paction->min_distance,
1319 ok = FALSE;
1320 }
1321
1322 if (paction->max_distance > ACTION_DISTANCE_MAX) {
1323 ruleset_error(logger, LOG_ERROR,
1324 _("Action %s: max distance is %d. "
1325 "A map can't be that big."),
1326 action_id_rule_name(act), paction->max_distance);
1327 ok = FALSE;
1328 }
1329
1330 if (!action_distance_inside_max(paction, paction->min_distance)) {
1331 ruleset_error(logger, LOG_ERROR,
1332 _("Action %s: min distance is %d but max distance is %d."),
1334 paction->min_distance, paction->max_distance);
1335 ok = FALSE;
1336 }
1337
1338 action_iterate(blocker) {
1339 if (BV_ISSET(paction->blocked_by, blocker)
1340 && action_id_get_target_kind(blocker) == ATK_UNIT
1342 /* Can't find an individual unit target to evaluate the blocking
1343 * action against. (A tile may have more than one individual
1344 * unit) */
1345 ruleset_error(logger, LOG_ERROR,
1346 _("The action %s can't block %s."),
1347 action_id_rule_name(blocker),
1348 action_id_rule_name(act));
1349 ok = FALSE;
1350 }
1352
1354 if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1,
1355 "Action Enabler Actor Reqs")
1356 || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1,
1357 "Action Enabler Target Reqs")) {
1358 ruleset_error(logger, LOG_ERROR,
1359 _("Action enabler for %s has conflicting or invalid "
1360 "requirements!"), action_id_rule_name(act));
1361 ok = FALSE;
1362 }
1363
1365 /* Special test for self targeted actions. */
1366
1367 if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1368 /* Shouldn't have target requirements since the action doesn't
1369 * have a target. */
1370 ruleset_error(logger, LOG_ERROR,
1371 _("An action enabler for %s has a target "
1372 "requirement vector. %s doesn't have a target."),
1374 action_id_rule_name(act));
1375 ok = FALSE;
1376 }
1377 }
1378
1379 requirement_vector_iterate(&(enabler->target_reqs), preq) {
1380 if (preq->source.kind == VUT_DIPLREL
1381 && preq->range == REQ_RANGE_LOCAL) {
1382 struct astring astr;
1383
1384 /* A Local DiplRel requirement can be expressed as a requirement
1385 * in actor_reqs. Demand that it is there. This avoids breaking
1386 * code that reasons about actions. */
1387 ruleset_error(logger, LOG_ERROR,
1388 _("Action enabler for %s has a local DiplRel "
1389 "requirement %s in target_reqs! Please read the "
1390 "section \"Requirement vector rules\" in "
1391 "doc/README.actions"),
1394 astr_free(&astr);
1395 ok = FALSE;
1396 } else if (preq->source.kind == VUT_MAX_DISTANCE_SQ
1397 && preq->range == REQ_RANGE_TILE) {
1398 struct astring astr;
1399
1400 /* A Tile-ranged MaxDistanceSq requirement can be expressed as a
1401 * requirement in actor_reqs. Demand that it is there. */
1402 ruleset_error(logger, LOG_ERROR,
1403 _("Action enabler for %s has a tile MaxDistanceSq "
1404 "requirement %s in target_reqs! Please read the "
1405 "section \"Requirement vector rules\" in "
1406 "doc/README.actions"),
1409 astr_free(&astr);
1410 ok = FALSE;
1411 }
1413
1414 if (compat == NULL || !compat->compat_mode
1415 || compat->version >= RSFORMAT_3_3) {
1416 /* Support for letting some of the following hard requirements be
1417 * implicit were retired in Freeciv 3.0. Others were retired later.
1418 * Make sure that the opposite of each hard action requirement
1419 * blocks all its action enablers. */
1420
1421 struct req_vec_problem *problem
1423
1424 if (problem != NULL) {
1425 ruleset_error(logger, LOG_ERROR, "%s", problem->description);
1427 ok = FALSE;
1428 }
1429
1431 if (problem != NULL) {
1432 /* There is a potential for improving this enabler. */
1433 log_deprecation("%s", problem->description);
1435 }
1436 }
1438
1440 /* The action performer, action_dice_roll_initial_odds() and the
1441 * action probability calculation in action_prob() must probably all
1442 * be updated to add a new action here. */
1459 ruleset_error(logger, LOG_ERROR,
1460 _("diplchance_initial_odds: \"%s\" not supported."),
1462 ok = FALSE;
1463 }
1464
1465 if (BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER)
1466 && BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)) {
1467 ruleset_error(logger, LOG_ERROR,
1468 _("%s both enters and frightens a hut at the same time."),
1470 ok = FALSE;
1471 }
1473
1474 /* Auto attack */
1475 {
1477
1479
1481 struct action *paction = action_by_number(act_id);
1482
1487 /* Only allow removing and changing the order of old auto
1488 * attack actions for now. Other actions need more testing and
1489 * fixing of issues caused by a worst case action probability of
1490 * 0%. */
1491 ruleset_error(logger, LOG_ERROR,
1492 _("auto_attack: %s not supported in"
1493 " attack_actions."),
1495 ok = FALSE;
1496 }
1498 }
1499
1500 /* There must be basic city style for each nation style to start with */
1503 ruleset_error(logger, LOG_ERROR,
1504 _("There's no basic city style for nation style %s"),
1506 ok = FALSE;
1507 }
1509
1510 /* Music styles */
1512 if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) {
1513 ruleset_error(logger, LOG_ERROR,
1514 _("Music Styles have conflicting or invalid requirements!"));
1515 ok = FALSE;
1516 }
1518
1520 if (pterr->animal != NULL) {
1521 if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) {
1522 ruleset_error(logger, LOG_ERROR,
1523 _("%s has %s as animal to appear, but it's not native to the terrain."),
1525 ok = FALSE;
1526 }
1527 }
1528
1530 (void) freq;
1532 ruleset_error(logger, LOG_ERROR,
1533 _("%s has %s as a resource, but it's not a resource extra."),
1535 ok = FALSE;
1536 }
1539
1540 /* Check that all unit classes can exist somewhere */
1543 bool can_exist = FALSE;
1544
1546 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1547 can_exist = TRUE;
1548 break;
1549 }
1551
1552 if (!can_exist) {
1554 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1555 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1556 can_exist = TRUE;
1557 break;
1558 }
1560 }
1561
1562 if (!can_exist) {
1563 ruleset_error(logger, LOG_ERROR,
1564 _("Unit class %s cannot exist anywhere."),
1566 ok = FALSE;
1567 }
1568 }
1570
1572 if (!pach->unique && pach->cons_msg == NULL) {
1573 ruleset_error(logger, LOG_ERROR,
1574 _("Achievement %s has no message for consecutive gainers though "
1575 "it's possible to be gained by multiple players"),
1577 ok = FALSE;
1578 }
1580
1582 int nati;
1583
1585 struct nation_type *pnat
1587
1588 if (pnat == NULL) {
1589 ruleset_error(logger, LOG_ERROR,
1590 _("There's nation %s listed in embedded nations, but there's "
1591 "no such nation."),
1593 ok = FALSE;
1594 }
1595 }
1596 }
1597
1598 if (ok) {
1599 ok = rs_common_units(logger);
1600 }
1601 if (ok) {
1602 ok = rs_barbarian_units(logger);
1603 }
1604 if (ok) {
1605 ok = rs_buildings(logger);
1606 }
1607
1608 return ok;
1609}
1610
1611/**********************************************************************/
1617{
1618 bool ok = TRUE;
1619
1622 if (pextra != pextra2) {
1623 int idx = extra_index(pextra2);
1624
1625 if (!BV_ISSET(pextra->conflicts, idx)) {
1626 log_debug("Autoconflicting resource %s with %s",
1628 BV_SET(pextra->conflicts, extra_index(pextra2));
1629 }
1630 }
1633
1634 /* Hard coded action blocking. */
1635 {
1636 const struct {
1637 const enum action_result blocked;
1638 const enum action_result blocker;
1639 } must_block[] = {
1640 /* Hard code that Help Wonder blocks Disband Unit Recover. This must be done
1641 * because caravan_shields makes it possible to avoid the
1642 * consequences of choosing to do Disband Unit Recover rather than having it
1643 * do Help Wonder.
1644 *
1645 * Explanation: Disband Unit Recover adds 50% of the shields used to produce
1646 * the unit to the production of the city where it is located. Help
1647 * Wonder adds 100%. If a unit that can do Help Wonder is disbanded with
1648 * production recovery in a city and the production later is changed
1649 * to something that can receive help from Help Wonder the remaining 50%
1650 * of the shields are added. This can be done because the city remembers
1651 * them in caravan_shields.
1652 *
1653 * If a unit that can do Help Wonder intentionally is disbanded with recovery
1654 * rather than making it do Help Wonder its shields will still be
1655 * remembered. The target city that got 50% of the shields can
1656 * therefore get 100% of them by changing its production. This trick
1657 * makes the ability to select Disband Unit Recover when Help Wonder is legal
1658 * pointless. */
1660
1661 /* Allowing regular disband when ACTION_HELP_WONDER or
1662 * ACTION_DISBAND_UNIT_RECOVER is legal while ACTION_HELP_WONDER always
1663 * blocks ACTION_DISBAND_UNIT_RECOVER doesn't work well with the force_*
1664 * semantics. Should move to the ruleset once it has blocked_by
1665 * semantics. */
1668
1669 /* Hard code that the ability to perform a regular attack blocks city
1670 * conquest. Is redundant as long as the requirement that the target
1671 * tile has no units remains hard coded. Kept "just in case" that
1672 * changes. */
1674
1675 /* Hard code that the ability to perform a regular attack blocks
1676 * extras conquest. Is redundant as long as the requirement that the
1677 * target tile has no non-allied units remains hard coded. Kept "just
1678 * in case" that changes. */
1680
1681 /* Hard code that the ability to enter or frighten a hut blocks
1682 * regular disembarking. */
1686 };
1687
1688 int i;
1689
1690 for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1691 enum action_result blocked_result = must_block[i].blocked;
1692 enum action_result blocker_result = must_block[i].blocker;
1693
1696 if (!action_would_be_blocked_by(blocked, blocker)) {
1697 log_verbose("Autoblocking %s with %s",
1698 action_rule_name(blocked),
1699 action_rule_name(blocker));
1700 BV_SET(blocked->blocked_by, action_id(blocker));
1701 }
1704 }
1705 }
1706
1707 return ok;
1708}
1709
1710/**********************************************************************/
1714{
1715 bool ok = TRUE;
1716
1717 if (num_role_units(L_BARBARIAN) == 0) {
1718 struct setting *pset = setting_by_name("barbarians");
1719
1720 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
1721 "unit types."));
1723 if (!setting_enum_set(pset, "DISABLED", NULL, NULL, 0)) {
1724 ok = FALSE;
1725 }
1727 }
1728
1729 return ok;
1730}
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:1173
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1098
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:5722
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:1922
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:1988
const char * action_rule_name(const struct action *action)
Definition actions.c:1216
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1239
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1196
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:5367
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1108
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1559
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:241
#define ACTION_DISTANCE_MAX
Definition actions.h:103
#define enabler_get_action(_enabler_)
Definition actions.h:182
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:371
#define action_auto_perf_actions_iterate_end
Definition actions.h:362
static struct action * action_by_number(action_id act_id)
Definition actions.h:396
#define action_enabler_list_re_iterate_end
Definition actions.h:196
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:99
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:192
#define action_has_result(_act_, _res_)
Definition actions.h:180
#define action_by_result_iterate_end
Definition actions.h:245
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition actions.h:359
#define action_iterate_end
Definition actions.h:214
#define action_has_result_safe(paction, result)
Definition actions.h:424
#define action_iterate(_act_)
Definition actions.h:210
#define action_id_get_target_kind(act_id)
Definition actions.h:413
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:694
bool actres_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actres.c:560
void astr_free(struct astring *astr)
Definition astring.c:148
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
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:103
char * incite_cost
Definition comments.c:76
#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:93
#define disaster_type_re_active_iterate_end
Definition disaster.h:96
int int id
Definition editgui_g.h:28
struct @22::@23 reqs
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1321
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:1202
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:875
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:778
int Tech_type_id
Definition fc_types.h:236
int ssetv
Definition fc_types.h:525
@ RPT_POSSIBLE
Definition fc_types.h:532
int action_id
Definition fc_types.h:248
#define MAX_NUM_TECH_LIST
Definition fc_types.h:44
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:61
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:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define log_normal(message,...)
Definition log.h:108
@ LOG_ERROR
Definition log.h:31
@ LOG_WARN
Definition log.h:32
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
Definition movement.c:341
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:869
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:903
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:498
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Definition rssanity.c:143
enum effect_type req_base_effects_3_3[]
Definition rssanity.c:51
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:257
static bool sanity_check_boolean_effects(rs_conversion_logger logger)
Definition rssanity.c:851
static bool sanity_check_setting_is_seen(struct setting *pset)
Definition rssanity.c:107
static bool sanity_check_req_individual(rs_conversion_logger logger, struct requirement *preq, const char *list_for)
Definition rssanity.c:170
static bool rs_buildings(rs_conversion_logger logger)
Definition rssanity.c:784
static bool sanity_check_metadata(rs_conversion_logger logger)
Definition rssanity.c:60
bool autolock_settings(void)
Definition rssanity.c:1713
static bool rs_common_units(rs_conversion_logger logger)
Definition rssanity.c:705
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1616
static bool rs_barbarian_units(rs_conversion_logger logger)
Definition rssanity.c:633
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Definition rssanity.c:540
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Definition rssanity.c:116
static bool nation_has_initial_tech(struct nation_type *pnation, struct advance *tech)
Definition rssanity.c:78
void(* rs_conversion_logger)(const char *msg)
Definition ruleload.h:42
#define ruleset_error(logger, level, format,...)
Definition ruleload.h:59
#define RSFORMAT_3_3
Definition ruleload.h:37
static struct compatibility compat[]
Definition savecompat.c:112
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:4676
struct setting * setting_by_name(const char *name)
Definition settings.c:3309
struct setting * setting_by_number(int id)
Definition settings.c:3301
enum sset_category setting_category(const struct setting *pset)
Definition settings.c:3378
bool setting_enum_set(struct setting *pset, const char *val, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Definition settings.c:4022
void setting_ruleset_lock_set(struct setting *pset)
Definition settings.c:4656
bool setting_is_visible_at_level(const struct setting *pset, enum cmdlevel plevel)
Definition settings.c:3496
bool formats_match(const char *format1, const char *format2)
Definition shared.c:2446
#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:127
struct civ_game::@32::@36::@42 ruledit
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:290
struct civ_game::@31 rgame
size_t embedded_nations_count
Definition game.h:291
struct civ_game::@32::@36 server
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:534
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:565
const struct unit_type * obsoleted_by
Definition unittype.h:536
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:960
#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:309
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define advance_re_active_iterate(_p)
Definition tech.h:277
#define A_NEVER
Definition tech.h:51
#define advance_req_iterate(_goal, _padvance)
Definition tech.h:295
@ AR_ROOT
Definition tech.h:108
@ AR_ONE
Definition tech.h:106
@ AR_SIZE
Definition tech.h:109
#define advance_re_active_iterate_end
Definition tech.h:281
#define advance_req_iterate_end
Definition tech.h:299
#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:281
#define is_ocean(pterrain)
Definition terrain.h:194
#define terrain_re_active_iterate(_p)
Definition terrain.h:277
#define terrain_resources_iterate_end
Definition terrain.h:294
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:285
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:2971
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2259
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:205
int num_role_units(int role)
Definition unittype.c:2209
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1584
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1647
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
#define unit_type_re_active_iterate(_p)
Definition unittype.h:874
#define utype_class(_t_)
Definition unittype.h:756
#define unit_class_iterate(_p)
Definition unittype.h:915
#define unit_class_re_active_iterate_end
Definition unittype.h:931
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:862
#define unit_class_re_active_iterate(_p)
Definition unittype.h:927
#define UNIT_MAX_PARADROP_RANGE
Definition unittype.h:56
#define uclass_index(_c_)
Definition unittype.h:749
#define unit_class_iterate_end
Definition unittype.h:922
#define unit_type_iterate_end
Definition unittype.h:869
#define unit_type_re_active_iterate_end
Definition unittype.h:878