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. */
51
52/* These have been made mandatory in freeciv-3.4 */
53enum effect_type req_base_effects_3_4[] =
54 {
55 /* None yet */
57 };
58
59/**********************************************************************/
63{
64 if (game.ruleset_summary != nullptr
66 ruleset_error(logger,
68 _("Too long ruleset summary. It can be only %d bytes long. "
69 "Put longer explanations to ruleset description."),
71 return FALSE;
72 }
73
74 return TRUE;
75}
76
77/**********************************************************************/
80static bool nation_has_initial_tech(struct nation_type *pnation,
81 struct advance *tech)
82{
83 int i;
84
85 /* See if it's given as global init tech */
86 for (i = 0; i < MAX_NUM_TECH_LIST
89 return TRUE;
90 }
91 }
92
93 /* See if it's given as national init tech */
94 for (i = 0;
95 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
96 i++) {
97 if (pnation->init_techs[i] == advance_number(tech)) {
98 return TRUE;
99 }
100 }
101
102 return FALSE;
103}
104
105/**********************************************************************/
113
114/**********************************************************************/
119{
122 /* White list for SSET_INTERNAL and SSET_NETWORK settings. */
123 && !(pset == setting_by_name("phasemode")
124 || pset == setting_by_name("timeout")
125 || pset == setting_by_name("timeaddenemymove")
126 || pset == setting_by_name("unitwaittime")
127 || pset == setting_by_name("victories"))) {
128 /* The given server setting is a server operator related setting (like
129 * the compression type of savegames), not a game rule. */
130 return FALSE;
131 }
132
133 if (pset == setting_by_name("naturalcitynames")) {
134 /* This setting is about "look", not rules. */
135 return FALSE;
136 }
137
138 return TRUE;
139}
140
141/**********************************************************************/
146{
148 struct setting *pset;
149
150 /* TODO: use ssetv_setting_get() if setting value becomes multiplexed with
151 * the server setting id. */
152 id = (server_setting_id)ssetval;
154
156 /* Not supported yet. */
157 return FALSE;
158 }
159
161
164}
165
166/**********************************************************************/
173 struct requirement *preq,
174 const char *list_for)
175{
176 switch (preq->source.kind) {
177 case VUT_IMPROVEMENT:
178 case VUT_SITE:
179 /* This check corresponds to what is_req_active() will support.
180 * It can't be done in req_from_str(), as we may not have
181 * loaded all building information at that time. */
182 {
183 const struct impr_type *pimprove = preq->source.value.building;
184
185 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
186 ruleset_error(logger, LOG_ERROR,
187 _("%s: World-ranged requirement not supported for "
188 "%s (only great wonders supported)"), list_for,
190 return FALSE;
191 } else if (preq->range > REQ_RANGE_TRADE_ROUTE && !is_wonder(pimprove)) {
192 ruleset_error(logger, LOG_ERROR,
193 _("%s: %s-ranged requirement not supported for "
194 "%s (only wonders supported)"), list_for,
195 req_range_name(preq->range),
197 return FALSE;
198 }
199 }
200 break;
201 case VUT_MINCALFRAG:
202 /* Currently [calendar] is loaded after some requirements are
203 * parsed, so we can't do this in universal_value_from_str(). */
205 ruleset_error(logger, LOG_ERROR,
206 _("%s: MinCalFrag requirement used in ruleset without "
207 "calendar fragments"), list_for);
208 return FALSE;
209 } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) {
210 ruleset_error(logger, LOG_ERROR,
211 _("%s: MinCalFrag requirement %d out of range (max %d in "
212 "this ruleset)"), list_for, preq->source.value.mincalfrag,
214 return FALSE;
215 }
216 break;
218 /* There is currently no way to check a server setting's category and
219 * access level that works in both the client and the server. */
220 {
222 struct setting *pset;
223
224 id = ssetv_setting_get(preq->source.value.ssetval);
227
229 ruleset_error(logger, LOG_ERROR,
230 _("%s: ServerSetting requirement %s isn't visible enough "
231 "to appear in a requirement. Everyone should be able to "
232 "see the value of a server setting that appears in a "
233 "requirement."), list_for, server_setting_name_get(id));
234 return FALSE;
235 }
236
238 /* This is a server operator related setting (like the compression
239 * type of savegames), not a game rule. */
240 ruleset_error(logger, LOG_ERROR,
241 _("%s: ServerSetting requirement setting %s isn't about a "
242 "game rule."),
244 return FALSE;
245 }
246 }
247 break;
248 default:
249 /* No other universals have checks that can't be done at ruleset
250 * load time. See req_from_str(). */
251 break;
252 }
253 return TRUE;
254}
255
256/**********************************************************************/
260 int reqs_of_type[],
261 int local_reqs_of_type[],
262 int tile_reqs_of_type[],
263 struct requirement *preq, bool conjunctive,
264 int max_tiles, const char *list_for)
265{
266 int rc;
267
269
271 return FALSE;
272 }
273
274 if (!conjunctive) {
275 /* All the checks below are only meaningful for conjunctive lists. */
276 /* FIXME: we could add checks suitable for disjunctive lists. */
277 return TRUE;
278 }
279
280 /* Add to counter for positive requirements. */
281 if (preq->present) {
282 reqs_of_type[preq->source.kind]++;
283 }
284 rc = reqs_of_type[preq->source.kind];
285
286 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
287 local_reqs_of_type[preq->source.kind]++;
288
289 switch (preq->source.kind) {
290 case VUT_EXTRA:
291 if (local_reqs_of_type[VUT_EXTRA] > 1) {
292 ruleset_error(logger, LOG_ERROR,
293 _("%s: Requirement list has multiple local-ranged extra "
294 "requirements (did you mean to make them tile-ranged?)"),
295 list_for);
296 return FALSE;
297 }
298 break;
299 default:
300 break;
301 }
302 }
303
304 if (preq->range == REQ_RANGE_TILE && preq->present) {
305 tile_reqs_of_type[preq->source.kind]++;
306
307 switch (preq->source.kind) {
308 case VUT_TERRAINCLASS:
310 ruleset_error(logger, LOG_ERROR,
311 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
312 list_for);
313 return FALSE;
314 }
315 break;
316 case VUT_TERRAIN:
318 ruleset_error(logger, LOG_ERROR,
319 _("%s: Requirement list has both tile terrain and terrainclass requirement"),
320 list_for);
321 return FALSE;
322 }
323 break;
324 case VUT_MINLATITUDE:
325 case VUT_MAXLATITUDE:
326 if (tile_reqs_of_type[preq->range] > 1) {
327 ruleset_error(logger, LOG_ERROR,
328 _("%s: Requirement list has duplicate %s requirement at Tile range"),
330 return FALSE;
331 }
332 break;
333 default:
334 break;
335 }
336 }
337
338 if (rc > 1 && preq->present) {
339 /* Multiple requirements of the same type */
340 switch (preq->source.kind) {
341 case VUT_GOVERNMENT:
342 case VUT_ACTION:
343 case VUT_ACTIVITY:
344 case VUT_OTYPE:
345 case VUT_SPECIALIST:
346 case VUT_MINSIZE: /* Breaks nothing, but has no sense either */
347 case VUT_MINCITIES:
349 case VUT_MINMOVES: /* Breaks nothing, but has no sense either */
350 case VUT_MINVETERAN: /* Breaks nothing, but has no sense either */
351 case VUT_MINHP: /* Breaks nothing, but has no sense either */
352 case VUT_MINYEAR:
353 case VUT_MINCALFRAG:
354 case VUT_AI_LEVEL:
355 case VUT_TERRAINALTER: /* Local range only */
356 case VUT_STYLE:
357 case VUT_IMPR_GENUS:
358 case VUT_ORIGINAL_OWNER: /* City range -> only one original owner */
359 case VUT_FORM_AGE:
360 case VUT_MAX_DISTANCE_SQ: /* Breaks nothing, but has no sense either */
361 /* There can be only one requirement of these types (with current
362 * range limitations)
363 * Requirements might be identical, but we consider multiple
364 * declarations error anyway. */
365
366 ruleset_error(logger, LOG_ERROR,
367 _("%s: Requirement list has multiple %s requirements"),
369 return FALSE;
370 break;
371
372 case VUT_TERRAIN:
373 /* There can be only up to max_tiles requirements of these types */
374 if (max_tiles != -1 && rc > max_tiles) {
375 ruleset_error(logger, LOG_ERROR,
376 _("%s: Requirement list has more %s requirements than "
377 "can ever be fulfilled."), list_for,
379 return FALSE;
380 }
381 break;
382
383 case VUT_TERRAINCLASS:
384 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
385 ruleset_error(logger, LOG_ERROR,
386 _("%s: Requirement list has more %s requirements than "
387 "can ever be fulfilled."), list_for,
389 return FALSE;
390 }
391 break;
392
393 case VUT_AGE:
394 /* There can be age of the city, unit, and player */
395 if (rc > 3) {
396 ruleset_error(logger, LOG_ERROR,
397 _("%s: Requirement list has more %s requirements than "
398 "can ever be fulfilled."), list_for,
400 return FALSE;
401 }
402 break;
403
404 case VUT_MINTECHS:
405 case VUT_FUTURETECHS:
406 /* At ranges 'Player' and 'World' */
407 if (rc > 2) {
408 ruleset_error(logger, LOG_ERROR,
409 _("%s: Requirement list has more %s requirements than "
410 "can ever be fulfilled."), list_for,
412 return FALSE;
413 }
414 break;
415
416 case VUT_COUNTER:
417 /* Can have multiple, since many counters (also of the same range)
418 * can meet checkpoint */
420 /* Can have multiple, since there are many settings. */
421 case VUT_TOPO:
422 /* Can have multiple, since it's flag based (iso & hex) */
423 case VUT_WRAP:
424 /* Can have multiple, since it's flag based (wrapx & wrapy) */
425 case VUT_EXTRA:
426 case VUT_TILEDEF:
428 /* Note that there can be more than 1 extra / tile. */
431 /* Can require different numbers on e.g. local/adjacent tiles. */
432 case VUT_NATION:
433 /* Can require multiple nations at Team/Alliance/World range. */
434 case VUT_NATIONGROUP:
435 /* Nations can be in multiple groups. */
436 case VUT_NONE:
437 case VUT_ADVANCE:
438 case VUT_TECHFLAG:
439 case VUT_IMPROVEMENT:
440 case VUT_SITE:
441 case VUT_UNITSTATE:
442 case VUT_CITYTILE:
443 case VUT_GOOD:
444 case VUT_UTYPE:
445 case VUT_UCLASS:
446 case VUT_TILE_REL:
447 /* Can check different properties. */
448 case VUT_GOVFLAG:
449 case VUT_UTFLAG:
450 case VUT_UCFLAG:
451 case VUT_TERRFLAG:
452 case VUT_ROADFLAG:
453 case VUT_EXTRAFLAG:
454 case VUT_IMPR_FLAG:
455 case VUT_PLAYER_FLAG:
456 case VUT_PLAYER_STATE:
457 case VUT_NATIONALITY:
458 case VUT_MINCULTURE:
459 case VUT_ACHIEVEMENT:
460 case VUT_DIPLREL:
461 case VUT_DIPLREL_TILE:
465 /* Can have multiple requirements of these types */
466 case VUT_MINLATITUDE:
467 case VUT_MAXLATITUDE:
469 /* Can have multiple requirements at different ranges.
470 * TODO: Compare to number of legal ranges? */
471 break;
472 case VUT_CITYSTATUS:
473 /* Could check "CITYS_LAST * number of ranges" ? */
474 break;
475 case VUT_COUNT:
476 /* Should never be in requirement vector */
478 return FALSE;
479 break;
480 /* No default handling here, as we want compiler warning
481 * if new requirement type is added to enum and it's not handled
482 * here. */
483 }
484 }
485
486 return TRUE;
487}
488
489/**********************************************************************/
506 const struct requirement_vector *preqs,
507 bool conjunctive, int max_tiles,
508 const char *list_for)
509{
510 struct req_vec_problem *problem;
514
515 /* Initialize requirement counters */
516 memset(reqs_of_type, 0, sizeof(reqs_of_type));
518
523 return FALSE;
524 }
526
528 if (problem != nullptr) {
529 ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description);
531 return FALSE;
532 }
533
534 return TRUE;
535}
536
537typedef struct {
538 struct {
539 bool effect_present[EFT_COUNT];
540 } base_effects;
542} els_data;
543
544/**********************************************************************/
547static bool effect_list_sanity_cb(struct effect *peffect, void *data)
548{
549 int one_tile = -1; /* TODO: Determine correct value from effect.
550 * -1 disables checking */
551 els_data *els = (els_data *)data;
552 struct astring astr;
553 int i;
554
555 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
556 if (peffect->type == req_base_effects[i]) {
557 els->base_effects.effect_present[peffect->type] = TRUE;
558 break;
559 }
560 }
561 for (i = 0; req_base_effects_3_4[i] != EFT_COUNT; i++) {
562 if (peffect->type == req_base_effects_3_4[i]) {
563 els->base_effects.effect_present[peffect->type] = TRUE;
564 break;
565 }
566 }
567
569 /* Only unit targets can pay in move fragments. */
571 if (preq->source.kind == VUT_ACTION) {
572 if (action_get_target_kind(preq->source.value.action) != ATK_UNIT) {
573 /* TODO: support for ATK_STACK could be added. That would require
574 * manually calling action_success_target_pay_mp() in each
575 * supported unit stack targeted action performer (like
576 * action_consequence_success() does) or to have the unit stack
577 * targeted actions return a list of targets. */
578 ruleset_error(els->logger, LOG_ERROR,
579 _("The effect Action_Success_Target_Move_Cost has the"
580 " requirement {%s} but the action %s isn't"
581 " (single) unit targeted."),
583 universal_rule_name(&preq->source));
584 astr_free(&astr);
585 return FALSE;
586 }
587 }
589 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
590 /* Only unit actors can pay in move fragments. */
592 if (preq->source.kind == VUT_ACTION && preq->present) {
593 if (action_get_actor_kind(preq->source.value.action) != AAK_UNIT) {
594 ruleset_error(els->logger, LOG_ERROR,
595 _("The effect Action_Success_Actor_Move_Cost has the"
596 " requirement {%s} but the action %s isn't"
597 " performed by a unit."),
599 universal_rule_name(&preq->source));
600 astr_free(&astr);
601 return FALSE;
602 }
603 }
605 } else if (peffect->type == EFT_ACTION_ODDS_PCT
606 || peffect->type == EFT_ACTION_RESIST_PCT) {
607 /* Catch trying to set Action_Odds_Pct for non supported actions. */
609 if (preq->source.kind == VUT_ACTION && preq->present) {
610 if (action_dice_roll_initial_odds(preq->source.value.action)
612 ruleset_error(els->logger, LOG_ERROR,
613 _("The effect %s has the"
614 " requirement {%s} but the action %s doesn't"
615 " roll the dice to see if it fails."),
618 universal_rule_name(&preq->source));
619 astr_free(&astr);
620 return FALSE;
621 }
622 }
624 }
625
626 if (!sanity_check_req_vec(els->logger, &peffect->reqs, TRUE, one_tile,
627 effect_type_name(peffect->type))) {
628 ruleset_error(els->logger, LOG_ERROR,
629 _("Effects have conflicting or invalid requirements!"));
630
631 return FALSE;
632 }
633
634 return TRUE;
635}
636
637/**********************************************************************/
641{
642 if (num_role_units(L_BARBARIAN) > 0) {
644 ruleset_error(logger, LOG_ERROR, _("No role barbarian leader units"));
645 return FALSE;
646 }
648 ruleset_error(logger, LOG_ERROR, _("No role barbarian build units"));
649 return FALSE;
650 }
652 ruleset_error(logger, LOG_ERROR, _("No role barbarian ship units"));
653 return FALSE;
654 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
655 bool sea_capable = FALSE;
657
659 if (is_ocean(pterr)
660 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
662 break;
663 }
665
666 if (!sea_capable) {
667 ruleset_error(logger, LOG_ERROR,
668 _("Barbarian boat (%s) needs to be able to move at sea."),
669 utype_rule_name(u));
670 return FALSE;
671 }
672 }
674 ruleset_error(logger, LOG_ERROR, _("No role sea raider barbarian units"));
675 return FALSE;
676 }
677
680 if (ptype->transport_capacity <= 1) {
681 ruleset_error(logger, LOG_ERROR,
682 _("Barbarian boat %s has no capacity for both "
683 "leader and at least one man."),
685 return FALSE;
686 }
687
693 ruleset_error(logger, LOG_ERROR,
694 _("Barbarian boat %s cannot transport "
695 "barbarian cargo %s."),
698 return FALSE;
699 }
700 }
702 }
704 }
705
706 return TRUE;
707}
708
709/**********************************************************************/
713{
714 /* Check some required flags and roles etc: */
715 if (num_role_units(UTYF_WORKERS) == 0) {
716 ruleset_error(logger, LOG_ERROR, _("No flag Worker units"));
717 return FALSE;
718 }
720 ruleset_error(logger, LOG_ERROR, _("No role Start Explorer units"));
721 return FALSE;
722 }
723 if (num_role_units(L_FERRYBOAT) == 0) {
724 ruleset_error(logger, LOG_ERROR, _("No role Ferryboat units"));
725 return FALSE;
726 }
727 if (num_role_units(L_FIRSTBUILD) == 0) {
728 ruleset_error(logger, LOG_ERROR, _("No role Firstbuild units"));
729 return FALSE;
730 }
731
732 if (num_role_units(L_FERRYBOAT) > 0) {
733 bool sea_capable = FALSE;
734 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
735
737 if (is_ocean(pterr)
738 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
740 break;
741 }
743
744 if (!sea_capable) {
745 ruleset_error(logger, LOG_ERROR,
746 _("Ferryboat (%s) needs to be able to move at sea."),
747 utype_rule_name(u));
748 return FALSE;
749 }
750 }
751
752 if (num_role_units(L_PARTISAN) == 0
753 && effect_cumulative_max(EFT_INSPIRE_PARTISANS, nullptr, 0) > 0) {
754 ruleset_error(logger, LOG_ERROR,
755 _("Inspire_Partisans effect present, "
756 "but no units with partisan role."));
757 return FALSE;
758 }
759
761 bool cargo = FALSE;
762
764 if (BV_ISSET(ptype->cargo, uclass_index(pclass))) {
765 cargo = TRUE;
766 break;
767 }
769
770 if (ptype->transport_capacity > 0) {
771 if (!cargo) {
772 ruleset_error(logger, LOG_ERROR,
773 _("%s has transport capacity %d, but no cargo types."),
774 utype_rule_name(ptype), ptype->transport_capacity);
775 return FALSE;
776 }
777 } else if (cargo) {
778 ruleset_error(logger, LOG_ERROR,
779 _("%s has cargo types, but no transport capacity."),
781 return FALSE;
782 }
784
785 return TRUE;
786}
787
788/**********************************************************************/
792{
793 /* Special Genus */
795 if (improvement_has_flag(pimprove, IF_GOLD)) {
796 if (pimprove->genus != IG_CONVERT) {
797 ruleset_error(logger, LOG_ERROR,
798 _("Gold producing improvement %s with genus other than \"Convert\""),
799 improvement_rule_name(pimprove));
800
801 return FALSE;
802 }
803 if (improvement_has_flag(pimprove, IF_INFRA)) {
804 ruleset_error(logger, LOG_ERROR,
805 _("The same improvement has both \"Gold\" and \"Infra\" flags"));
806 return FALSE;
807 }
808 } else if (improvement_has_flag(pimprove, IF_INFRA)) {
809 if (pimprove->genus != IG_CONVERT) {
810 ruleset_error(logger, LOG_ERROR,
811 _("Infrapoints producing improvement %s with genus other than \"Convert\""),
812 improvement_rule_name(pimprove));
813
814 return FALSE;
815 }
816 } else if (pimprove->genus == IG_CONVERT) {
817 ruleset_error(logger, LOG_ERROR,
818 _("Improvement %s with no conversion target with genus \"Convert\""),
819 improvement_rule_name(pimprove));
820 return FALSE;
821 }
822
824 && pimprove->genus != IG_IMPROVEMENT) {
825 ruleset_error(logger, LOG_ERROR,
826 _("Disasterproof improvement %s with genus other than \"Improvement\""),
827 improvement_rule_name(pimprove));
828
829 return FALSE;
830 }
831 if (pimprove->genus != IG_SPECIAL
837 RPT_POSSIBLE, FALSE))) {
838 ruleset_error(logger, LOG_ERROR,
839 _("Space part %s with genus other than \"Special\""),
840 improvement_rule_name(pimprove));
841 return FALSE;
842 }
843
844 if (!is_building_sellable(pimprove) && pimprove->upkeep != 0) {
845 ruleset_error(logger, LOG_ERROR,
846 _("%s is a nonsellable building with a nonzero upkeep value"),
847 improvement_rule_name(pimprove));
848 return FALSE;
849 }
851
852 return TRUE;
853}
854
855/**********************************************************************/
859{
860 enum effect_type boolean_effects[] =
861 {
885 };
886 int i;
887 bool ret = TRUE;
888
889 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
890 if (effect_cumulative_min(boolean_effects[i], nullptr) < 0
891 && effect_cumulative_max(boolean_effects[i], nullptr, 0) == 0) {
892 ruleset_error(logger, LOG_ERROR,
893 _("Boolean effect %s can get disabled, but it can't get "
894 "enabled before that."),
896 ret = FALSE;
897 }
898 }
899
900 return ret;
901}
902
903/**********************************************************************/
911{
912 int num_utypes;
913 int i;
914 bool ok = TRUE; /* Store failures to variable instead of returning
915 * immediately so all errors get printed, not just first
916 * one. */
921 = ((compat != nullptr) ? compat->log_cb : nullptr);
922
923 if (!sanity_check_metadata(logger)) {
924 ok = FALSE;
925 }
926
929 ruleset_error(logger, LOG_ERROR,
930 _("Cost based free tech method, but tech cost style "
931 "\"Civ I|II\" so all techs cost the same."));
932 ok = FALSE;
933 }
934
935 /* Advances. */
937 for (i = AR_ONE; i < AR_SIZE; i++) {
938 const struct advance *preq;
939
940 if (i == AR_ROOT) {
941 /* Self rootreq is a feature. */
942 continue;
943 }
944
946
947 if (A_NEVER == preq) {
948 continue;
949 } else if (preq == padvance) {
950 ruleset_error(logger, LOG_ERROR, _("Tech \"%s\" requires itself."),
952 ok = FALSE;
953 continue;
954 }
955
957 if (preqreq == padvance) {
958 ruleset_error(logger, LOG_ERROR,
959 _("Tech \"%s\" requires itself indirectly via \"%s\"."),
962 ok = FALSE;
963 }
965 }
966
967 requirement_vector_iterate(&(padvance->research_reqs), preq) {
968 if (preq->source.kind == VUT_ADVANCE) {
969 /* Don't allow this even if allowing changing reqs. Players will
970 * expect all tech reqs to appear in the client tech tree. That
971 * should be taken care of first. */
972 ruleset_error(logger, LOG_ERROR,
973 _("Tech \"%s\" requires a tech in its research_reqs."
974 " This isn't supported yet. Please keep using req1"
975 " and req2 like before."),
977 ok = FALSE;
978 } else if (is_req_unchanging(nullptr, preq) < REQUCH_HACK
979 /* If we get an obsolete improvement before the game,
980 * almost surely it is going to become not obsolete later.
981 * This check must catch it. */) {
982 struct astring astr;
983
984 /* Only support unchanging requirements until the reachability code
985 * can handle it and the tech tree can display changing
986 * requirements. */
987 ruleset_error(logger, LOG_ERROR,
988 _("Tech \"%s\" has the requirement %s in its"
989 " research_reqs. This requirement may change during"
990 " the game. Changing requirements aren't supported"
991 " yet."),
994 astr_free(&astr);
995 ok = FALSE;
996 }
998
999 if (padvance->bonus_message != nullptr) {
1000 if (!formats_match(padvance->bonus_message, "%s")) {
1001 ruleset_error(logger, LOG_ERROR,
1002 _("Tech \"%s\" bonus message is not format with %%s "
1003 "for a bonus tech name."),
1005 ok = FALSE;
1006 }
1007 }
1009
1011 ruleset_error(logger, LOG_ERROR,
1012 _("The government form %s reserved for revolution handling "
1013 "has been set as default_government."),
1015 ok = FALSE;
1017 }
1018
1019 /* Check that all players can have their initial techs */
1020 nations_re_active_iterate(pnation) {
1021 int techi;
1022
1023 /* Check global initial techs */
1024 for (techi = 0; techi < MAX_NUM_TECH_LIST
1027 struct advance *a = valid_advance_by_number(tech);
1028
1029 if (a == nullptr) {
1030 ruleset_error(logger, LOG_ERROR,
1031 _("Tech %s does not exist, but is initial "
1032 "tech for everyone."),
1034 ok = FALSE;
1035 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1036 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1037 /* Nation has no root_req for tech */
1038 ruleset_error(logger, LOG_ERROR,
1039 _("Tech %s is initial for everyone, but %s has "
1040 "no root_req for it."),
1042 nation_rule_name(pnation));
1043 ok = FALSE;
1044 }
1045 }
1046
1047 /* Check national initial techs */
1048 for (techi = 0;
1049 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
1050 techi++) {
1051 Tech_type_id tech = pnation->init_techs[techi];
1052 struct advance *a = valid_advance_by_number(tech);
1053
1054 if (a == nullptr) {
1055 ruleset_error(logger, LOG_ERROR,
1056 _("Tech %s does not exist, but is initial tech for %s."),
1058 nation_rule_name(pnation));
1059 ok = FALSE;
1060 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
1061 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
1062 /* Nation has no root_req for tech */
1063 ruleset_error(logger, LOG_ERROR,
1064 _("Tech %s is initial for %s, but they have "
1065 "no root_req for it."),
1067 nation_rule_name(pnation));
1068 ok = FALSE;
1069 }
1070 }
1071
1072 /* Check national initial buildings */
1074 && pnation->init_buildings[0] != B_LAST) {
1075 ruleset_error(logger, LOG_ERROR,
1076 _("Nation %s has init_buildings set but as barbarians will "
1077 "never get them."), nation_rule_name(pnation));
1078 }
1079
1080 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
1081 ruleset_error(logger, LOG_ERROR,
1082 _("The government form %s reserved for revolution "
1083 "handling has been set as initial government for %s."),
1085 nation_rule_name(pnation));
1086 ok = FALSE;
1087 }
1089
1090 /* Check against unit upgrade loops */
1093 int chain_length = 0;
1094 const struct unit_type *upgraded = putype;
1095
1096 while (upgraded != nullptr && !obsoleted_by_loop) {
1098 chain_length++;
1099 if (chain_length > num_utypes) {
1100 ruleset_error(logger, LOG_ERROR,
1101 _("There seems to be obsoleted_by loop in update "
1102 "chain that starts from %s"),
1104 ok = FALSE;
1106 }
1107 }
1109
1110 /* Some unit type properties depend on other unit type properties to work
1111 * properly. */
1113 /* "Spy" is a better "Diplomat". Until all the places that assume that
1114 * "Diplomat" is set if "Spy" is set is changed this limitation must be
1115 * kept. */
1118 ruleset_error(logger, LOG_ERROR,
1119 _("The unit type '%s' has the 'Spy' unit type flag but "
1120 "not the 'Diplomat' unit type flag."),
1122 ok = FALSE;
1123 }
1125
1126 /* Check that unit type fields are in range. */
1128 if (putype->paratroopers_range < 0
1129 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
1130 /* Paradrop range is limited by the network protocol. */
1131 ruleset_error(logger, LOG_ERROR,
1132 _("The paratroopers_range of the unit type '%s' is %d. "
1133 "That is out of range. Max range is %d."),
1135 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
1136 ok = FALSE;
1137 }
1138 /* never fires if game.scenario.prevent_new_cities is TRUE */
1139 if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE)
1141 ruleset_error(logger, LOG_ERROR,
1142 _("Unit type '%s' would build size %d cities. "
1143 "City sizes must be from 1 to %d."),
1144 utype_rule_name(putype), putype->city_size,
1146 ok = FALSE;
1147 }
1149
1150 memset(&els, 0, sizeof(els));
1151 els.logger = logger;
1152
1153 /* Check requirement sets against conflicting requirements.
1154 * For effects check also other sanity in the same iteration */
1156 ok = FALSE;
1157 }
1158
1159 for (i = 0; req_base_effects[i] != EFT_COUNT; i++) {
1160 if (!els.base_effects.effect_present[req_base_effects[i]]) {
1161 ruleset_error(logger, LOG_ERROR,
1162 _("There is no base %s effect."),
1164 ok = FALSE;
1165 }
1166 }
1167 for (i = 0; req_base_effects_3_4[i] != EFT_COUNT; i++) {
1168 if (!els.base_effects.effect_present[req_base_effects_3_4[i]]) {
1170
1171 if (compat != nullptr && compat->compat_mode && compat->version < RSFORMAT_3_4) {
1172 log_deprecation("There is no base %s effect.", ename);
1173 if (compat->log_cb != nullptr) {
1174 char buf[512];
1175
1176 fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename);
1177 compat->log_cb(buf);
1178 }
1179 } else {
1180 ruleset_error(logger, LOG_ERROR,
1181 _("There is no base %s effect."), ename);
1182 ok = FALSE;
1183 }
1184 }
1185 }
1186
1187 if (!sanity_check_boolean_effects(logger)) {
1188 ok = FALSE;
1189 }
1190
1191 /* Others use requirement vectors */
1192
1193 /* Disasters */
1195 if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1,
1197 ruleset_error(logger, LOG_ERROR,
1198 _("Disasters have conflicting or invalid requirements!"));
1199 ok = FALSE;
1200 }
1202
1203 /* Goods */
1205 if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1,
1207 ruleset_error(logger, LOG_ERROR,
1208 _("Goods have conflicting or invalid requirements!"));
1209 ok = FALSE;
1210 }
1212
1213 /* Buildings */
1215 if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1,
1216 improvement_rule_name(pimprove))) {
1217 ruleset_error(logger, LOG_ERROR,
1218 _("Buildings have conflicting or invalid requirements!"));
1219 ok = FALSE;
1220 }
1221 if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1,
1222 improvement_rule_name(pimprove))) {
1223 ruleset_error(logger, LOG_ERROR,
1224 _("Buildings have conflicting or invalid obsolescence req!"));
1225 ok = FALSE;
1226 }
1228
1229 /* Governments */
1231 if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1,
1233 ruleset_error(logger, LOG_ERROR,
1234 _("Governments have conflicting or invalid requirements!"));
1235 ok = FALSE;
1236 }
1238
1239 /* Specialists */
1241 if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1,
1242 specialist_rule_name(psp))) {
1243 ruleset_error(logger, LOG_ERROR,
1244 _("Specialists have conflicting or invalid requirements!"));
1245 ok = FALSE;
1246 }
1248
1249 /* Extras */
1251 if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1,
1252 extra_rule_name(pextra))) {
1253 ruleset_error(logger, LOG_ERROR,
1254 _("Extras have conflicting or invalid requirements!"));
1255 ok = FALSE;
1256 }
1257 if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1,
1258 extra_rule_name(pextra))) {
1259 ruleset_error(logger, LOG_ERROR,
1260 _("Extras have conflicting or invalid removal requirements!"));
1261 ok = FALSE;
1262 }
1263 if ((requirement_vector_size(&pextra->rmreqs) > 0)
1264 && !(pextra->rmcauses
1265 & (ERM_ENTER | ERM_CLEAN | ERM_PILLAGE))) {
1266 ruleset_error(logger, LOG_WARN,
1267 _("Requirements for extra removal defined but not "
1268 "a valid remove cause!"));
1269 }
1271
1272 /* Roads */
1274 struct road_type *proad = extra_road_get(pextra);
1275
1276 extra_type_list_iterate(proad->integrators, iextra) {
1278 int pnbr = road_number(proad);
1279
1280 if (pnbr != road_number(iroad)
1281 && !BV_ISSET(iroad->integrates, pnbr)) {
1282 /* We don't support non-symmetric integrator relationships yet. */
1283 ruleset_error(logger, LOG_ERROR,
1284 _("Road '%s' integrates with '%s' but not vice versa!"),
1285 extra_rule_name(pextra),
1287 ok = FALSE;
1288 }
1291
1292 /* City styles */
1293 for (i = 0; i < game.control.num_city_styles; i++) {
1294 if (!sanity_check_req_vec(logger, &city_styles[i].reqs, TRUE, -1,
1296 ruleset_error(logger, LOG_ERROR,
1297 _("City styles have conflicting or invalid requirements!"));
1298 ok = FALSE;
1299 }
1300 }
1301
1302 /* Actions */
1303 action_iterate(act) {
1304 struct action *paction = action_by_number(act);
1305
1306 if (!actres_legal_target_kind(paction->result, paction->target_kind)) {
1307 ruleset_error(logger, LOG_ERROR,
1308 _("Action \"%s\": unsupported target kind %s."),
1310 action_target_kind_name(paction->target_kind));
1311 ok = FALSE;
1312 }
1313
1314 if (paction->min_distance < 0) {
1315 ruleset_error(logger, LOG_ERROR,
1316 _("Action %s: negative min distance (%d)."),
1317 action_id_rule_name(act), paction->min_distance);
1318 ok = FALSE;
1319 }
1320
1321 if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) {
1322 ruleset_error(logger, LOG_ERROR,
1323 _("Action %s: min distance (%d) larger than "
1324 "any distance on a map can be (%d)."),
1325 action_id_rule_name(act), paction->min_distance,
1327 ok = FALSE;
1328 }
1329
1330 if (paction->max_distance > ACTION_DISTANCE_MAX) {
1331 ruleset_error(logger, LOG_ERROR,
1332 _("Action %s: max distance is %d. "
1333 "A map can't be that big."),
1334 action_id_rule_name(act), paction->max_distance);
1335 ok = FALSE;
1336 }
1337
1338 if (!action_distance_inside_max(paction, paction->min_distance)) {
1339 ruleset_error(logger, LOG_ERROR,
1340 _("Action %s: min distance is %d but max distance is %d."),
1342 paction->min_distance, paction->max_distance);
1343 ok = FALSE;
1344 }
1345
1346 action_iterate(blocker) {
1347 if (BV_ISSET(paction->blocked_by, blocker)
1348 && action_id_get_target_kind(blocker) == ATK_UNIT
1350 /* Can't find an individual unit target to evaluate the blocking
1351 * action against. (A tile may have more than one individual
1352 * unit) */
1353 ruleset_error(logger, LOG_ERROR,
1354 _("The action %s can't block %s."),
1355 action_id_rule_name(blocker),
1356 action_id_rule_name(act));
1357 ok = FALSE;
1358 }
1360
1362 if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1,
1363 "Action Enabler Actor Reqs")
1364 || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1,
1365 "Action Enabler Target Reqs")) {
1366 ruleset_error(logger, LOG_ERROR,
1367 _("Action enabler for %s has conflicting or invalid "
1368 "requirements!"), action_id_rule_name(act));
1369 ok = FALSE;
1370 }
1371
1373 /* Special test for self targeted actions. */
1374
1375 if (requirement_vector_size(&(enabler->target_reqs)) > 0) {
1376 /* Shouldn't have target requirements since the action doesn't
1377 * have a target. */
1378 ruleset_error(logger, LOG_ERROR,
1379 _("An action enabler for %s has a target "
1380 "requirement vector. %s doesn't have a target."),
1382 action_id_rule_name(act));
1383 ok = FALSE;
1384 }
1385 }
1386
1387 requirement_vector_iterate(&(enabler->target_reqs), preq) {
1388 if (preq->source.kind == VUT_DIPLREL
1389 && preq->range == REQ_RANGE_LOCAL) {
1390 struct astring astr;
1391
1392 /* A Local DiplRel requirement can be expressed as a requirement
1393 * in actor_reqs. Demand that it is there. This avoids breaking
1394 * code that reasons about actions. */
1395 ruleset_error(logger, LOG_ERROR,
1396 _("Action enabler for %s has a local DiplRel "
1397 "requirement %s in target_reqs! Please read the "
1398 "section \"Requirement vector rules\" in "
1399 "doc/README.actions"),
1402 astr_free(&astr);
1403 ok = FALSE;
1404 } else if (preq->source.kind == VUT_MAX_DISTANCE_SQ
1405 && preq->range == REQ_RANGE_TILE) {
1406 struct astring astr;
1407
1408 /* A Tile-ranged MaxDistanceSq requirement can be expressed as a
1409 * requirement in actor_reqs. Demand that it is there. */
1410 ruleset_error(logger, LOG_ERROR,
1411 _("Action enabler for %s has a tile MaxDistanceSq "
1412 "requirement %s in target_reqs! Please read the "
1413 "section \"Requirement vector rules\" in "
1414 "doc/README.actions"),
1417 astr_free(&astr);
1418 ok = FALSE;
1419 }
1421
1422 if (compat == nullptr || !compat->compat_mode
1423 || compat->version >= RSFORMAT_3_4) {
1424 /* Support for letting some of the following hard requirements be
1425 * implicit were retired in Freeciv 3.0. Others were retired later.
1426 * Make sure that the opposite of each hard action requirement
1427 * blocks all its action enablers. */
1428
1429 struct req_vec_problem *problem
1431
1432 if (problem != nullptr) {
1433 ruleset_error(logger, LOG_ERROR, "%s", problem->description);
1435 ok = FALSE;
1436 }
1437
1439 if (problem != nullptr) {
1440 /* There is a potential for improving this enabler. */
1441 log_deprecation("%s", problem->description);
1443 }
1444 }
1446
1448 /* The action performer, action_dice_roll_initial_odds() and the
1449 * action probability calculation in action_prob() must probably all
1450 * be updated to add a new action here. */
1467 ruleset_error(logger, LOG_ERROR,
1468 _("diplchance_initial_odds: \"%s\" not supported."),
1470 ok = FALSE;
1471 }
1472
1473 if (BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER)
1474 && BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)) {
1475 ruleset_error(logger, LOG_ERROR,
1476 _("%s both enters and frightens a hut at the same time."),
1478 ok = FALSE;
1479 }
1481
1482 /* Auto attack */
1483 {
1485
1487
1489 struct action *paction = action_by_number(act_id);
1490
1495 /* Only allow removing and changing the order of old auto
1496 * attack actions for now. Other actions need more testing and
1497 * fixing of issues caused by a worst case action probability of
1498 * 0%. */
1499 ruleset_error(logger, LOG_ERROR,
1500 _("auto_attack: %s not supported in"
1501 " attack_actions."),
1503 ok = FALSE;
1504 }
1506 }
1507
1508 /* There must be basic city style for each nation style to start with */
1511 ruleset_error(logger, LOG_ERROR,
1512 _("There's no basic city style for nation style %s"),
1514 ok = FALSE;
1515 }
1517
1518 /* Music styles */
1520 if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) {
1521 ruleset_error(logger, LOG_ERROR,
1522 _("Music Styles have conflicting or invalid requirements!"));
1523 ok = FALSE;
1524 }
1526
1529 if (!is_native_to_class(utype_class(panimal), pterr, nullptr)) {
1530 ruleset_error(logger, LOG_ERROR,
1531 _("%s has %s as animal to appear, but it's not native to the terrain."),
1533 ok = FALSE;
1534 break;
1535 }
1537
1539 (void) freq;
1541 ruleset_error(logger, LOG_ERROR,
1542 _("%s has %s as a resource, but it's not a resource extra."),
1544 ok = FALSE;
1545 }
1548
1549 /* Check that all unit classes can exist somewhere */
1552 bool can_exist = FALSE;
1553
1555 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
1556 can_exist = TRUE;
1557 break;
1558 }
1560
1561 if (!can_exist) {
1563 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
1564 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
1565 can_exist = TRUE;
1566 break;
1567 }
1569 }
1570
1571 if (!can_exist) {
1572 ruleset_error(logger, LOG_ERROR,
1573 _("Unit class %s cannot exist anywhere."),
1575 ok = FALSE;
1576 }
1577 }
1579
1581 if (!pach->unique && pach->cons_msg == nullptr) {
1582 ruleset_error(logger, LOG_ERROR,
1583 _("Achievement %s has no message for consecutive gainers though "
1584 "it's possible to be gained by multiple players"),
1586 ok = FALSE;
1587 }
1589
1590 if (game.server.ruledit.embedded_nations != nullptr) {
1591 int nati;
1592
1594 struct nation_type *pnat
1596
1597 if (pnat == nullptr) {
1598 ruleset_error(logger, LOG_ERROR,
1599 _("There's nation %s listed in embedded nations, but there's "
1600 "no such nation."),
1602 ok = FALSE;
1603 }
1604 }
1605 }
1606
1607 if (ok) {
1608 ok = rs_common_units(logger);
1609 }
1610 if (ok) {
1611 ok = rs_barbarian_units(logger);
1612 }
1613 if (ok) {
1614 ok = rs_buildings(logger);
1615 }
1616
1617 return ok;
1618}
1619
1620/**********************************************************************/
1626{
1627 bool ok = TRUE;
1628
1631 if (pextra != pextra2) {
1632 int idx = extra_index(pextra2);
1633
1634 if (!BV_ISSET(pextra->conflicts, idx)) {
1635 log_debug("Autoconflicting resource %s with %s",
1637 BV_SET(pextra->conflicts, extra_index(pextra2));
1638 }
1639 }
1642
1643 /* Hard coded action blocking. */
1644 {
1645 const struct {
1646 const enum action_result blocked;
1647 const enum action_result blocker;
1648 } must_block[] = {
1649 /* Hard code that Help Wonder blocks Disband Unit Recover. This must be done
1650 * because caravan_shields makes it possible to avoid the
1651 * consequences of choosing to do Disband Unit Recover rather than having it
1652 * do Help Wonder.
1653 *
1654 * Explanation: Disband Unit Recover adds 50% of the shields used to produce
1655 * the unit to the production of the city where it is located. Help
1656 * Wonder adds 100%. If a unit that can do Help Wonder is disbanded with
1657 * production recovery in a city and the production later is changed
1658 * to something that can receive help from Help Wonder the remaining 50%
1659 * of the shields are added. This can be done because the city remembers
1660 * them in caravan_shields.
1661 *
1662 * If a unit that can do Help Wonder intentionally is disbanded with recovery
1663 * rather than making it do Help Wonder its shields will still be
1664 * remembered. The target city that got 50% of the shields can
1665 * therefore get 100% of them by changing its production. This trick
1666 * makes the ability to select Disband Unit Recover when Help Wonder is legal
1667 * pointless. */
1669
1670 /* Allowing regular disband when ACTION_HELP_WONDER or
1671 * ACTION_DISBAND_UNIT_RECOVER is legal while ACTION_HELP_WONDER always
1672 * blocks ACTION_DISBAND_UNIT_RECOVER doesn't work well with the force_*
1673 * semantics. Should move to the ruleset once it has blocked_by
1674 * semantics. */
1677
1678 /* Hard code that the ability to perform a regular attack blocks city
1679 * conquest. Is redundant as long as the requirement that the target
1680 * tile has no units remains hard coded. Kept "just in case" that
1681 * changes. */
1683
1684 /* Hard code that the ability to perform a regular attack blocks
1685 * extras conquest. Is redundant as long as the requirement that the
1686 * target tile has no non-allied units remains hard coded. Kept "just
1687 * in case" that changes. */
1689
1690 /* Hard code that the ability to enter or frighten a hut blocks
1691 * regular disembarking. */
1695 };
1696
1697 int i;
1698
1699 for (i = 0; i < ARRAY_SIZE(must_block); i++) {
1700 enum action_result blocked_result = must_block[i].blocked;
1701 enum action_result blocker_result = must_block[i].blocker;
1702
1705 if (!action_would_be_blocked_by(blocked, blocker)) {
1706 log_verbose("Autoblocking %s with %s",
1707 action_rule_name(blocked),
1708 action_rule_name(blocker));
1709 BV_SET(blocked->blocked_by, action_id(blocker));
1710 }
1713 }
1714 }
1715
1716 return ok;
1717}
1718
1719/**********************************************************************/
1723{
1724 bool ok = TRUE;
1725
1726 if (num_role_units(L_BARBARIAN) == 0) {
1727 struct setting *pset = setting_by_name("barbarians");
1728
1729 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
1730 "unit types."));
1732 if (!setting_enum_set(pset, "DISABLED", nullptr, nullptr, 0)) {
1733 ok = FALSE;
1734 }
1736 }
1737
1738 return ok;
1739}
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:5956
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:5593
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:1822
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:77
#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:1329
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:1210
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:765
int Tech_type_id
Definition fc_types.h:238
int ssetv
Definition fc_types.h:508
@ RPT_POSSIBLE
Definition fc_types.h:515
int action_id
Definition fc_types.h:250
#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:132
#define governments_re_active_iterate(_p)
Definition government.h:141
#define governments_re_active_iterate_end
Definition government.h:145
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:919
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:212
#define nations_re_active_iterate_end
Definition nation.h:370
#define nations_re_active_iterate(_pnat_)
Definition nation.h:367
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:910
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:505
bool sanity_check_server_setting_value_in_req(ssetv ssetval)
Definition rssanity.c:145
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:259
static bool sanity_check_boolean_effects(rs_conversion_logger logger)
Definition rssanity.c:858
static bool sanity_check_setting_is_seen(struct setting *pset)
Definition rssanity.c:109
static bool sanity_check_req_individual(rs_conversion_logger logger, struct requirement *preq, const char *list_for)
Definition rssanity.c:172
static bool rs_buildings(rs_conversion_logger logger)
Definition rssanity.c:791
enum effect_type req_base_effects_3_4[]
Definition rssanity.c:53
static bool sanity_check_metadata(rs_conversion_logger logger)
Definition rssanity.c:62
bool autolock_settings(void)
Definition rssanity.c:1722
static bool rs_common_units(rs_conversion_logger logger)
Definition rssanity.c:712
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1625
static bool rs_barbarian_units(rs_conversion_logger logger)
Definition rssanity.c:640
static bool effect_list_sanity_cb(struct effect *peffect, void *data)
Definition rssanity.c:547
static bool sanity_check_setting_is_game_rule(struct setting *pset)
Definition rssanity.c:118
static bool nation_has_initial_tech(struct nation_type *pnation, struct advance *tech)
Definition rssanity.c:80
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:2455
#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:541
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:104
int basic_city_style_for_style(struct nation_style *pstyle)
Definition style.c:204
#define music_styles_re_active_iterate_end
Definition style.h:91
#define music_styles_re_active_iterate(_p)
Definition style.h:88
#define styles_re_active_iterate_end
Definition style.h:62
#define styles_re_active_iterate(_p)
Definition style.h:58
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:110
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Definition tech.c:139
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:181
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:314
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:100
#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:249
#define terrain_re_active_iterate_end
Definition terrain.h:282
#define terrain_animals_iterate(pterrain, _animal)
Definition terrain.h:299
#define is_ocean(pterrain)
Definition terrain.h:195
#define terrain_re_active_iterate(_p)
Definition terrain.h:278
#define terrain_resources_iterate_end
Definition terrain.h:295
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:286
#define terrain_animals_iterate_end
Definition terrain.h:307
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:3002
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2284
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:224
int num_role_units(int role)
Definition unittype.c:2234
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:877
#define utype_class(_t_)
Definition unittype.h:756
#define unit_class_iterate(_p)
Definition unittype.h:918
#define unit_class_re_active_iterate_end
Definition unittype.h:934
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:865
#define unit_class_re_active_iterate(_p)
Definition unittype.h:930
#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:925
#define unit_type_iterate_end
Definition unittype.h:872
#define unit_type_re_active_iterate_end
Definition unittype.h:881