Freeciv-3.4
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. */
50
51/* These have been made mandatory in freeciv-3.4 */
52enum effect_type req_base_effects_3_4[] =
53 {
54 /* None yet */
56 };
57
58/**********************************************************************/
62{
65 ruleset_error(logger,
67 _("Too long ruleset summary. It can be only %d bytes long. "
68 "Put longer explanations to ruleset description."),
70 return FALSE;
71 }
72
73 return TRUE;
74}
75
76/**********************************************************************/
79static bool nation_has_initial_tech(struct nation_type *pnation,
80 struct advance *tech)
81{
82 int i;
83
84 /* See if it's given as global init tech */
85 for (i = 0; i < MAX_NUM_TECH_LIST
88 return TRUE;
89 }
90 }
91
92 /* See if it's given as national init tech */
93 for (i = 0;
94 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
95 i++) {
96 if (pnation->init_techs[i] == advance_number(tech)) {
97 return TRUE;
98 }
99 }
100
101 return FALSE;
102}
103
104/**********************************************************************/
112
113/**********************************************************************/
118{
121 /* White list for SSET_INTERNAL and SSET_NETWORK settings. */
122 && !(pset == setting_by_name("phasemode")
123 || pset == setting_by_name("timeout")
124 || pset == setting_by_name("timeaddenemymove")
125 || pset == setting_by_name("unitwaittime")
126 || pset == setting_by_name("victories"))) {
127 /* The given server setting is a server operator related setting (like
128 * the compression type of savegames), not a game rule. */
129 return FALSE;
130 }
131
132 if (pset == setting_by_name("naturalcitynames")) {
133 /* This setting is about "look", not rules. */
134 return FALSE;
135 }
136
137 return TRUE;
138}
139
140/**********************************************************************/
145{
147 struct setting *pset;
148
149 /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
150 * the server setting id. */
151 id = (server_setting_id)ssetval;
153
155 /* Not supported yet. */
156 return FALSE;
157 }
158
160
163}
164
165/**********************************************************************/
172 struct requirement *preq,
173 const char *list_for)
174{
175 switch (preq->source.kind) {
176 case VUT_IMPROVEMENT:
177 case VUT_SITE:
178 /* This check corresponds to what is_req_active() will support.
179 * It can't be done in req_from_str(), as we may not have
180 * loaded all building information at that time. */
181 {
182 const struct impr_type *pimprove = preq->source.value.building;
183
184 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
185 ruleset_error(logger, LOG_ERROR,
186 _("%s: World-ranged requirement not supported for "
187 "%s (only great wonders supported)"), list_for,
189 return FALSE;
190 } else if (preq->range > REQ_RANGE_TRADE_ROUTE && !is_wonder(pimprove)) {
191 ruleset_error(logger, LOG_ERROR,
192 _("%s: %s-ranged requirement not supported for "
193 "%s (only wonders supported)"), list_for,
194 req_range_name(preq->range),
196 return FALSE;
197 }
198 }
199 break;
200 case VUT_MINCALFRAG:
201 /* Currently [calendar] is loaded after some requirements are
202 * parsed, so we can't do this in universal_value_from_str(). */
204 ruleset_error(logger, LOG_ERROR,
205 _("%s: MinCalFrag requirement used in ruleset without "
206 "calendar fragments"), list_for);
207 return FALSE;
208 } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) {
209 ruleset_error(logger, LOG_ERROR,
210 _("%s: MinCalFrag requirement %d out of range (max %d in "
211 "this ruleset)"), list_for, preq->source.value.mincalfrag,
213 return FALSE;
214 }
215 break;
217 /* There is currently no way to check a server setting's category and
218 * access level that works in both the client and the server. */
219 {
221 struct setting *pset;
222
223 id = ssetv_setting_get(preq->source.value.ssetval);
226
228 ruleset_error(logger, LOG_ERROR,
229 _("%s: ServerSetting requirement %s isn't visible enough "
230 "to appear in a requirement. Everyone should be able to "
231 "see the value of a server setting that appears in a "
232 "requirement."), list_for, server_setting_name_get(id));
233 return FALSE;
234 }
235
237 /* This is a server operator related setting (like the compression
238 * type of savegames), not a game rule. */
239 ruleset_error(logger, LOG_ERROR,
240 _("%s: ServerSetting requirement setting %s isn't about a "
241 "game rule."),
243 return FALSE;
244 }
245 }
246 break;
247 default:
248 /* No other universals have checks that can't be done at ruleset
249 * load time. See req_from_str(). */
250 break;
251 }
252 return TRUE;
253}
254
255/**********************************************************************/
259 int reqs_of_type[],
260 int local_reqs_of_type[],
261 int tile_reqs_of_type[],
262 struct requirement *preq, bool conjunctive,
263 int max_tiles, const char *list_for)
264{
265 int rc;
266
268
270 return FALSE;
271 }
272
273 if (!conjunctive) {
274 /* All the checks below are only meaningful for conjunctive lists. */
275 /* FIXME: we could add checks suitable for disjunctive lists. */
276 return TRUE;
277 }
278
279 /* Add to counter for positive requirements. */
280 if (preq->present) {
281 reqs_of_type[preq->source.kind]++;
282 }
283 rc = reqs_of_type[preq->source.kind];
284
285 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
286 local_reqs_of_type[preq->source.kind]++;
287
288 switch (preq->source.kind) {
289 case VUT_EXTRA:
290 if (local_reqs_of_type[VUT_EXTRA] > 1) {
291 ruleset_error(logger, LOG_ERROR,
292 _("%s: Requirement list has multiple local-ranged extra "
293 "requirements (did you mean to make them tile-ranged?)"),
294 list_for);
295 return FALSE;
296 }
297 break;
298 default:
299 break;
300 }
301 }
302
303 if (preq->range == REQ_RANGE_TILE && preq->present) {
304 tile_reqs_of_type[preq->source.kind]++;
305
306 switch (preq->source.kind) {
307 case VUT_TERRAINCLASS:
309 ruleset_error(logger, LOG_ERROR,
310 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
311 list_for);
312 return FALSE;
313 }
314 break;
315 case VUT_TERRAIN:
317 ruleset_error(logger, LOG_ERROR,
318 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
319 list_for);
320 return FALSE;
321 }
322 break;
323 case VUT_MINLATITUDE:
324 case VUT_MAXLATITUDE:
325 if (tile_reqs_of_type[preq->range] > 1) {
326 ruleset_error(logger, LOG_ERROR,
327 _("%s: Requirement list has duplicate %s requirement at Tile range"),
329 return FALSE;
330 }
331 break;
332 default:
333 break;
334 }
335 }
336
337 if (rc > 1 && preq->present) {
338 /* Multiple requirements of the same type */
339 switch (preq->source.kind) {
340 case VUT_GOVERNMENT:
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 */
346 case VUT_MINCITIES:
348 case VUT_MINMOVES: /* Breaks nothing, but has no sense either */
349 case VUT_MINVETERAN: /* Breaks nothing, but has no sense either */
350 case VUT_MINHP: /* Breaks nothing, but has no sense either */
351 case VUT_MINYEAR:
352 case VUT_MINCALFRAG:
353 case VUT_AI_LEVEL:
354 case VUT_TERRAINALTER: /* Local range only */
355 case VUT_STYLE:
356 case VUT_IMPR_GENUS:
357 case VUT_ORIGINAL_OWNER: /* City range -> only one original owner */
358 case VUT_FORM_AGE:
359 case VUT_MAX_DISTANCE_SQ: /* Breaks nothing, but has no sense either */
360 /* There can be only one requirement of these types (with current
361 * range limitations)
362 * Requirements might be identical, but we consider multiple
363 * declarations error anyway. */
364
365 ruleset_error(logger, LOG_ERROR,
366 _("%s: Requirement list has multiple %s requirements"),
368 return FALSE;
369 break;
370
371 case VUT_TERRAIN:
372 /* There can be only up to max_tiles requirements of these types */
373 if (max_tiles != -1 && rc > max_tiles) {
374 ruleset_error(logger, LOG_ERROR,
375 _("%s: Requirement list has more %s requirements than "
376 "can ever be fulfilled."), list_for,
378 return FALSE;
379 }
380 break;
381
382 case VUT_TERRAINCLASS:
383 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
384 ruleset_error(logger, LOG_ERROR,
385 _("%s: Requirement list has more %s requirements than "
386 "can ever be fulfilled."), list_for,
388 return FALSE;
389 }
390 break;
391
392 case VUT_AGE:
393 /* There can be age of the city, unit, and player */
394 if (rc > 3) {
395 ruleset_error(logger, LOG_ERROR,
396 _("%s: Requirement list has more %s requirements than "
397 "can ever be fulfilled."), list_for,
399 return FALSE;
400 }
401 break;
402
403 case VUT_MINTECHS:
404 case VUT_FUTURETECHS:
405 /* At ranges 'Player' and 'World' */
406 if (rc > 2) {
407 ruleset_error(logger, LOG_ERROR,
408 _("%s: Requirement list has more %s requirements than "
409 "can ever be fulfilled."), list_for,
411 return FALSE;
412 }
413 break;
414
415 case VUT_COUNTER:
416 /* Can have multiple, since many counters (also of the same range)
417 * can meet checkpoint */
419 /* Can have multiple, since there are many settings. */
420 case VUT_TOPO:
421 /* Can have multiple, since it's flag based (iso & hex) */
422 case VUT_WRAP:
423 /* Can have multiple, since it's flag based (wrapx & wrapy) */
424 case VUT_EXTRA:
425 /* Note that there can be more than 1 extra / tile. */
428 /* Can require different numbers on e.g. local/adjacent tiles. */
429 case VUT_NATION:
430 /* Can require multiple nations at Team/Alliance/World range. */
431 case VUT_NATIONGROUP:
432 /* Nations can be in multiple groups. */
433 case VUT_NONE:
434 case VUT_ADVANCE:
435 case VUT_TECHFLAG:
436 case VUT_IMPROVEMENT:
437 case VUT_SITE:
438 case VUT_UNITSTATE:
439 case VUT_CITYTILE:
440 case VUT_GOOD:
441 case VUT_UTYPE:
442 case VUT_UCLASS:
443 case VUT_TILE_REL:
444 /* Can check different properties. */
445 case VUT_GOVFLAG:
446 case VUT_UTFLAG:
447 case VUT_UCFLAG:
448 case VUT_TERRFLAG:
449 case VUT_ROADFLAG:
450 case VUT_EXTRAFLAG:
451 case VUT_IMPR_FLAG:
452 case VUT_PLAYER_FLAG:
453 case VUT_PLAYER_STATE:
454 case VUT_NATIONALITY:
455 case VUT_MINCULTURE:
456 case VUT_ACHIEVEMENT:
457 case VUT_DIPLREL:
458 case VUT_DIPLREL_TILE:
462 /* Can have multiple requirements of these types */
463 case VUT_MINLATITUDE:
464 case VUT_MAXLATITUDE:
466 /* Can have multiple requirements at different ranges.
467 * TODO: Compare to number of legal ranges? */
468 break;
469 case VUT_CITYSTATUS:
470 /* Could check "CITYS_LAST * number of ranges" ? */
471 break;
472 case VUT_COUNT:
473 /* Should never be in requirement vector */
475 return FALSE;
476 break;
477 /* No default handling here, as we want compiler warning
478 * if new requirement type is added to enum and it's not handled
479 * here. */
480 }
481 }
482
483 return TRUE;
484}
485
486/**********************************************************************/
503 const struct requirement_vector *preqs,
504 bool conjunctive, int max_tiles,
505 const char *list_for)
506{
507 struct req_vec_problem *problem;
511
512 /* Initialize requirement counters */
513 memset(reqs_of_type, 0, sizeof(reqs_of_type));
515
520 return FALSE;
521 }
523
525 if (problem != NULL) {
526 ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description);
528 return FALSE;
529 }
530
531 return TRUE;
532}
533
534typedef struct {
535 struct {
536 bool effect_present[EFT_COUNT];
537 } base_effects;
539} els_data;
540
541/**********************************************************************/
544static bool effect_list_sanity_cb(struct effect *peffect, void *data)
545{
546 int one_tile = -1; /* TODO: Determine correct value from effect.
547 * -1 disables checking */
548 els_data *els = (els_data *)data;
549 struct astring astr;
550 int i;
551
552 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
553 if (peffect->type == req_base_effects[i]) {
554 els->base_effects.effect_present[peffect->type] = TRUE;
555 break;
556 }
557 }
558 for (i = 0; req_base_effects_3_4[i] != EFT_COUNT; i++) {
559 if (peffect->type == req_base_effects_3_4[i]) {
560 els->base_effects.effect_present[peffect->type] = TRUE;
561 break;
562 }
563 }
564
566 /* Only unit targets can pay in move fragments. */
568 if (preq->source.kind == VUT_ACTION) {
569 if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
570 /* TODO: support for ATK_STACK could be added. That would require
571 * manually calling action_success_target_pay_mp() in each
572 * supported unit stack targeted action performer (like
573 * action_consequence_success() does) or to have the unit stack
574 * targeted actions return a list of targets. */
575 ruleset_error(els->logger, LOG_ERROR,
576 _("The effect Action_Success_Target_Move_Cost has the"
577 " requirement {%s} but the action %s isn't"
578 " (single) unit targeted."),
580 universal_rule_name(&preq->source));
581 astr_free(&astr);
582 return FALSE;
583 }
584 }
586 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
587 /* Only unit actors can pay in move fragments. */
589 if (preq->source.kind == VUT_ACTION && preq->present) {
590 if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
591 ruleset_error(els->logger, LOG_ERROR,
592 _("The effect Action_Success_Actor_Move_Cost has the"
593 " requirement {%s} but the action %s isn't"
594 " performed by a unit."),
596 universal_rule_name(&preq->source));
597 astr_free(&astr);
598 return FALSE;
599 }
600 }
602 } else if (peffect->type == EFT_ACTION_ODDS_PCT
603 || peffect->type == EFT_ACTION_RESIST_PCT) {
604 /* Catch trying to set Action_Odds_Pct for non supported actions. */
606 if (preq->source.kind == VUT_ACTION && preq->present) {
607 if (action_dice_roll_initial_odds(preq->source.value.action)
609 ruleset_error(els->logger, LOG_ERROR,
610 _("The effect %s has the"
611 " requirement {%s} but the action %s doesn't"
612 " roll the dice to see if it fails."),
615 universal_rule_name(&preq->source));
616 astr_free(&astr);
617 return FALSE;
618 }
619 }
621 }
622
623 if (!sanity_check_req_vec(els->logger, &peffect->reqs, TRUE, one_tile,
624 effect_type_name(peffect->type))) {
625 ruleset_error(els->logger, LOG_ERROR,
626 _("Effects have conflicting or invalid requirements!"));
627
628 return FALSE;
629 }
630
631 return TRUE;
632}
633
634/**********************************************************************/
638{
639 if (num_role_units(L_BARBARIAN) > 0) {
641 ruleset_error(logger, LOG_ERROR, _("No role barbarian leader units"));
642 return FALSE;
643 }
645 ruleset_error(logger, LOG_ERROR, _("No role barbarian build units"));
646 return FALSE;
647 }
649 ruleset_error(logger, LOG_ERROR, _("No role barbarian ship units"));
650 return FALSE;
651 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
652 bool sea_capable = FALSE;
654
656 if (is_ocean(pterr)
657 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
659 break;
660 }
662
663 if (!sea_capable) {
664 ruleset_error(logger, LOG_ERROR,
665 _("Barbarian boat (%s) needs to be able to move at sea."),
666 utype_rule_name(u));
667 return FALSE;
668 }
669 }
671 ruleset_error(logger, LOG_ERROR, _("No role sea raider barbarian units"));
672 return FALSE;
673 }
674
677 if (ptype->transport_capacity <= 1) {
678 ruleset_error(logger, LOG_ERROR,
679 _("Barbarian boat %s has no capacity for both "
680 "leader and at least one man."),
682 return FALSE;
683 }
684
690 ruleset_error(logger, LOG_ERROR,
691 _("Barbarian boat %s cannot transport "
692 "barbarian cargo %s."),
695 return FALSE;
696 }
697 }
699 }
701 }
702
703 return TRUE;
704}
705
706/**********************************************************************/
710{
711 /* Check some required flags and roles etc: */
712 if (num_role_units(UTYF_WORKERS) == 0) {
713 ruleset_error(logger, LOG_ERROR, _("No flag Worker units"));
714 return FALSE;
715 }
717 ruleset_error(logger, LOG_ERROR, _("No role Start Explorer units"));
718 return FALSE;
719 }
720 if (num_role_units(L_FERRYBOAT) == 0) {
721 ruleset_error(logger, LOG_ERROR, _("No role Ferryboat units"));
722 return FALSE;
723 }
724 if (num_role_units(L_FIRSTBUILD) == 0) {
725 ruleset_error(logger, LOG_ERROR, _("No role Firstbuild units"));
726 return FALSE;
727 }
728
729 if (num_role_units(L_FERRYBOAT) > 0) {
730 bool sea_capable = FALSE;
731 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
732
734 if (is_ocean(pterr)
735 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
737 break;
738 }
740
741 if (!sea_capable) {
742 ruleset_error(logger, LOG_ERROR,
743 _("Ferryboat (%s) needs to be able to move at sea."),
744 utype_rule_name(u));
745 return FALSE;
746 }
747 }
748
749 if (num_role_units(L_PARTISAN) == 0
751 ruleset_error(logger, LOG_ERROR,
752 _("Inspire_Partisans effect present, "
753 "but no units with partisan role."));
754 return FALSE;
755 }
756
758 bool cargo = FALSE;
759
761 if (BV_ISSET(ptype->cargo, uclass_index(pclass))) {
762 cargo = TRUE;
763 break;
764 }
766
767 if (ptype->transport_capacity > 0) {
768 if (!cargo) {
769 ruleset_error(logger, LOG_ERROR,
770 _("%s has transport capacity %d, but no cargo types."),
771 utype_rule_name(ptype), ptype->transport_capacity);
772 return FALSE;
773 }
774 } else if (cargo) {
775 ruleset_error(logger, LOG_ERROR,
776 _("%s has cargo types, but no transport capacity."),
778 return FALSE;
779 }
781
782 return TRUE;
783}
784
785/**********************************************************************/
789{
790 /* Special Genus */
792 if (improvement_has_flag(pimprove, IF_GOLD)) {
793 if (pimprove->genus != IG_CONVERT) {
794 ruleset_error(logger, LOG_ERROR,
795 _("Gold producing improvement %s with genus other than \"Convert\""),
796 improvement_rule_name(pimprove));
797
798 return FALSE;
799 }
800 if (improvement_has_flag(pimprove, IF_INFRA)) {
801 ruleset_error(logger, LOG_ERROR,
802 _("The same improvement has both \"Gold\" and \"Infra\" flags"));
803 return FALSE;
804 }
805 } else if (improvement_has_flag(pimprove, IF_INFRA)) {
806 if (pimprove->genus != IG_CONVERT) {
807 ruleset_error(logger, LOG_ERROR,
808 _("Infrapoints producing improvement %s with genus other than \"Convert\""),
809 improvement_rule_name(pimprove));
810
811 return FALSE;
812 }
813 } else if (pimprove->genus == IG_CONVERT) {
814 ruleset_error(logger, LOG_ERROR,
815 _("Improvement %s with no conversion target with genus \"Convert\""),
816 improvement_rule_name(pimprove));
817 return FALSE;
818 }
819
821 && pimprove->genus != IG_IMPROVEMENT) {
822 ruleset_error(logger, LOG_ERROR,
823 _("Disasterproof improvement %s with genus other than \"Improvement\""),
824 improvement_rule_name(pimprove));
825
826 return FALSE;
827 }
828 if (pimprove->genus != IG_SPECIAL
834 RPT_POSSIBLE, FALSE))) {
835 ruleset_error(logger, LOG_ERROR,
836 _("Space part %s with genus other than \"Special\""),
837 improvement_rule_name(pimprove));
838 return FALSE;
839 }
840
841 if (!is_building_sellable(pimprove) && pimprove->upkeep != 0) {
842 ruleset_error(logger, LOG_ERROR,
843 _("%s is a nonsellable building with a nonzero upkeep value"),
844 improvement_rule_name(pimprove));
845 return FALSE;
846 }
848
849 return TRUE;
850}
851
852/**********************************************************************/
856{
857 enum effect_type boolean_effects[] =
858 {
882 };
883 int i;
884 bool ret = TRUE;
885
886 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
889 ruleset_error(logger, LOG_ERROR,
890 _("Boolean effect %s can get disabled, but it can't get "
891 "enabled before that."),
893 ret = FALSE;
894 }
895 }
896
897 return ret;
898}
899
900/**********************************************************************/
908{
909 int num_utypes;
910 int i;
911 bool ok = TRUE; /* Store failures to variable instead of returning
912 * immediately so all errors get printed, not just first
913 * one. */
917 rs_conversion_logger logger = ((compat != NULL) ? compat->log_cb : NULL);
918
919 if (!sanity_check_metadata(logger)) {
920 ok = FALSE;
921 }
922
925 ruleset_error(logger, LOG_ERROR,
926 _("Cost based free tech method, but tech cost style "
927 "\"Civ I|II\" so all techs cost the same."));
928 ok = FALSE;
929 }
930
931 /* Advances. */
933 for (i = AR_ONE; i < AR_SIZE; i++) {
934 const struct advance *preq;
935
936 if (i == AR_ROOT) {
937 /* Self rootreq is a feature. */
938 continue;
939 }
940
942
943 if (A_NEVER == preq) {
944 continue;
945 } else if (preq == padvance) {
946 ruleset_error(logger, LOG_ERROR, _("Tech \"%s\" requires itself."),
948 ok = FALSE;
949 continue;
950 }
951
953 if (preqreq == padvance) {
954 ruleset_error(logger, LOG_ERROR,
955 _("Tech \"%s\" requires itself indirectly via \"%s\"."),
958 ok = FALSE;
959 }
961 }
962
963 requirement_vector_iterate(&(padvance->research_reqs), preq) {
964 if (preq->source.kind == VUT_ADVANCE) {
965 /* Don't allow this even if allowing changing reqs. Players will
966 * expect all tech reqs to appear in the client tech tree. That
967 * should be taken care of first. */
968 ruleset_error(logger, LOG_ERROR,
969 _("Tech \"%s\" requires a tech in its research_reqs."
970 " This isn't supported yet. Please keep using req1"
971 " and req2 like before."),
973 ok = FALSE;
975 /* If we get an obsolete improvement before the game,
976 * almost surely it is going to become not obsolete later.
977 * This check must catch it. */) {
978 struct astring astr;
979
980 /* Only support unchanging requirements until the reachability code
981 * can handle it and the tech tree can display changing
982 * requirements. */
983 ruleset_error(logger, LOG_ERROR,
984 _("Tech \"%s\" has the requirement %s in its"
985 " research_reqs. This requirement may change during"
986 " the game. Changing requirements aren't supported"
987 " yet."),
990 astr_free(&astr);
991 ok = FALSE;
992 }
994
995 if (padvance->bonus_message != NULL) {
996 if (!formats_match(padvance->bonus_message, "%s")) {
997 ruleset_error(logger, LOG_ERROR,
998 _("Tech \"%s\" bonus message is not format with %%s "
999 "for a bonus tech name."),
1001 ok = FALSE;
1002 }
1003 }
1005
1007 ruleset_error(logger, LOG_ERROR,
1008 _("The government form %s reserved for revolution handling "
1009 "has been set as default_government."),
1011 ok = FALSE;
1013 }
1014
1015 /* Check that all players can have their initial techs */
1016 nations_re_active_iterate(pnation) {
1017 int techi;
1018
1019 /* Check global initial techs */
1020 for (techi = 0; techi < MAX_NUM_TECH_LIST
1023 struct advance *a = valid_advance_by_number(tech);
1024
1025 if (a == NULL) {
1026 ruleset_error(logger, LOG_ERROR,
1027 _("Tech %s does not exist, but is initial "
1028 "tech for everyone."),
1030 ok = FALSE;
1031 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1032 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1033 /* Nation has no root_req for tech */
1034 ruleset_error(logger, LOG_ERROR,
1035 _("Tech %s is initial for everyone, but %s has "
1036 "no root_req for it."),
1038 nation_rule_name(pnation));
1039 ok = FALSE;
1040 }
1041 }
1042
1043 /* Check national initial techs */
1044 for (techi = 0;
1045 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
1046 techi++) {
1047 Tech_type_id tech = pnation->init_techs[techi];
1048 struct advance *a = valid_advance_by_number(tech);
1049
1050 if (a == NULL) {
1051 ruleset_error(logger, LOG_ERROR,
1052 _("Tech %s does not exist, but is initial tech for %s."),
1054 nation_rule_name(pnation));
1055 ok = FALSE;
1056 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1057 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1058 /* Nation has no root_req for tech */
1059 ruleset_error(logger, LOG_ERROR,
1060 _("Tech %s is initial for %s, but they have "
1061 "no root_req for it."),
1063 nation_rule_name(pnation));
1064 ok = FALSE;
1065 }
1066 }
1067
1068 /* Check national initial buildings */
1070 && pnation->init_buildings[0] != B_LAST) {
1071 ruleset_error(logger, LOG_ERROR,
1072 _("Nation %s has init_buildings set but as barbarians will "
1073 "never get them."), nation_rule_name(pnation));
1074 }
1075
1076 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
1077 ruleset_error(logger, LOG_ERROR,
1078 _("The government form %s reserved for revolution "
1079 "handling has been set as initial government for %s."),
1081 nation_rule_name(pnation));
1082 ok = FALSE;
1083 }
1085
1086 /* Check against unit upgrade loops */
1089 int chain_length = 0;
1090 const struct unit_type *upgraded = putype;
1091
1092 while (upgraded != NULL && !obsoleted_by_loop) {
1094 chain_length++;
1095 if (chain_length > num_utypes) {
1096 ruleset_error(logger, LOG_ERROR,
1097 _("There seems to be obsoleted_by loop in update "
1098 "chain that starts from %s"),
1100 ok = FALSE;
1102 }
1103 }
1105
1106 /* Some unit type properties depend on other unit type properties to work
1107 * properly. */
1109 /* "Spy" is a better "Diplomat". Until all the places that assume that
1110 * "Diplomat" is set if "Spy" is set is changed this limitation must be
1111 * kept. */
1114 ruleset_error(logger, LOG_ERROR,
1115 _("The unit type '%s' has the 'Spy' unit type flag but "
1116 "not the 'Diplomat' unit type flag."),
1118 ok = FALSE;
1119 }
1121
1122 /* Check that unit type fields are in range. */
1124 if (putype->paratroopers_range < 0
1125 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
1126 /* Paradrop range is limited by the network protocol. */
1127 ruleset_error(logger, LOG_ERROR,
1128 _("The paratroopers_range of the unit type '%s' is %d. "
1129 "That is out of range. Max range is %d."),
1131 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
1132 ok = FALSE;
1133 }
1134 /* never fires if game.scenario.prevent_new_cities is TRUE */
1135 if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE)
1137 ruleset_error(logger, LOG_ERROR,
1138 _("Unit type '%s' would build size %d cities. "
1139 "City sizes must be from 1 to %d."),
1140 utype_rule_name(putype), putype->city_size,
1142 ok = FALSE;
1143 }
1145
1146 memset(&els, 0, sizeof(els));
1147 els.logger = logger;
1148
1149 /* Check requirement sets against conflicting requirements.
1150 * For effects check also other sanity in the same iteration */
1152 ok = FALSE;
1153 }
1154
1155 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
1156 if (!els.base_effects.effect_present[req_base_effects[i]]) {
1157 ruleset_error(logger, LOG_ERROR,
1158 _("There is no base %s effect."),
1160 ok = FALSE;
1161 }
1162 }
1163 for (i = 0; req_base_effects_3_4[i] != EFT_COUNT; i++) {
1164 if (!els.base_effects.effect_present[req_base_effects_3_4[i]]) {
1166
1167 if (compat != nullptr && compat->compat_mode && compat->version < RSFORMAT_3_4) {
1168 log_deprecation("There is no base %s effect.", ename);
1169 if (compat->log_cb != nullptr) {
1170 char buf[512];
1171
1172 fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename);
1173 compat->log_cb(buf);
1174 }
1175 } else {
1176 ruleset_error(logger, LOG_ERROR,
1177 _("There is no base %s effect."), ename);
1178 ok = FALSE;
1179 }
1180 }
1181 }
1182
1183 if (!sanity_check_boolean_effects(logger)) {
1184 ok = FALSE;
1185 }
1186
1187 /* Others use requirement vectors */
1188
1189 /* Disasters */
1191 if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1,
1193 ruleset_error(logger, LOG_ERROR,
1194 _("Disasters have conflicting or invalid requirements!"));
1195 ok = FALSE;
1196 }
1198
1199 /* Goods */
1201 if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1,
1203 ruleset_error(logger, LOG_ERROR,
1204 _("Goods have conflicting or invalid requirements!"));
1205 ok = FALSE;
1206 }
1208
1209 /* Buildings */
1211 if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1,
1212 improvement_rule_name(pimprove))) {
1213 ruleset_error(logger, LOG_ERROR,
1214 _("Buildings have conflicting or invalid requirements!"));
1215 ok = FALSE;
1216 }
1217 if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1,
1218 improvement_rule_name(pimprove))) {
1219 ruleset_error(logger, LOG_ERROR,
1220 _("Buildings have conflicting or invalid obsolescence req!"));
1221 ok = FALSE;
1222 }
1224
1225 /* Governments */
1227 if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1,
1229 ruleset_error(logger, LOG_ERROR,
1230 _("Governments have conflicting or invalid requirements!"));
1231 ok = FALSE;
1232 }
1234
1235 /* Specialists */
1237 if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1,
1238 specialist_rule_name(psp))) {
1239 ruleset_error(logger, LOG_ERROR,
1240 _("Specialists have conflicting or invalid requirements!"));
1241 ok = FALSE;
1242 }
1244
1245 /* Extras */
1247 if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1,
1248 extra_rule_name(pextra))) {
1249 ruleset_error(logger, LOG_ERROR,
1250 _("Extras have conflicting or invalid requirements!"));
1251 ok = FALSE;
1252 }
1253 if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1,
1254 extra_rule_name(pextra))) {
1255 ruleset_error(logger, LOG_ERROR,
1256 _("Extras have conflicting or invalid removal requirements!"));
1257 ok = FALSE;
1258 }
1259 if ((requirement_vector_size(&pextra->rmreqs) > 0)
1260 && !(pextra->rmcauses
1261 & (ERM_ENTER | ERM_CLEAN | ERM_PILLAGE))) {
1262 ruleset_error(logger, LOG_WARN,
1263 _("Requirements for extra removal defined but not "
1264 "a valid remove cause!"));
1265 }
1267
1268 /* Roads */
1270 struct road_type *proad = extra_road_get(pextra);
1271
1272 extra_type_list_iterate(proad->integrators, iextra) {
1274 int pnbr = road_number(proad);
1275
1276 if (pnbr != road_number(iroad)
1277 && !BV_ISSET(iroad->integrates, pnbr)) {
1278 /* We don't support non-symmetric integrator relationships yet. */
1279 ruleset_error(logger, LOG_ERROR,
1280 _("Road '%s' integrates with '%s' but not vice versa!"),
1281 extra_rule_name(pextra),
1283 ok = FALSE;
1284 }
1287
1288 /* City styles */
1289 for (i = 0; i < game.control.num_city_styles; i++) {
1290 if (!sanity_check_req_vec(logger, &city_styles[i].reqs, TRUE, -1,
1292 ruleset_error(logger, LOG_ERROR,
1293 _("City styles have conflicting or invalid requirements!"));
1294 ok = FALSE;
1295 }
1296 }
1297
1298 /* Actions */
1299 action_iterate(act) {
1300 struct action *paction = action_by_number(act);
1301
1302 if (!actres_legal_target_kind(paction->result, paction->target_kind)) {
1303 ruleset_error(logger, LOG_ERROR,
1304 _("Action \"%s\": unsupported target kind %s."),
1306 action_target_kind_name(paction->target_kind));
1307 ok = FALSE;
1308 }
1309
1310 if (paction->min_distance < 0) {
1311 ruleset_error(logger, LOG_ERROR,
1312 _("Action %s: negative min distance (%d)."),
1313 action_id_rule_name(act), paction->min_distance);
1314 ok = FALSE;
1315 }
1316
1317 if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) {
1318 ruleset_error(logger, LOG_ERROR,
1319 _("Action %s: min distance (%d) larger than "
1320 "any distance on a map can be (%d)."),
1321 action_id_rule_name(act), paction->min_distance,
1323 ok = FALSE;
1324 }
1325
1326 if (paction->max_distance > ACTION_DISTANCE_MAX) {
1327 ruleset_error(logger, LOG_ERROR,
1328 _("Action %s: max distance is %d. "
1329 "A map can't be that big."),
1330 action_id_rule_name(act), paction->max_distance);
1331 ok = FALSE;
1332 }
1333
1334 if (!action_distance_inside_max(paction, paction->min_distance)) {
1335 ruleset_error(logger, LOG_ERROR,
1336 _("Action %s: min distance is %d but max distance is %d."),
1338 paction->min_distance, paction->max_distance);
1339 ok = FALSE;
1340 }
1341
1342 action_iterate(blocker) {
1343 if (BV_ISSET(paction->blocked_by, blocker)
1344 && action_id_get_target_kind(blocker) == ATK_UNIT
1346 /* Can't find an individual unit target to evaluate the blocking
1347 * action against. (A tile may have more than one individual
1348 * unit) */
1349 ruleset_error(logger, LOG_ERROR,
1350 _("The action %s can't block %s."),
1351 action_id_rule_name(blocker),
1352 action_id_rule_name(act));
1353 ok = FALSE;
1354 }
1356
1358 if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1,
1359 "Action Enabler Actor Reqs")
1360 || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1,
1361 "Action Enabler Target Reqs")) {
1362 ruleset_error(logger, LOG_ERROR,
1363 _("Action enabler for %s has conflicting or invalid "
1364 "requirements!"), action_id_rule_name(act));
1365 ok = FALSE;
1366 }
1367
1369 /* Special test for self targeted actions. */
1370
1371 if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1372 /* Shouldn't have target requirements since the action doesn't
1373 * have a target. */
1374 ruleset_error(logger, LOG_ERROR,
1375 _("An action enabler for %s has a target "
1376 "requirement vector. %s doesn't have a target."),
1378 action_id_rule_name(act));
1379 ok = FALSE;
1380 }
1381 }
1382
1383 requirement_vector_iterate(&(enabler->target_reqs), preq) {
1384 if (preq->source.kind == VUT_DIPLREL
1385 && preq->range == REQ_RANGE_LOCAL) {
1386 struct astring astr;
1387
1388 /* A Local DiplRel requirement can be expressed as a requirement
1389 * in actor_reqs. Demand that it is there. This avoids breaking
1390 * code that reasons about actions. */
1391 ruleset_error(logger, LOG_ERROR,
1392 _("Action enabler for %s has a local DiplRel "
1393 "requirement %s in target_reqs! Please read the "
1394 "section \"Requirement vector rules\" in "
1395 "doc/README.actions"),
1398 astr_free(&astr);
1399 ok = FALSE;
1400 } else if (preq->source.kind == VUT_MAX_DISTANCE_SQ
1401 && preq->range == REQ_RANGE_TILE) {
1402 struct astring astr;
1403
1404 /* A Tile-ranged MaxDistanceSq requirement can be expressed as a
1405 * requirement in actor_reqs. Demand that it is there. */
1406 ruleset_error(logger, LOG_ERROR,
1407 _("Action enabler for %s has a tile MaxDistanceSq "
1408 "requirement %s in target_reqs! Please read the "
1409 "section \"Requirement vector rules\" in "
1410 "doc/README.actions"),
1413 astr_free(&astr);
1414 ok = FALSE;
1415 }
1417
1418 if (compat == nullptr || !compat->compat_mode
1419 || compat->version >= RSFORMAT_3_4) {
1420 /* Support for letting some of the following hard requirements be
1421 * implicit were retired in Freeciv 3.0. Others were retired later.
1422 * Make sure that the opposite of each hard action requirement
1423 * blocks all its action enablers. */
1424
1425 struct req_vec_problem *problem
1427
1428 if (problem != nullptr) {
1429 ruleset_error(logger, LOG_ERROR, "%s", problem->description);
1431 ok = FALSE;
1432 }
1433
1435 if (problem != nullptr) {
1436 /* There is a potential for improving this enabler. */
1437 log_deprecation("%s", problem->description);
1439 }
1440 }
1442
1444 /* The action performer, action_dice_roll_initial_odds() and the
1445 * action probability calculation in action_prob() must probably all
1446 * be updated to add a new action here. */
1463 ruleset_error(logger, LOG_ERROR,
1464 _("diplchance_initial_odds: \"%s\" not supported."),
1466 ok = FALSE;
1467 }
1468
1469 if (BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER)
1470 && BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)) {
1471 ruleset_error(logger, LOG_ERROR,
1472 _("%s both enters and frightens a hut at the same time."),
1474 ok = FALSE;
1475 }
1477
1478 /* Auto attack */
1479 {
1481
1483
1485 struct action *paction = action_by_number(act_id);
1486
1491 /* Only allow removing and changing the order of old auto
1492 * attack actions for now. Other actions need more testing and
1493 * fixing of issues caused by a worst case action probability of
1494 * 0%. */
1495 ruleset_error(logger, LOG_ERROR,
1496 _("auto_attack: %s not supported in"
1497 " attack_actions."),
1499 ok = FALSE;
1500 }
1502 }
1503
1504 /* There must be basic city style for each nation style to start with */
1507 ruleset_error(logger, LOG_ERROR,
1508 _("There's no basic city style for nation style %s"),
1510 ok = FALSE;
1511 }
1513
1514 /* Music styles */
1516 if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) {
1517 ruleset_error(logger, LOG_ERROR,
1518 _("Music Styles have conflicting or invalid requirements!"));
1519 ok = FALSE;
1520 }
1522
1524 if (pterr->animal != NULL) {
1525 if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) {
1526 ruleset_error(logger, LOG_ERROR,
1527 _("%s has %s as animal to appear, but it's not native to the terrain."),
1529 ok = FALSE;
1530 }
1531 }
1532
1534 (void) freq;
1536 ruleset_error(logger, LOG_ERROR,
1537 _("%s has %s as a resource, but it's not a resource extra."),
1539 ok = FALSE;
1540 }
1543
1544 /* Check that all unit classes can exist somewhere */
1547 bool can_exist = FALSE;
1548
1550 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1551 can_exist = TRUE;
1552 break;
1553 }
1555
1556 if (!can_exist) {
1558 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1559 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1560 can_exist = TRUE;
1561 break;
1562 }
1564 }
1565
1566 if (!can_exist) {
1567 ruleset_error(logger, LOG_ERROR,
1568 _("Unit class %s cannot exist anywhere."),
1570 ok = FALSE;
1571 }
1572 }
1574
1576 if (!pach->unique && pach->cons_msg == NULL) {
1577 ruleset_error(logger, LOG_ERROR,
1578 _("Achievement %s has no message for consecutive gainers though "
1579 "it's possible to be gained by multiple players"),
1581 ok = FALSE;
1582 }
1584
1586 int nati;
1587
1589 struct nation_type *pnat
1591
1592 if (pnat == NULL) {
1593 ruleset_error(logger, LOG_ERROR,
1594 _("There's nation %s listed in embedded nations, but there's "
1595 "no such nation."),
1597 ok = FALSE;
1598 }
1599 }
1600 }
1601
1602 if (ok) {
1603 ok = rs_common_units(logger);
1604 }
1605 if (ok) {
1606 ok = rs_barbarian_units(logger);
1607 }
1608 if (ok) {
1609 ok = rs_buildings(logger);
1610 }
1611
1612 return ok;
1613}
1614
1615/**********************************************************************/
1621{
1622 bool ok = TRUE;
1623
1626 if (pextra != pextra2) {
1627 int idx = extra_index(pextra2);
1628
1629 if (!BV_ISSET(pextra->conflicts, idx)) {
1630 log_debug("Autoconflicting resource %s with %s",
1632 BV_SET(pextra->conflicts, extra_index(pextra2));
1633 }
1634 }
1637
1638 /* Hard coded action blocking. */
1639 {
1640 const struct {
1641 const enum action_result blocked;
1642 const enum action_result blocker;
1643 } must_block[] = {
1644 /* Hard code that Help Wonder blocks Disband Unit Recover. This must be done
1645 * because caravan_shields makes it possible to avoid the
1646 * consequences of choosing to do Disband Unit Recover rather than having it
1647 * do Help Wonder.
1648 *
1649 * Explanation: Disband Unit Recover adds 50% of the shields used to produce
1650 * the unit to the production of the city where it is located. Help
1651 * Wonder adds 100%. If a unit that can do Help Wonder is disbanded with
1652 * production recovery in a city and the production later is changed
1653 * to something that can receive help from Help Wonder the remaining 50%
1654 * of the shields are added. This can be done because the city remembers
1655 * them in caravan_shields.
1656 *
1657 * If a unit that can do Help Wonder intentionally is disbanded with recovery
1658 * rather than making it do Help Wonder its shields will still be
1659 * remembered. The target city that got 50% of the shields can
1660 * therefore get 100% of them by changing its production. This trick
1661 * makes the ability to select Disband Unit Recover when Help Wonder is legal
1662 * pointless. */
1664
1665 /* Allowing regular disband when ACTION_HELP_WONDER or
1666 * ACTION_DISBAND_UNIT_RECOVER is legal while ACTION_HELP_WONDER always
1667 * blocks ACTION_DISBAND_UNIT_RECOVER doesn't work well with the force_*
1668 * semantics. Should move to the ruleset once it has blocked_by
1669 * semantics. */
1672
1673 /* Hard code that the ability to perform a regular attack blocks city
1674 * conquest. Is redundant as long as the requirement that the target
1675 * tile has no units remains hard coded. Kept "just in case" that
1676 * changes. */
1678
1679 /* Hard code that the ability to perform a regular attack blocks
1680 * extras conquest. Is redundant as long as the requirement that the
1681 * target tile has no non-allied units remains hard coded. Kept "just
1682 * in case" that changes. */
1684
1685 /* Hard code that the ability to enter or frighten a hut blocks
1686 * regular disembarking. */
1690 };
1691
1692 int i;
1693
1694 for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1695 enum action_result blocked_result = must_block[i].blocked;
1696 enum action_result blocker_result = must_block[i].blocker;
1697
1700 if (!action_would_be_blocked_by(blocked, blocker)) {
1701 log_verbose("Autoblocking %s with %s",
1702 action_rule_name(blocked),
1703 action_rule_name(blocker));
1704 BV_SET(blocked->blocked_by, action_id(blocker));
1705 }
1708 }
1709 }
1710
1711 return ok;
1712}
1713
1714/**********************************************************************/
1718{
1719 bool ok = TRUE;
1720
1721 if (num_role_units(L_BARBARIAN) == 0) {
1722 struct setting *pset = setting_by_name("barbarians");
1723
1724 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
1725 "unit types."));
1727 if (!setting_enum_set(pset, "DISABLED", NULL, NULL, 0)) {
1728 ok = FALSE;
1729 }
1731 }
1732
1733 return ok;
1734}
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:1194
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1119
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:5945
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:1918
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:1984
const char * action_rule_name(const struct action *action)
Definition actions.c:1237
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1260
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1217
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:5582
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1129
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1580
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:245
#define ACTION_DISTANCE_MAX
Definition actions.h:107
#define enabler_get_action(_enabler_)
Definition actions.h:186
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:375
#define action_auto_perf_actions_iterate_end
Definition actions.h:366
static struct action * action_by_number(action_id act_id)
Definition actions.h:400
#define action_enabler_list_re_iterate_end
Definition actions.h:200
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:103
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:196
#define action_has_result(_act_, _res_)
Definition actions.h:184
#define action_by_result_iterate_end
Definition actions.h:249
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition actions.h:363
#define action_iterate_end
Definition actions.h:218
#define action_has_result_safe(paction, result)
Definition actions.h:428
#define action_iterate(_act_)
Definition actions.h:214
#define action_id_get_target_kind(act_id)
Definition actions.h:417
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:724
bool actres_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actres.c:561
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:104
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:763
int Tech_type_id
Definition fc_types.h:237
int ssetv
Definition fc_types.h:507
@ RPT_POSSIBLE
Definition fc_types.h:514
int action_id
Definition fc_types.h:249
#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:135
#define governments_re_active_iterate(_p)
Definition government.h:132
#define governments_re_active_iterate_end
Definition government.h:136
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:373
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:901
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:344
#define nations_re_active_iterate(_pnat_)
Definition nation.h:341
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:907
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:502
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Definition rssanity.c:144
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:258
static bool sanity_check_boolean_effects(rs_conversion_logger logger)
Definition rssanity.c:855
static bool sanity_check_setting_is_seen(struct setting *pset)
Definition rssanity.c:108
static bool sanity_check_req_individual(rs_conversion_logger logger, struct requirement *preq, const char *list_for)
Definition rssanity.c:171
static bool rs_buildings(rs_conversion_logger logger)
Definition rssanity.c:788
enum effect_type req_base_effects_3_4[]
Definition rssanity.c:52
static bool sanity_check_metadata(rs_conversion_logger logger)
Definition rssanity.c:61
bool autolock_settings(void)
Definition rssanity.c:1717
static bool rs_common_units(rs_conversion_logger logger)
Definition rssanity.c:709
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1620
static bool rs_barbarian_units(rs_conversion_logger logger)
Definition rssanity.c:637
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Definition rssanity.c:544
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Definition rssanity.c:117
static bool nation_has_initial_tech(struct nation_type *pnation, struct advance *tech)
Definition rssanity.c:79
void(* rs_conversion_logger)(const char *msg)
Definition ruleload.h:41
#define ruleset_error(logger, level, format,...)
Definition ruleload.h:58
#define RSFORMAT_3_4
Definition ruleload.h:36
static struct compatibility compat[]
Definition savecompat.c:117
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:4721
struct setting * setting_by_name(const char *name)
Definition settings.c:3349
struct setting * setting_by_number(int id)
Definition settings.c:3341
enum sset_category setting_category(const struct setting *pset)
Definition settings.c:3420
bool setting_enum_set(struct setting *pset, const char *val, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Definition settings.c:4065
void setting_ruleset_lock_set(struct setting *pset)
Definition settings.c:4701
bool setting_is_visible_at_level(const struct setting *pset, enum cmdlevel plevel)
Definition settings.c:3538
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:157
#define specialist_type_re_active_iterate_end
Definition specialist.h:114
#define specialist_type_re_active_iterate(_p)
Definition specialist.h:109
struct advance * require[AR_SIZE]
Definition tech.h:129
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:538
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:279
#define A_NEVER
Definition tech.h:51
#define advance_req_iterate(_goal, _padvance)
Definition tech.h:297
@ AR_ROOT
Definition tech.h:110
@ AR_ONE
Definition tech.h:108
@ AR_SIZE
Definition tech.h:111
#define advance_re_active_iterate_end
Definition tech.h:283
#define advance_req_iterate_end
Definition tech.h:301
#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:250
#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:2997
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2279
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:224
int num_role_units(int role)
Definition unittype.c:2229
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1604
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1667
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:875
#define utype_class(_t_)
Definition unittype.h:756
#define unit_class_iterate(_p)
Definition unittype.h:916
#define unit_class_re_active_iterate_end
Definition unittype.h:932
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:863
#define unit_class_re_active_iterate(_p)
Definition unittype.h:928
#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:923
#define unit_type_iterate_end
Definition unittype.h:870
#define unit_type_re_active_iterate_end
Definition unittype.h:879