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 "deprecations.h"
20
21 /* common */
22 #include "achievements.h"
23 #include "effects.h"
24 #include "game.h"
25 #include "government.h"
26 #include "movement.h"
27 #include "player.h"
28 #include "road.h"
29 #include "specialist.h"
30 #include "tech.h"
31
32 /* server */
33 #include "ruleset.h"
34 #include "settings.h"
35
36 #include "rssanity.h"
37
38 /**************************************************************************
39 Is non-rule data in ruleset sane?
40 **************************************************************************/
sanity_check_metadata(void)41 static bool sanity_check_metadata(void)
42 {
43 if (game.ruleset_summary != NULL &&
44 strlen(game.ruleset_summary) > MAX_LEN_CONTENT) {
45 log_error("Too long ruleset summary. It can be only %d bytes long. "
46 "Put longer explanations to ruleset description.",
47 MAX_LEN_CONTENT);
48 return FALSE;
49 }
50
51 return TRUE;
52 }
53
54 /**************************************************************************
55 Does nation have tech initially?
56 **************************************************************************/
nation_has_initial_tech(struct nation_type * pnation,struct advance * tech)57 static bool nation_has_initial_tech(struct nation_type *pnation,
58 struct advance *tech)
59 {
60 int i;
61
62 /* See if it's given as global init tech */
63 for (i = 0; i < MAX_NUM_TECH_LIST
64 && game.rgame.global_init_techs[i] != A_LAST; i++) {
65 if (game.rgame.global_init_techs[i] == advance_number(tech)) {
66 return TRUE;
67 }
68 }
69
70 /* See if it's given as national init tech */
71 for (i = 0;
72 i < MAX_NUM_TECH_LIST && pnation->init_techs[i] != A_LAST;
73 i++) {
74 if (pnation->init_techs[i] == advance_number(tech)) {
75 return TRUE;
76 }
77 }
78
79 return FALSE;
80 }
81
82 /**************************************************************************
83 Sanity checks on a requirement in isolation.
84 This will generally be things that could only not be checked at
85 ruleset load time because they would have referenced things not yet
86 loaded from the ruleset.
87 **************************************************************************/
sanity_check_req_individual(struct requirement * preq,const char * list_for)88 static bool sanity_check_req_individual(struct requirement *preq,
89 const char *list_for)
90 {
91 switch (preq->source.kind) {
92 case VUT_IMPROVEMENT:
93 /* This check corresponds to what is_req_active() will support.
94 * It can't be done in req_from_str(), as we may not have
95 * loaded all building information at that time. */
96 {
97 struct impr_type *pimprove = preq->source.value.building;
98 if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) {
99 log_error("%s: World-ranged requirement not supported for "
100 "%s (only great wonders supported)", list_for,
101 improvement_name_translation(pimprove));
102 return FALSE;
103 } else if (preq->range > REQ_RANGE_TRADEROUTE && !is_wonder(pimprove)) {
104 log_error("%s: %s-ranged requirement not supported for "
105 "%s (only wonders supported)", list_for,
106 req_range_name(preq->range),
107 improvement_name_translation(pimprove));
108 return FALSE;
109 }
110 }
111 break;
112 default:
113 /* No other universals have checks that can't be done at ruleset
114 * load time. See req_from_str(). */
115 break;
116 }
117 return TRUE;
118 }
119
120 /**************************************************************************
121 Helper function for sanity_check_req_list() and sanity_check_req_vec()
122 **************************************************************************/
sanity_check_req_set(int reqs_of_type[],int local_reqs_of_type[],struct requirement * preq,bool conjunctive,int max_tiles,const char * list_for)123 static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[],
124 struct requirement *preq, bool conjunctive,
125 int max_tiles, const char *list_for)
126 {
127 int rc;
128
129 fc_assert_ret_val(universals_n_is_valid(preq->source.kind), FALSE);
130
131 if (!sanity_check_req_individual(preq, list_for)) {
132 return FALSE;
133 }
134
135 if (!conjunctive) {
136 /* All the checks below are only meaningful for conjunctive lists. */
137 /* FIXME: we could add checks suitable for disjunctive lists. */
138 return TRUE;
139 }
140
141 /* Add to counter for positive requirements. */
142 if (preq->present) {
143 reqs_of_type[preq->source.kind]++;
144 }
145 rc = reqs_of_type[preq->source.kind];
146
147 if (preq->range == REQ_RANGE_LOCAL && preq->present) {
148 local_reqs_of_type[preq->source.kind]++;
149
150 switch (preq->source.kind) {
151 case VUT_TERRAINCLASS:
152 if (local_reqs_of_type[VUT_TERRAIN] > 0) {
153 log_error("%s: Requirement list has both local terrain and terrainclass requirement",
154 list_for);
155 return FALSE;
156 }
157 break;
158 case VUT_TERRAIN:
159 if (local_reqs_of_type[VUT_TERRAINCLASS] > 0) {
160 log_error("%s: Requirement list has both local terrain and terrainclass requirement",
161 list_for);
162 return FALSE;
163 }
164 break;
165 default:
166 break;
167 }
168 }
169
170 if (rc > 1 && preq->present) {
171 /* Multiple requirements of the same type */
172 switch (preq->source.kind) {
173 case VUT_GOVERNMENT:
174 case VUT_UTYPE:
175 case VUT_UCLASS:
176 case VUT_OTYPE:
177 case VUT_SPECIALIST:
178 case VUT_MINSIZE: /* Breaks nothing, but has no sense either */
179 case VUT_MINMOVES: /* Breaks nothing, but has no sense either */
180 case VUT_MINVETERAN: /* Breaks nothing, but has no sense either */
181 case VUT_MINHP: /* Breaks nothing, but has no sense either */
182 case VUT_MINYEAR:
183 case VUT_AI_LEVEL:
184 case VUT_TERRAINALTER: /* Local range only */
185 case VUT_CITYTILE:
186 case VUT_STYLE:
187 /* There can be only one requirement of these types (with current
188 * range limitations)
189 * Requirements might be identical, but we consider multiple
190 * declarations error anyway. */
191
192 log_error("%s: Requirement list has multiple %s requirements",
193 list_for, universal_type_rule_name(&preq->source));
194 return FALSE;
195 break;
196
197 case VUT_TERRAIN:
198 case VUT_RESOURCE:
199 /* There can be only up to max_tiles requirements of these types */
200 if (max_tiles != -1 && rc > max_tiles) {
201 log_error("%s: Requirement list has more %s requirements than "
202 "can ever be fulfilled.", list_for,
203 universal_type_rule_name(&preq->source));
204 return FALSE;
205 }
206 break;
207
208 case VUT_TERRAINCLASS:
209 if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) {
210 log_error("%s: Requirement list has more %s requirements than "
211 "can ever be fulfilled.", list_for,
212 universal_type_rule_name(&preq->source));
213 return FALSE;
214 }
215 break;
216
217 case VUT_AGE:
218 /* There can be age of the city, unit, and player */
219 if (rc > 3) {
220 log_error("%s: Requirement list has more %s requirements than "
221 "can ever be fulfilled.", list_for,
222 universal_type_rule_name(&preq->source));
223 return FALSE;
224 }
225 break;
226
227 case VUT_TOPO:
228 /* Can have multiple, since it's flag based (iso & wrapx & wrapy & hex) */
229 case VUT_EXTRA:
230 /* Note that there can be more than 1 extra / tile. */
231 case VUT_MAXTILEUNITS:
232 /* Can require different numbers on e.g. local/adjacent tiles. */
233 case VUT_NATION:
234 /* Can require multiple nations at Team/Alliance/World range. */
235 case VUT_NATIONGROUP:
236 /* Nations can be in multiple groups. */
237 case VUT_NONE:
238 case VUT_ADVANCE:
239 case VUT_TECHFLAG:
240 case VUT_IMPROVEMENT:
241 case VUT_UNITSTATE:
242 /* Can check different properties. */
243 case VUT_UTFLAG:
244 case VUT_UCFLAG:
245 case VUT_TERRFLAG:
246 case VUT_BASEFLAG:
247 case VUT_ROADFLAG:
248 case VUT_EXTRAFLAG:
249 case VUT_NATIONALITY:
250 case VUT_MINCULTURE:
251 case VUT_ACHIEVEMENT:
252 case VUT_DIPLREL:
253 /* Can have multiple requirements of these types */
254 break;
255 case VUT_COUNT:
256 /* Should never be in requirement vector */
257 fc_assert(FALSE);
258 return FALSE;
259 break;
260 /* No default handling here, as we want compiler warning
261 * if new requirement type is added to enum and it's not handled
262 * here. */
263 }
264 }
265
266 return TRUE;
267 }
268
269 /**************************************************************************
270 Sanity check requirement vector, including whether it's free of
271 conflicting requirements.
272 'conjunctive' should be TRUE if the vector is an AND vector (all requirements
273 must be active), FALSE if it's a disjunctive (OR) vector.
274 max_tiles is number of tiles that can provide requirement. Value -1
275 disables checking based on number of tiles.
276
277 Returns TRUE iff everything ok.
278
279 TODO: This is based on current hardcoded range limitations.
280 - There should be method of automatically determining these
281 limitations for each requirement type
282 - This function should check also problems caused by defining
283 range to less than hardcoded max for requirement type
284 **************************************************************************/
sanity_check_req_vec(const struct requirement_vector * preqs,bool conjunctive,int max_tiles,const char * list_for)285 static bool sanity_check_req_vec(const struct requirement_vector *preqs,
286 bool conjunctive, int max_tiles,
287 const char *list_for)
288 {
289 int reqs_of_type[VUT_COUNT];
290 int local_reqs_of_type[VUT_COUNT];
291
292 /* Initialize requirement counters */
293 memset(reqs_of_type, 0, sizeof(reqs_of_type));
294 memset(local_reqs_of_type, 0, sizeof(local_reqs_of_type));
295
296 requirement_vector_iterate(preqs, preq) {
297 if (!sanity_check_req_set(reqs_of_type, local_reqs_of_type, preq,
298 conjunctive, max_tiles, list_for)) {
299 return FALSE;
300 }
301 requirement_vector_iterate(preqs, nreq) {
302 if (are_requirements_contradictions(preq, nreq)) {
303 log_error("%s: Requirements {%s} and {%s} contradict each other.",
304 list_for,
305 req_to_fstring(preq),
306 req_to_fstring(nreq));
307 return FALSE;
308 }
309 } requirement_vector_iterate_end;
310 } requirement_vector_iterate_end;
311
312 return TRUE;
313 }
314
315 /**************************************************************************
316 Sanity check callback for iterating effects cache.
317 **************************************************************************/
effect_list_sanity_cb(const struct effect * peffect,void * data)318 static bool effect_list_sanity_cb(const struct effect *peffect, void *data)
319 {
320 int one_tile = -1; /* TODO: Determine correct value from effect.
321 * -1 disables checking */
322
323 return sanity_check_req_vec(&peffect->reqs, TRUE, one_tile,
324 effect_type_name(peffect->type));
325 }
326
327 /**************************************************************************
328 Sanity check barbarian unit types
329 **************************************************************************/
rs_barbarian_units(void)330 static bool rs_barbarian_units(void)
331 {
332 if (num_role_units(L_BARBARIAN) > 0) {
333 if (num_role_units(L_BARBARIAN_LEADER) == 0) {
334 ruleset_error(LOG_ERROR, "No role barbarian leader units");
335 return FALSE;
336 }
337 if (num_role_units(L_BARBARIAN_BUILD) == 0) {
338 ruleset_error(LOG_ERROR, "No role barbarian build units");
339 return FALSE;
340 }
341 if (num_role_units(L_BARBARIAN_BOAT) == 0) {
342 ruleset_error(LOG_ERROR, "No role barbarian ship units");
343 return FALSE;
344 } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
345 bool sea_capable = FALSE;
346 struct unit_type *u = get_role_unit(L_BARBARIAN_BOAT, 0);
347
348 terrain_type_iterate(pterr) {
349 if (is_ocean(pterr)
350 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
351 sea_capable = TRUE;
352 break;
353 }
354 } terrain_type_iterate_end;
355
356 if (!sea_capable) {
357 ruleset_error(LOG_ERROR,
358 "Barbarian boat (%s) needs to be able to move at sea.",
359 utype_rule_name(u));
360 return FALSE;
361 }
362 }
363 if (num_role_units(L_BARBARIAN_SEA) == 0) {
364 ruleset_error(LOG_ERROR, "No role sea raider barbarian units");
365 return FALSE;
366 }
367
368 unit_type_iterate(ptype) {
369 if (utype_has_role(ptype, L_BARBARIAN_BOAT)) {
370 if (ptype->transport_capacity <= 1) {
371 ruleset_error(LOG_ERROR,
372 "Barbarian boat %s has no capacity for both "
373 "leader and at least one man.",
374 utype_rule_name(ptype));
375 return FALSE;
376 }
377
378 unit_type_iterate(pbarb) {
379 if (utype_has_role(pbarb, L_BARBARIAN_SEA)
380 || utype_has_role(pbarb, L_BARBARIAN_SEA_TECH)
381 || utype_has_role(pbarb, L_BARBARIAN_LEADER)) {
382 if (!can_unit_type_transport(ptype, utype_class(pbarb))) {
383 ruleset_error(LOG_ERROR,
384 "Barbarian boat %s cannot transport "
385 "barbarian cargo %s.",
386 utype_rule_name(ptype),
387 utype_rule_name(pbarb));
388 return FALSE;
389 }
390 }
391 } unit_type_iterate_end;
392 }
393 } unit_type_iterate_end;
394 }
395
396 return TRUE;
397 }
398
399 /**************************************************************************
400 Sanity check common unit types
401 **************************************************************************/
rs_common_units(void)402 static bool rs_common_units(void)
403 {
404 /* Check some required flags and roles etc: */
405 if (num_role_units(UTYF_SETTLERS) == 0) {
406 ruleset_error(LOG_ERROR, "No flag Settler units");
407 return FALSE;
408 }
409 if (num_role_units(L_START_EXPLORER) == 0) {
410 ruleset_error(LOG_ERROR, "No role Start Explorer units");
411 }
412 if (num_role_units(L_FERRYBOAT) == 0) {
413 ruleset_error(LOG_ERROR, "No role Ferryboat units");
414 }
415 if (num_role_units(L_FIRSTBUILD) == 0) {
416 ruleset_error(LOG_ERROR, "No role Firstbuild units");
417 }
418
419 if (num_role_units(L_FERRYBOAT) > 0) {
420 bool sea_capable = FALSE;
421 struct unit_type *u = get_role_unit(L_FERRYBOAT, 0);
422
423 terrain_type_iterate(pterr) {
424 if(is_ocean(pterr)
425 && BV_ISSET(pterr->native_to, uclass_index(utype_class(u)))) {
426 sea_capable = TRUE;
427 break;
428 }
429 } terrain_type_iterate_end;
430
431 if (!sea_capable) {
432 ruleset_error(LOG_ERROR,
433 "Ferryboat (%s) needs to be able to move at sea.",
434 utype_rule_name(u));
435 return FALSE;
436 }
437 }
438
439 if (num_role_units(L_PARTISAN) == 0
440 && effect_cumulative_max(EFT_INSPIRE_PARTISANS, NULL) > 0) {
441 ruleset_error(LOG_ERROR,
442 "Inspire_Partisans effect present, but no units with partisan role.");
443 return FALSE;
444 }
445
446 return TRUE;
447 }
448
449 /**************************************************************************
450 Sanity check buildings
451 **************************************************************************/
rs_buildings(void)452 static bool rs_buildings(void)
453 {
454 /* Special Genus */
455 improvement_iterate(pimprove) {
456 if (improvement_has_flag(pimprove, IF_GOLD)
457 && pimprove->genus != IG_SPECIAL) {
458 ruleset_error(LOG_ERROR,
459 "Gold producing improvement %s with genus other than \"Special\"",
460 improvement_rule_name(pimprove));
461
462 return FALSE;
463 }
464
465 if (is_wonder(pimprove) && pimprove->upkeep != 0) {
466 /* Not treating this as a hard error for the sake of the rulesets
467 * already in the wild. */
468 log_deprecation("Ignoring nonzero upkeep value of %s as it's a wonder",
469 improvement_rule_name(pimprove));
470 pimprove->upkeep = 0; /* Forced also in city_improvement_upkeep() */
471 }
472 } improvement_iterate_end;
473
474 return TRUE;
475 }
476
477 /**************************************************************************
478 Check that boolean effect types have sensible effects.
479 **************************************************************************/
sanity_check_boolean_effects(void)480 static bool sanity_check_boolean_effects(void)
481 {
482 enum effect_type boolean_effects[] =
483 {
484 EFT_ANY_GOVERNMENT,
485 EFT_CAPITAL_CITY,
486 EFT_ENABLE_NUKE,
487 EFT_ENABLE_SPACE,
488 EFT_HAVE_EMBASSIES,
489 EFT_NO_ANARCHY,
490 EFT_NUKE_PROOF,
491 EFT_REVEAL_CITIES,
492 EFT_REVEAL_MAP,
493 EFT_SIZE_UNLIMIT,
494 EFT_SS_STRUCTURAL,
495 EFT_SS_COMPONENT,
496 EFT_NO_UNHAPPY,
497 EFT_RAPTURE_GROW,
498 EFT_HAS_SENATE,
499 EFT_INSPIRE_PARTISANS,
500 EFT_HAPPINESS_TO_GOLD,
501 EFT_FANATICS,
502 EFT_NO_DIPLOMACY,
503 EFT_IRRIG_POSSIBLE,
504 EFT_GOV_CENTER,
505 EFT_TRANSFORM_POSSIBLE,
506 EFT_MINING_POSSIBLE,
507 EFT_IRRIG_TF_POSSIBLE,
508 EFT_MINING_TF_POSSIBLE,
509 EFT_NOT_TECH_SOURCE,
510 EFT_VICTORY,
511 EFT_COUNT
512 };
513 int i;
514 bool ret = TRUE;
515
516 for (i = 0; boolean_effects[i] != EFT_COUNT; i++) {
517 if (effect_cumulative_min(boolean_effects[i], NULL) < 0
518 && effect_cumulative_max(boolean_effects[i], NULL) == 0) {
519 ruleset_error(LOG_ERROR, "Boolean effect %s can get disabled, but it can't get "
520 "enabled before that.", effect_type_name(boolean_effects[i]));
521 ret = FALSE;
522 }
523 }
524
525 return ret;
526 }
527
528 /**************************************************************************
529 Some more sanity checking once all rulesets are loaded. These check
530 for some cross-referencing which was impossible to do while only one
531 party was loaded in load_ruleset_xxx()
532
533 Returns TRUE iff everything ok.
534 **************************************************************************/
sanity_check_ruleset_data(void)535 bool sanity_check_ruleset_data(void)
536 {
537 int num_utypes;
538 int i;
539 bool ok = TRUE; /* Store failures to variable instead of returning
540 * immediately so all errors get printed, not just first
541 * one. */
542 bool default_gov_failed = FALSE;
543 bool obsoleted_by_loop = FALSE;
544
545 if (!sanity_check_metadata()) {
546 ok = FALSE;
547 }
548
549 if (game.info.tech_cost_style == TECH_COST_CIV1CIV2
550 && game.info.free_tech_method == FTM_CHEAPEST) {
551 ruleset_error(LOG_ERROR, "Cost based free tech method, but tech cost style "
552 "\"Civ I|II\" so all techs cost the same.");
553 ok = FALSE;
554 }
555
556 /* Advances. */
557 advance_iterate(A_FIRST, padvance) {
558 for (i = AR_ONE; i < AR_SIZE; i++) {
559 const struct advance *preq;
560
561 if (i == AR_ROOT) {
562 /* Self rootreq is a feature. */
563 continue;
564 }
565
566 preq = advance_requires(padvance, i);
567
568 if (A_NEVER == preq) {
569 continue;
570 } else if (preq == padvance) {
571 ruleset_error(LOG_ERROR, "Tech \"%s\" requires itself.",
572 advance_rule_name(padvance));
573 ok = FALSE;
574 continue;
575 }
576
577 advance_req_iterate(preq, preqreq) {
578 if (preqreq == padvance) {
579 ruleset_error(LOG_ERROR,
580 "Tech \"%s\" requires itself indirectly via \"%s\".",
581 advance_rule_name(padvance),
582 advance_rule_name(preq));
583 ok = FALSE;
584 }
585 } advance_req_iterate_end;
586 }
587
588 if (padvance->bonus_message != NULL) {
589 if (!formats_match(padvance->bonus_message, "%s")) {
590 ruleset_error(LOG_ERROR,
591 "Tech \"%s\" bonus message is not format with %%s for a bonus tech name.",
592 advance_rule_name(padvance));
593 ok = FALSE;
594 }
595 }
596 } advance_iterate_end;
597
598 if (game.default_government == game.government_during_revolution) {
599 ruleset_error(LOG_ERROR,
600 "The government form %s reserved for revolution handling has been set as "
601 "default_government.",
602 government_rule_name(game.government_during_revolution));
603 ok = FALSE;
604 default_gov_failed = TRUE;
605 }
606
607 /* Check that all players can have their initial techs */
608 nations_iterate(pnation) {
609 int techi;
610
611 /* Check global initial techs */
612 for (techi = 0; techi < MAX_NUM_TECH_LIST
613 && game.rgame.global_init_techs[techi] != A_LAST; techi++) {
614 Tech_type_id tech = game.rgame.global_init_techs[techi];
615 struct advance *a = valid_advance_by_number(tech);
616
617 if (a == NULL) {
618 ruleset_error(LOG_ERROR,
619 "Tech %s does not exist, but is initial "
620 "tech for everyone.",
621 advance_rule_name(advance_by_number(tech)));
622 ok = FALSE;
623 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
624 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
625 /* Nation has no root_req for tech */
626 ruleset_error(LOG_ERROR,
627 "Tech %s is initial for everyone, but %s has "
628 "no root_req for it.",
629 advance_rule_name(a),
630 nation_rule_name(pnation));
631 ok = FALSE;
632 }
633 }
634
635 /* Check national initial techs */
636 for (techi = 0;
637 techi < MAX_NUM_TECH_LIST && pnation->init_techs[techi] != A_LAST;
638 techi++) {
639 Tech_type_id tech = pnation->init_techs[techi];
640 struct advance *a = valid_advance_by_number(tech);
641
642 if (a == NULL) {
643 ruleset_error(LOG_ERROR,
644 "Tech %s does not exist, but is tech for %s.",
645 advance_rule_name(advance_by_number(tech)),
646 nation_rule_name(pnation));
647 ok = FALSE;
648 } else if (advance_by_number(A_NONE) != a->require[AR_ROOT]
649 && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) {
650 /* Nation has no root_req for tech */
651 ruleset_error(LOG_ERROR,
652 "Tech %s is initial for %s, but they have "
653 "no root_req for it.",
654 advance_rule_name(a),
655 nation_rule_name(pnation));
656 ok = FALSE;
657 }
658 }
659
660 /* Check national initial buildings */
661 if (nation_barbarian_type(pnation) != NOT_A_BARBARIAN
662 && pnation->init_buildings[0] != B_LAST) {
663 ruleset_error(LOG_ERROR,
664 "Barbarian nation %s has init_buildings set but will "
665 "never see them", nation_rule_name(pnation));
666 }
667
668 if (!default_gov_failed && pnation->init_government == game.government_during_revolution) {
669 ruleset_error(LOG_ERROR,
670 "The government form %s reserved for revolution handling has been set as "
671 "initial government for %s.",
672 government_rule_name(game.government_during_revolution),
673 nation_rule_name(pnation));
674 ok = FALSE;
675 }
676 } nations_iterate_end;
677
678 /* Check against unit upgrade loops */
679 num_utypes = game.control.num_unit_types;
680 unit_type_iterate(putype) {
681 int chain_length = 0;
682 struct unit_type *upgraded = putype;
683
684 while (upgraded != NULL && !obsoleted_by_loop) {
685 upgraded = upgraded->obsoleted_by;
686 chain_length++;
687 if (chain_length > num_utypes) {
688 ruleset_error(LOG_ERROR,
689 "There seems to be obsoleted_by loop in update "
690 "chain that starts from %s", utype_rule_name(putype));
691 ok = FALSE;
692 obsoleted_by_loop = TRUE;
693 }
694 }
695 } unit_type_iterate_end;
696
697 /* Some unit type properties depend on other unit type properties to work
698 * properly. */
699 unit_type_iterate(putype) {
700 /* "Spy" is a better "Diplomat". Until all the places that assume that
701 * "Diplomat" is set if "Spy" is set is changed this limitation must be
702 * kept. */
703 if (utype_has_flag(putype, UTYF_SPY)
704 && !utype_has_flag(putype, UTYF_DIPLOMAT)) {
705 ruleset_error(LOG_ERROR,
706 "The unit type '%s' has the 'Spy' unit type flag but "
707 "not the 'Diplomat' unit type flag.",
708 utype_rule_name(putype));
709 ok = FALSE;
710 }
711
712 /* The ability to bombard requires a bombard_rate. */
713 if (utype_has_flag(putype, UTYF_BOMBARDER)
714 && putype->bombard_rate <= 0) {
715 ruleset_error(LOG_ERROR,
716 "The unit type '%s' has the 'Bombarder' unit type flag"
717 " but no bombard_rate is set.",
718 utype_rule_name(putype));
719 ok = FALSE;
720 }
721 } unit_type_iterate_end;
722
723 /* Check that unit type fields are in range. */
724 unit_type_iterate(putype) {
725 if (putype->paratroopers_range < 0
726 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) {
727 /* Paradrop range is limited by the network protocol. */
728 ruleset_error(LOG_ERROR,
729 "The paratroopers_range of the unit type '%s' is %d. "
730 "That is out of range. Max range is %d.",
731 utype_rule_name(putype),
732 putype->paratroopers_range, UNIT_MAX_PARADROP_RANGE);
733 ok = FALSE;
734 }
735 } unit_type_iterate_end;
736
737 /* Check requirement sets against conflicting requirements.
738 * Effects use requirement lists */
739 if (!iterate_effect_cache(effect_list_sanity_cb, NULL)) {
740 ruleset_error(LOG_ERROR,
741 "Effects have conflicting or invalid requirements!");
742 ok = FALSE;
743 }
744
745 if (!sanity_check_boolean_effects()) {
746 ok = FALSE;
747 }
748
749 /* Others use requirement vectors */
750
751 /* Disasters */
752 disaster_type_iterate(pdis) {
753 if (!sanity_check_req_vec(&pdis->reqs, TRUE, -1,
754 disaster_rule_name(pdis))) {
755 ruleset_error(LOG_ERROR,
756 "Disasters have conflicting or invalid requirements!");
757 ok = FALSE;
758 }
759 } disaster_type_iterate_end;
760
761 /* Buildings */
762 improvement_iterate(pimprove) {
763 if (!sanity_check_req_vec(&pimprove->reqs, TRUE, -1,
764 improvement_rule_name(pimprove))) {
765 ruleset_error(LOG_ERROR,
766 "Buildings have conflicting or invalid requirements!");
767 ok = FALSE;
768 }
769 if (!sanity_check_req_vec(&pimprove->obsolete_by, FALSE, -1,
770 improvement_rule_name(pimprove))) {
771 ruleset_error(LOG_ERROR,
772 "Buildings have conflicting or invalid obsolescence req!");
773 ok = FALSE;
774 }
775 } improvement_iterate_end;
776
777 /* Governments */
778 governments_iterate(pgov) {
779 if (!sanity_check_req_vec(&pgov->reqs, TRUE, -1,
780 government_rule_name(pgov))) {
781 ruleset_error(LOG_ERROR,
782 "Governments have conflicting or invalid requirements!");
783 ok = FALSE;
784 }
785 } governments_iterate_end;
786
787 /* Specialists */
788 specialist_type_iterate(sp) {
789 struct specialist *psp = specialist_by_number(sp);
790
791 if (!sanity_check_req_vec(&psp->reqs, TRUE, -1,
792 specialist_rule_name(psp))) {
793 ruleset_error(LOG_ERROR,
794 "Specialists have conflicting or invalid requirements!");
795 ok = FALSE;
796 }
797 } specialist_type_iterate_end;
798
799 /* Extras */
800 extra_type_iterate(pextra) {
801 if (!sanity_check_req_vec(&pextra->reqs, TRUE, -1,
802 extra_rule_name(pextra))) {
803 ruleset_error(LOG_ERROR,
804 "Extras have conflicting or invalid requirements!");
805 ok = FALSE;
806 }
807 if (!sanity_check_req_vec(&pextra->rmreqs, TRUE, -1,
808 extra_rule_name(pextra))) {
809 ruleset_error(LOG_ERROR,
810 "Extras have conflicting or invalid removal requirements!");
811 ok = FALSE;
812 }
813 } extra_type_iterate_end;
814
815 /* Roads */
816 extra_type_by_cause_iterate(EC_ROAD, pextra) {
817 struct road_type *proad = extra_road_get(pextra);
818
819 extra_type_list_iterate(proad->integrators, iextra) {
820 struct road_type *iroad = extra_road_get(iextra);
821
822 if (road_index(proad) != road_index(iroad)
823 && !BV_ISSET(iroad->integrates, road_index(proad))) {
824 /* We don't support non-symmetric integrator relationships yet. */
825 ruleset_error(LOG_ERROR,
826 "Road '%s' integrates with '%s' but not vice versa!",
827 extra_rule_name(pextra),
828 extra_rule_name(iextra));
829 ok = FALSE;
830 }
831 } extra_type_list_iterate_end;
832 } extra_type_by_cause_iterate_end;
833
834 /* City styles */
835 for (i = 0; i < game.control.styles_count; i++) {
836 if (!sanity_check_req_vec(&city_styles[i].reqs, TRUE, -1,
837 city_style_rule_name(i))) {
838 ruleset_error(LOG_ERROR,
839 "City styles have conflicting or invalid requirements!");
840 ok = FALSE;
841 }
842 }
843
844 /* Action enablers */
845 action_iterate(act) {
846 action_enabler_list_iterate(action_enablers_for_action(act), enabler) {
847 if (!sanity_check_req_vec(&(enabler->actor_reqs), TRUE, -1,
848 "Action Enabler Actor Reqs")
849 || !sanity_check_req_vec(&(enabler->target_reqs), TRUE, -1,
850 "Action Enabler Target Reqs")) {
851 ruleset_error(LOG_ERROR,
852 "Action enabler for %s has conflicting or invalid "
853 "requirements!", action_id_rule_name(act));
854 ok = FALSE;
855 }
856
857 requirement_vector_iterate(&(enabler->target_reqs), preq) {
858 if (preq->source.kind == VUT_DIPLREL
859 && preq->range == REQ_RANGE_LOCAL) {
860 /* A Local DiplRel requirement can be expressed as a requirement
861 * in actor_reqs. Demand that it is there. This avoids breaking
862 * code that reasons about actions. */
863 ruleset_error(LOG_ERROR,
864 "Action enabler for %s has a local DiplRel "
865 "requirement %s in target_reqs! Please read the "
866 "section \"Requirement vector rules\" in "
867 "doc/README.actions",
868 action_id_rule_name(act),
869 req_to_fstring(preq));
870 ok = FALSE;
871 }
872 } requirement_vector_iterate_end;
873 } action_enabler_list_iterate_end;
874 } action_iterate_end;
875
876 /* There must be basic city style for each nation style to start with */
877 styles_iterate(pstyle) {
878 if (basic_city_style_for_style(pstyle) < 0) {
879 ruleset_error(LOG_ERROR,
880 "There's no basic city style for nation style %s",
881 style_rule_name(pstyle));
882 ok = FALSE;
883 }
884 } styles_iterate_end;
885
886 /* Music styles */
887 music_styles_iterate(pmus) {
888 if (!sanity_check_req_vec(&pmus->reqs, TRUE, -1, "Music Style")) {
889 ruleset_error(LOG_ERROR,
890 "Music Styles have conflicting or invalid requirements!");
891 ok = FALSE;
892 }
893 } music_styles_iterate_end;
894
895 terrain_type_iterate(pterr) {
896 if (pterr->animal != NULL) {
897 if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) {
898 ruleset_error(LOG_ERROR,
899 "%s has %s as animal to appear, but it's not native to the terrain.",
900 terrain_rule_name(pterr), utype_rule_name(pterr->animal));
901 ok = FALSE;
902 }
903 }
904 } terrain_type_iterate_end;
905
906 /* Check that all unit classes can exist somewhere */
907 unit_class_iterate(pclass) {
908 if (!uclass_has_flag(pclass, UCF_BUILD_ANYWHERE)) {
909 bool can_exist = FALSE;
910
911 terrain_type_iterate(pterr) {
912 if (BV_ISSET(pterr->native_to, uclass_index(pclass))) {
913 can_exist = TRUE;
914 break;
915 }
916 } terrain_type_iterate_end;
917
918 if (!can_exist) {
919 extra_type_iterate(pextra) {
920 if (BV_ISSET(pextra->native_to, uclass_index(pclass))
921 && extra_has_flag(pextra, EF_NATIVE_TILE)) {
922 can_exist = TRUE;
923 break;
924 }
925 } extra_type_iterate_end;
926 }
927
928 if (!can_exist) {
929 ruleset_error(LOG_ERROR,
930 "Unit class %s cannot exist anywhere.",
931 uclass_rule_name(pclass));
932 ok = FALSE;
933 }
934 }
935 } unit_class_iterate_end;
936
937 achievements_iterate(pach) {
938 if (!pach->unique && pach->cons_msg == NULL) {
939 ruleset_error(LOG_ERROR,
940 "Achievement %s has no message for consecutive gainers though "
941 "it's possible to be gained by multiple players",
942 achievement_rule_name(pach));
943 ok = FALSE;
944 }
945 } achievements_iterate_end;
946
947 if (game.server.ruledit.embedded_nations != NULL) {
948 int nati;
949
950 for (nati = 0; nati < game.server.ruledit.embedded_nations_count; nati++) {
951 struct nation_type *pnat
952 = nation_by_rule_name(game.server.ruledit.embedded_nations[nati]);
953
954 if (pnat == NULL) {
955 ruleset_error(LOG_ERROR,
956 "There's nation %s listed in embedded nations, but there's "
957 "no such nation.",
958 game.server.ruledit.embedded_nations[nati]);
959 ok = FALSE;
960 }
961 }
962 }
963
964 if (ok) {
965 ok = rs_common_units();
966 }
967 if (ok) {
968 ok = rs_barbarian_units();
969 }
970 if (ok) {
971 ok = rs_buildings();
972 }
973
974 return ok;
975 }
976
977 /**************************************************************************
978 Set and lock settings that must have certain value.
979 **************************************************************************/
autolock_settings(void)980 bool autolock_settings(void)
981 {
982 bool ok = TRUE;
983
984 if (num_role_units(L_BARBARIAN) == 0) {
985 struct setting *pset = setting_by_name("barbarians");
986
987 log_normal(_("Disabling 'barbarians' setting for lack of suitable "
988 "unit types."));
989 setting_lock_set(pset, FALSE);
990 if (!setting_enum_set(pset, "DISABLED", NULL, NULL, 0)) {
991 ok = FALSE;
992 }
993 setting_lock_set(pset, TRUE);
994 }
995
996 return ok;
997 }
998