Freeciv-3.3: /fast/freeciv/nightly/main/server/ruleset/ruleload.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
ruleload.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#include <stdarg.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23/* utility */
24#include "bitvector.h"
25#include "deprecations.h"
26#include "fcintl.h"
27#include "log.h"
28#include "mem.h"
29#include "registry.h"
30#include "shared.h"
31#include "string_vector.h"
32#include "support.h"
33
34/* common */
35#include "achievements.h"
36#include "actions.h"
37#include "ai.h"
38#include "base.h"
39#include "capability.h"
40#include "city.h"
41#include "counters.h"
42#include "effects.h"
43#include "extras.h"
44#include "fc_types.h"
45#include "featured_text.h"
46#include "game.h"
47#include "government.h"
48#include "map.h"
49#include "movement.h"
50#include "multipliers.h"
51#include "name_translation.h"
52#include "nation.h"
53#include "packets.h"
54#include "player.h"
55#include "requirements.h"
56#include "rgbcolor.h"
57#include "road.h"
58#include "sex.h"
59#include "specialist.h"
60#include "style.h"
61#include "tech.h"
62#include "traderoutes.h"
63#include "unit.h"
64#include "unittype.h"
65
66/* server */
67#include "citytools.h"
68#include "notify.h"
69#include "plrhand.h"
70#include "rscompat.h"
71#include "rssanity.h"
72#include "settings.h"
73#include "srv_main.h"
74
75/* server/advisors */
76#include "advruleset.h"
77
78/* server/scripting */
79#include "script_server.h"
80
81#include "ruleload.h"
82
83/* RULESET_SUFFIX already used, no leading dot here */
84#define RULES_SUFFIX "ruleset"
85#define SCRIPT_SUFFIX "lua"
86
87#define ADVANCE_SECTION_PREFIX "advance_"
88#define TECH_CLASS_SECTION_PREFIX "techclass_"
89#define BUILDING_SECTION_PREFIX "building_"
90#define CITYSTYLE_SECTION_PREFIX "citystyle_"
91#define MUSICSTYLE_SECTION_PREFIX "musicstyle_"
92#define UEFF_SECTION_PREFIX "ueff_"
93#define EFFECT_SECTION_PREFIX "effect_"
94#define GOVERNMENT_SECTION_PREFIX "government_"
95#define NATION_SET_SECTION_PREFIX "nset" /* without underscore? */
96#define NATION_GROUP_SECTION_PREFIX "ngroup" /* without underscore? */
97#define NATION_SECTION_PREFIX "nation" /* without underscore? */
98#define STYLE_SECTION_PREFIX "style_"
99#define CLAUSE_SECTION_PREFIX "clause_"
100#define EXTRA_SECTION_PREFIX "extra_"
101#define BASE_SECTION_PREFIX "base_"
102#define ROAD_SECTION_PREFIX "road_"
103#define RESOURCE_SECTION_PREFIX "resource_"
104#define GOODS_SECTION_PREFIX "goods_"
105#define SPECIALIST_SECTION_PREFIX "specialist_"
106#define TERRAIN_SECTION_PREFIX "terrain_"
107#define UNIT_CLASS_SECTION_PREFIX "unitclass_"
108#define UNIT_SECTION_PREFIX "unit_"
109#define DISASTER_SECTION_PREFIX "disaster_"
110#define ACHIEVEMENT_SECTION_PREFIX "achievement_"
111#define ACTION_ENABLER_SECTION_PREFIX "actionenabler_"
112#define MULTIPLIER_SECTION_PREFIX "multiplier_"
113#define COUNTER_SECTION_PREFIX "counter_"
114
115#define check_name(name) (check_strlen(name, MAX_LEN_NAME, NULL))
116#define check_cityname(name) (check_strlen(name, MAX_LEN_CITYNAME, NULL))
117
118/* avoid re-reading files */
119 static const char name_too_long[] = "Name \"%s\" too long; truncating.";
120#define MAX_SECTION_LABEL 64
121#define section_strlcpy(dst, src) \
122 (void) loud_strlcpy(dst, src, MAX_SECTION_LABEL, name_too_long)
123 static char *resource_sections = NULL;
124 static char *terrain_sections = NULL;
125 static char *extra_sections = NULL;
126 static char *base_sections = NULL;
127 static char *road_sections = NULL;
128
129 static struct requirement_vector reqs_list;
130
131static bool load_rulesetdir(const char *rsdir, bool compat_mode,
132 rs_conversion_logger logger,
133 bool act, bool buffer_script, bool load_luadata);
134static struct section_file *openload_ruleset_file(const char *whichset,
135 const char *rsdir);
136
137static bool load_game_names(struct section_file *file,
138 struct rscompat_info *compat);
139static bool load_action_names(struct section_file *file,
140 struct rscompat_info *compat);
141static bool load_tech_names(struct section_file *file,
142 struct rscompat_info *compat);
143static bool load_unit_names(struct section_file *file,
144 struct rscompat_info *compat);
145static bool load_building_names(struct section_file *file,
146 struct rscompat_info *compat);
147static bool load_government_names(struct section_file *file,
148 struct rscompat_info *compat);
149static bool load_terrain_names(struct section_file *file,
150 struct rscompat_info *compat);
151static bool load_style_names(struct section_file *file,
152 struct rscompat_info *compat);
153static bool load_nation_names(struct section_file *file,
154 struct rscompat_info *compat);
155static bool load_city_name_list(struct section_file *file,
156 struct nation_type *pnation,
157 const char *secfile_str1,
158 const char *secfile_str2,
159 const char **allowed_terrains,
160 size_t atcount);
161
162static bool load_ruleset_techs(struct section_file *file,
163 struct rscompat_info *compat);
164static bool load_ruleset_units(struct section_file *file,
165 struct rscompat_info *compat);
166static bool load_ruleset_buildings(struct section_file *file,
167 struct rscompat_info *compat);
168static bool load_ruleset_governments(struct section_file *file,
169 struct rscompat_info *compat);
170static bool load_ruleset_terrain(struct section_file *file,
171 struct rscompat_info *compat);
172static bool load_ruleset_styles(struct section_file *file,
173 struct rscompat_info *compat);
174static bool load_ruleset_cities(struct section_file *file,
175 struct rscompat_info *compat);
176static bool load_ruleset_effects(struct section_file *file,
177 struct rscompat_info *compat);
178static bool load_ruleset_game(struct section_file *file, bool act,
179 struct rscompat_info *compat);
180static bool load_ruleset_actions(struct section_file *file,
181 struct section_file *gamefile,
182 struct rscompat_info *compat);
183
184static void send_ruleset_tech_classes(struct conn_list *dest);
185static void send_ruleset_techs(struct conn_list *dest);
186static void send_ruleset_unit_classes(struct conn_list *dest);
187static void send_ruleset_units(struct conn_list *dest);
188static void send_ruleset_buildings(struct conn_list *dest);
189static void send_ruleset_terrain(struct conn_list *dest);
190static void send_ruleset_resources(struct conn_list *dest);
191static void send_ruleset_extras(struct conn_list *dest);
192static void send_ruleset_bases(struct conn_list *dest);
193static void send_ruleset_roads(struct conn_list *dest);
194static void send_ruleset_goods(struct conn_list *dest);
195static void send_ruleset_governments(struct conn_list *dest);
196static void send_ruleset_styles(struct conn_list *dest);
197static void send_ruleset_clauses(struct conn_list *dest);
198static void send_ruleset_musics(struct conn_list *dest);
199static void send_ruleset_cities(struct conn_list *dest);
200static void send_ruleset_game(struct conn_list *dest);
201static void send_ruleset_team_names(struct conn_list *dest);
202
203static bool load_ruleset_veteran(struct section_file *file,
204 const char *path,
205 struct veteran_system **vsystem, char *err,
206 size_t err_len);
207
208 char *script_buffer = NULL;
209 char *parser_buffer = NULL;
210
211/**********************************************************************/
215 void ruleset_error_real(rs_conversion_logger logger,
216 const char *file, const char *function,
217 int line, enum log_level level,
218 const char *format, ...)
219{
220 va_list args;
221 char buf[MAX_LEN_LOG_LINE];
222
223 if (logger == NULL && !log_do_output_for_level(level)) {
224 return;
225 }
226
227 va_start(args, format);
228 if (logger != NULL) {
229 fc_vsnprintf(buf, sizeof(buf), format, args);
230 logger(buf);
231 } else {
232 vdo_log(file, function, line, FALSE, level, buf, sizeof(buf), format, args);
233 }
234 va_end(args);
235
236 if (LOG_FATAL >= level) {
237 exit(EXIT_FAILURE);
238 }
239}
240
241/**********************************************************************/
244 static int ruleset_purge_unused_enablers(void)
245{
246 int purged = 0;
247
248 action_iterate(act_id) {
249 struct action *paction = action_by_number(act_id);
250
251 if (action_enabler_list_size(action_enablers_for_action(paction->id))
252 == 0) {
253 /* Not relevant. */
254 continue;
255 }
256
257 /* Impossible hard requirement. */
258 if (!action_is_in_use(paction)) {
259 /* Make sure that all action enablers are disabled. */
260 action_enabler_list_iterate(action_enablers_for_action(paction->id),
261 ae) {
262 ae->ruledit_disabled = TRUE;
263 purged++;
264 } action_enabler_list_iterate_end;
265
266 log_normal("Purged all action enablers for %s",
267 action_rule_name(paction));
268 }
269
270 /* Impossible requirement vector requirement. */
271 action_enabler_list_iterate(action_enablers_for_action(paction->id),
272 ae) {
273 if (!ae->ruledit_disabled
274 && (!action_enabler_possible_actor(ae)
275 || req_vec_is_impossible_to_fulfill(&ae->target_reqs))) {
276 ae->ruledit_disabled = TRUE;
277 purged++;
278 log_normal("Purged unused action enabler for %s",
279 action_rule_name(paction));
280 }
281 } action_enabler_list_iterate_end;
282 } action_iterate_end;
283
284 return purged;
285}
286
287/**********************************************************************/
290 static int ruleset_purge_unused_effects(void)
291{
292 int purged = 0;
293 enum effect_type type;
294
295 for (type = effect_type_begin(); type != effect_type_end();
296 type = effect_type_next(type)) {
297 effect_list_iterate(get_effects(type), eft) {
298 if (req_vec_is_impossible_to_fulfill(&eft->reqs)) {
299 eft->rulesave.do_not_save = TRUE;
300 purged++;
301 log_normal("Purged unused effect for %s",
302 effect_type_name(eft->type));
303 }
304 } effect_list_iterate_end;
305 }
306
307 return purged;
308}
309
310/**********************************************************************/
313 int ruleset_purge_unused_entities(void)
314{
315 int purged = 0;
316
317 purged += ruleset_purge_unused_enablers();
318 purged += ruleset_purge_unused_effects();
319
320 return purged;
321}
322
323/**********************************************************************/
327 static bool purge_unused_req_vec(const struct requirement_vector *reqs,
328 const char *msg)
329{
330 struct req_vec_problem *problem;
331 bool result;
332
333 problem = req_vec_get_first_missing_univ(reqs, req_vec_vector_number,
334 reqs);
335
336 if (problem == NULL) {
337 /* No problem. */
338 return FALSE;
339 }
340
341 if (problem->num_suggested_solutions == 0) {
342 /* No solution. */
343 req_vec_problem_free(problem);
344 return FALSE;
345 }
346
347 if (problem->num_suggested_solutions == 1
348 && problem->suggested_solutions[0].operation == RVCO_REMOVE) {
349 /* Remove !present req that never is there. */
350 log_normal("%s", msg);
351 result = req_vec_change_apply(&problem->suggested_solutions[0],
352 req_vec_by_number, reqs);
353 req_vec_problem_free(problem);
354 return result;
355 }
356
357 /* Not handled. Don't know what this is. */
358 fc_assert(problem->num_suggested_solutions == 1);
359 req_vec_problem_free(problem);
360 return FALSE;
361}
362
363/**********************************************************************/
367 static bool purge_duplicate_req_vec(const struct requirement_vector *reqs,
368 const char *msg)
369{
370 struct req_vec_problem *problem;
371 bool result;
372
373 problem = req_vec_get_first_redundant_req(reqs, req_vec_vector_number,
374 reqs);
375
376 if (problem == NULL) {
377 /* No problem. */
378 return FALSE;
379 }
380
381 if (problem->num_suggested_solutions == 0) {
382 /* No solution. */
383 req_vec_problem_free(problem);
384 return FALSE;
385 }
386
387 if (problem->num_suggested_solutions == 2
388 && problem->suggested_solutions[0].operation == RVCO_REMOVE
389 && problem->suggested_solutions[1].operation == RVCO_REMOVE
390 && are_requirements_equal(&problem->suggested_solutions[0].req,
391 &problem->suggested_solutions[1].req)) {
392 /* Simple duplication is handled. */
393 log_normal("%s", msg);
394 result = req_vec_change_apply(&problem->suggested_solutions[1],
395 req_vec_by_number, reqs);
396 req_vec_problem_free(problem);
397 return result;
398 }
399
400 /* Requirements of different kinds making each other redundant isn't
401 * supported yet. It could be done by always removing the most general
402 * requirement. So unit type is kept when redundant with unit flag, unit
403 * class and unit class flag etc. */
404 req_vec_problem_free(problem);
405 return FALSE;
406}
407
408/**********************************************************************/
412 static bool purge_redundant_req_vec(const struct requirement_vector *reqs,
413 const char *msg)
414{
415 return (purge_unused_req_vec(reqs, msg)
416 || purge_duplicate_req_vec(reqs, msg));
417}
418
419/**********************************************************************/
423 static int ruleset_purge_redundant_reqs_enablers(void)
424{
425 int purged = 0;
426
427 action_iterate(act_id) {
428 struct action *paction = action_by_number(act_id);
429 char actor_reqs[MAX_LEN_NAME * 2];
430 char target_reqs[MAX_LEN_NAME * 2];
431
432 /* Error log text */
433 fc_snprintf(actor_reqs, sizeof(actor_reqs),
434 "Purged redundant requirement in"
435 " %s in action enabler for %s",
436 "actor_reqs", action_rule_name(paction));
437 fc_snprintf(target_reqs, sizeof(target_reqs),
438 "Purged redundant requirement in"
439 " %s in action enabler for %s",
440 "target_reqs", action_rule_name(paction));
441
442 /* Do the purging. */
443 action_enabler_list_iterate(action_enablers_for_action(paction->id),
444 ae) {
445 while (!ae->ruledit_disabled
446 && (purge_redundant_req_vec(&ae->actor_reqs, actor_reqs)
447 || purge_redundant_req_vec(&ae->target_reqs,
448 target_reqs))) {
449 purged++;
450 }
451 } action_enabler_list_iterate_end;
452 } action_iterate_end;
453
454 return purged;
455}
456
457/**********************************************************************/
461 static int ruleset_purge_redundant_reqs_effects(void)
462{
463 int purged = 0;
464 enum effect_type type;
465
466 for (type = effect_type_begin(); type != effect_type_end();
467 type = effect_type_next(type)) {
468 char msg[MAX_LEN_NAME * 2];
469
470 /* Error log text */
471 fc_snprintf(msg, sizeof(msg),
472 "Purged redundant requirement in effect of type %s",
473 effect_type_name(type));
474
475 /* Do the purging. */
476 effect_list_iterate(get_effects(type), eft) {
477 while (purge_redundant_req_vec(&eft->reqs, msg)) {
478 purged++;
479 }
480 } effect_list_iterate_end;
481 }
482
483 return purged;
484}
485
486/**********************************************************************/
490 int ruleset_purge_redundant_reqs(void)
491{
492 int purged = 0;
493
494 purged += ruleset_purge_redundant_reqs_enablers();
495 purged += ruleset_purge_redundant_reqs_effects();
496
497 if (purged > 0) {
498 /* An unused requirement may be an obligatory hard requirement. */
499 rscompat_enablers_add_obligatory_hard_reqs();
500 }
501
502 return purged;
503}
504
505/**********************************************************************/
509 static const char *valid_ruleset_filename(const char *subdir,
510 const char *name,
511 const char *extension,
512 bool optional)
513{
514 char filename[512];
515 const char *dfilename;
516
517 fc_assert_ret_val(subdir && name && extension, NULL);
518
519 fc_snprintf(filename, sizeof(filename), "%s" DIR_SEPARATOR "%s.%s",
520 subdir, name, extension);
521 log_verbose("Trying \"%s\".", filename);
522 dfilename = fileinfoname(get_data_dirs(), filename);
523 if (dfilename) {
524 return dfilename;
525 }
526
527 fc_snprintf(filename, sizeof(filename), "default" DIR_SEPARATOR "%s.%s", name, extension);
528 log_verbose("Trying \"%s\": default ruleset directory.", filename);
529 dfilename = fileinfoname(get_data_dirs(), filename);
530 if (dfilename) {
531 return dfilename;
532 }
533
534 fc_snprintf(filename, sizeof(filename), "%s_%s.%s",
535 subdir, name, extension);
536 log_verbose("Trying \"%s\": alternative ruleset filename syntax.",
537 filename);
538 dfilename = fileinfoname(get_data_dirs(), filename);
539 if (dfilename) {
540 return dfilename;
541 } else if (!optional) {
542 ruleset_error(NULL, LOG_ERROR,
543 /* TRANS: message about an installation error. */
544 _("Could not find a readable \"%s.%s\" ruleset file."),
545 name, extension);
546 }
547
548 return NULL;
549}
550
551/**********************************************************************/
554 char *get_script_buffer(void)
555{
556 return script_buffer;
557}
558
559/**********************************************************************/
562 char *get_parser_buffer(void)
563{
564 return parser_buffer;
565}
566
567/**********************************************************************/
571 static struct section_file *openload_ruleset_file(const char *whichset,
572 const char *rsdir)
573{
574 char sfilename[512];
575 const char *dfilename = valid_ruleset_filename(rsdir, whichset,
576 RULES_SUFFIX, FALSE);
577 struct section_file *secfile;
578
579 if (dfilename == NULL) {
580 return NULL;
581 }
582
583 /* Need to save a copy of the filename for following message, since
584 section_file_load() may call datafilename() for includes. */
585 sz_strlcpy(sfilename, dfilename);
586 secfile = secfile_load(sfilename, FALSE);
587
588 if (secfile == NULL) {
589 ruleset_error(NULL, LOG_ERROR, "Could not load ruleset '%s':\n%s",
590 sfilename, secfile_error());
591 }
592
593 return secfile;
594}
595
596/**********************************************************************/
599 static enum fc_tristate openload_script_file(const char *whichset, const char *rsdir,
600 char **buffer, bool optional)
601{
602 const char *dfilename = valid_ruleset_filename(rsdir, whichset,
603 SCRIPT_SUFFIX, optional);
604
605 if (dfilename == NULL) {
606 return optional ? TRI_MAYBE : TRI_NO;
607 }
608
609 if (buffer == NULL) {
610 if (!script_server_do_file(NULL, dfilename)) {
611 ruleset_error(NULL, LOG_ERROR, "\"%s\": could not load ruleset script.",
612 dfilename);
613
614 return TRI_NO;
615 }
616 } else {
617 script_server_load_file(dfilename, buffer);
618 }
619
620 return TRI_YES;
621}
622
623/**********************************************************************/
626 static struct section_file *openload_luadata_file(const char *rsdir)
627{
628 struct section_file *secfile;
629 char sfilename[512];
630 const char *dfilename = valid_ruleset_filename(rsdir, "luadata",
631 "txt", TRUE);
632
633 if (dfilename == NULL) {
634 return NULL;
635 }
636
637 /* Need to save a copy of the filename for following message, since
638 section_file_load() may call datafilename() for includes. */
639 sz_strlcpy(sfilename, dfilename);
640 secfile = secfile_load(sfilename, FALSE);
641
642 if (secfile == NULL) {
643 ruleset_error(NULL, LOG_ERROR, "Could not load luadata '%s':\n%s",
644 sfilename, secfile_error());
645 }
646
647 return secfile;
648}
649
650/**********************************************************************/
654 struct requirement_vector *lookup_req_list(struct section_file *file,
655 struct rscompat_info *compat,
656 const char *sec,
657 const char *sub,
658 const char *rfor)
659{
660 const char *type, *name;
661 int j;
662 const char *filename;
663
664 filename = secfile_name(file);
665
666 requirement_vector_reserve(&reqs_list, 0);
667
668 for (j = 0; (type = secfile_lookup_str_default(file, NULL, "%s.%s%d.type",
669 sec, sub, j)); j++) {
670 char buf[MAX_LEN_NAME];
671 const char *range;
672 bool survives, present, quiet;
673 struct entry *pentry;
674 struct requirement req;
675
676 if (!(pentry = secfile_entry_lookup(file, "%s.%s%d.name",
677 sec, sub, j))) {
678 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
679
680 return NULL;
681 }
682 name = NULL;
683 switch (entry_type_get(pentry)) {
684 case ENTRY_BOOL:
685 {
686 bool val;
687
688 if (entry_bool_get(pentry, &val)) {
689 fc_snprintf(buf, sizeof(buf), "%d", val);
690 name = buf;
691 }
692 }
693 break;
694 case ENTRY_INT:
695 {
696 int val;
697
698 if (entry_int_get(pentry, &val)) {
699 fc_snprintf(buf, sizeof(buf), "%d", val);
700 name = buf;
701 }
702 }
703 break;
704 case ENTRY_STR:
705 (void) entry_str_get(pentry, &name);
706 break;
707 case ENTRY_FLOAT:
708 fc_assert(entry_type_get(pentry) != ENTRY_FLOAT);
709 ruleset_error(NULL, LOG_ERROR,
710 "\"%s\": trying to have an floating point entry as a requirement name in '%s.%s%d'.",
711 filename, sec, sub, j);
712 break;
713 case ENTRY_FILEREFERENCE:
714 fc_assert(entry_type_get(pentry) != ENTRY_FILEREFERENCE);
715 break;
716 case ENTRY_LONG_COMMENT:
717 fc_assert(entry_type_get(pentry) != ENTRY_LONG_COMMENT);
718 break;
719 case ENTRY_ILLEGAL:
720 fc_assert(entry_type_get(pentry) != ENTRY_ILLEGAL);
721 break;
722 }
723 if (NULL == name) {
724 ruleset_error(NULL, LOG_ERROR,
725 "\"%s\": error in handling requirement name for '%s.%s%d'.",
726 filename, sec, sub, j);
727 return NULL;
728 }
729
730 if (!(range = secfile_lookup_str(file, "%s.%s%d.range", sec, sub, j))) {
731 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
732
733 return NULL;
734 }
735
736 survives = FALSE;
737 if ((pentry = secfile_entry_lookup(file, "%s.%s%d.survives",
738 sec, sub, j))
739 && !entry_bool_get(pentry, &survives)) {
740 ruleset_error(NULL, LOG_ERROR,
741 "\"%s\": invalid boolean value for survives for "
742 "'%s.%s%d'.", filename, sec, sub, j);
743 }
744
745 present = TRUE;
746 if ((pentry = secfile_entry_lookup(file, "%s.%s%d.present",
747 sec, sub, j))
748 && !entry_bool_get(pentry, &present)) {
749 ruleset_error(NULL, LOG_ERROR,
750 "\"%s\": invalid boolean value for present for "
751 "'%s.%s%d'.", filename, sec, sub, j);
752 }
753 quiet = FALSE;
754 if ((pentry = secfile_entry_lookup(file, "%s.%s%d.quiet",
755 sec, sub, j))
756 && !entry_bool_get(pentry, &quiet)) {
757 ruleset_error(NULL, LOG_ERROR,
758 "\"%s\": invalid boolean value for quiet for "
759 "'%s.%s%d'.", filename, sec, sub, j);
760 }
761
762 req = req_from_str(type, range, survives, present, quiet, name);
763 if (req.source.kind == universals_n_invalid()) {
764 ruleset_error(NULL, LOG_ERROR,
765 "\"%s\" [%s] has invalid or unknown req: "
766 "\"%s\" \"%s\".",
767 filename, sec, type, name);
768
769 return NULL;
770 }
771
772 requirement_vector_append(&reqs_list, req);
773 }
774
775 if (j > MAX_NUM_REQS) {
776 ruleset_error(NULL, LOG_ERROR,
777 "Too many (%d) requirements for %s. Max is %d",
778 j, rfor, MAX_NUM_REQS);
779
780 return NULL;
781 }
782
783 return &reqs_list;
784}
785
786/**********************************************************************/
789 static bool lookup_cbonus_list(struct combat_bonus_list *list,
790 struct section_file *file,
791 const char *sec,
792 const char *sub)
793{
794 const char *flag;
795 int j;
796 const char *filename;
797 bool success = TRUE;
798
799 filename = secfile_name(file);
800
801 for (j = 0; (flag = secfile_lookup_str_default(file, NULL, "%s.%s%d.flag",
802 sec, sub, j)); j++) {
803 struct combat_bonus *bonus = fc_malloc(sizeof(*bonus));
804 const char *type;
805
806 bonus->flag = unit_type_flag_id_by_name(flag, fc_strcasecmp);
807 if (!unit_type_flag_id_is_valid(bonus->flag)) {
808 log_error("\"%s\": unknown flag name \"%s\" in '%s.%s'.",
809 filename, flag, sec, sub);
810 FC_FREE(bonus);
811 success = FALSE;
812 continue;
813 }
814 type = secfile_lookup_str(file, "%s.%s%d.type", sec, sub, j);
815 bonus->type = combat_bonus_type_by_name(type, fc_strcasecmp);
816 if (!combat_bonus_type_is_valid(bonus->type)) {
817 log_error("\"%s\": unknown bonus type \"%s\" in '%s.%s'.",
818 filename, type, sec, sub);
819 FC_FREE(bonus);
820 success = FALSE;
821 continue;
822 }
823 if (!secfile_lookup_int(file, &bonus->value, "%s.%s%d.value",
824 sec, sub, j)) {
825 log_error("\"%s\": failed to get value from '%s.%s%d'.",
826 filename, sec, sub, j);
827 FC_FREE(bonus);
828 success = FALSE;
829 continue;
830 }
831 bonus->quiet = secfile_lookup_bool_default(file, FALSE,
832 "%s.%s%d.quiet",
833 sec, sub, j);
834 combat_bonus_list_append(list, bonus);
835 }
836
837 return success;
838}
839
840/**********************************************************************/
848 static bool lookup_tech(struct section_file *file,
849 struct advance **result,
850 const char *prefix, const char *entry,
851 const char *filename,
852 const char *description)
853{
854 const char *sval;
855
856 sval = secfile_lookup_str_default(file, NULL, "%s.%s", prefix, entry);
857 if (!sval || !strcmp(sval, "Never")) {
858 *result = A_NEVER;
859 } else {
860 *result = advance_by_rule_name(sval);
861
862 if (A_NEVER == *result) {
863 ruleset_error(NULL, LOG_ERROR,
864 "\"%s\" %s %s: couldn't match \"%s\".",
865 filename, (description ? description : prefix), entry, sval);
866 return FALSE;
867 }
868 }
869
870 return TRUE;
871}
872
873/**********************************************************************/
880 static bool lookup_unit_list(struct section_file *file, const char *prefix,
881 const char *entry,
882 struct unit_type **output,
883 const char *filename)
884{
885 const char **slist;
886 size_t nval;
887 int i;
888 bool ok = TRUE;
889
890 /* pre-fill with NULL: */
891 for (i = 0; i < MAX_NUM_UNIT_LIST; i++) {
892 output[i] = NULL;
893 }
894 slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry);
895 if (nval == 0) {
896 /* 'No vector' is considered same as empty vector */
897 if (slist != NULL) {
898 free(slist);
899 }
900 return TRUE;
901 }
902 if (nval > MAX_NUM_UNIT_LIST) {
903 ruleset_error(NULL, LOG_ERROR,
904 "\"%s\": string vector %s.%s too long (%d, max %d)",
905 filename, prefix, entry, (int) nval, MAX_NUM_UNIT_LIST);
906 ok = FALSE;
907 } else if (nval == 1 && strcmp(slist[0], "") == 0) {
908 free(slist);
909 return TRUE;
910 }
911 if (ok) {
912 for (i = 0; i < nval; i++) {
913 const char *sval = slist[i];
914 struct unit_type *punittype = unit_type_by_rule_name(sval);
915
916 if (!punittype) {
917 ruleset_error(NULL, LOG_ERROR,
918 "\"%s\" %s.%s (%d): couldn't match \"%s\".",
919 filename, prefix, entry, i, sval);
920 ok = FALSE;
921 break;
922 }
923 output[i] = punittype;
924 log_debug("\"%s\" %s.%s (%d): %s (%d)", filename, prefix, entry, i, sval,
925 utype_number(punittype));
926 }
927 }
928 free(slist);
929
930 return ok;
931}
932
933/**********************************************************************/
940 static bool lookup_tech_list(struct section_file *file, const char *prefix,
941 const char *entry, int *output,
942 const char *filename)
943{
944 const char **slist;
945 size_t nval;
946 int i;
947 bool ok = TRUE;
948
949 /* pre-fill with A_LAST: */
950 for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
951 output[i] = A_LAST;
952 }
953 slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry);
954 if (slist == NULL || nval == 0) {
955 return TRUE;
956 } else if (nval > MAX_NUM_TECH_LIST) {
957 ruleset_error(NULL, LOG_ERROR,
958 "\"%s\": string vector %s.%s too long (%d, max %d)",
959 filename, prefix, entry, (int) nval, MAX_NUM_TECH_LIST);
960 ok = FALSE;
961 }
962
963 if (ok) {
964 if (nval == 1 && strcmp(slist[0], "") == 0) {
965 FC_FREE(slist);
966 return TRUE;
967 }
968 for (i = 0; i < nval && ok; i++) {
969 const char *sval = slist[i];
970 struct advance *padvance = advance_by_rule_name(sval);
971
972 if (NULL == padvance) {
973 ruleset_error(NULL, LOG_ERROR,
974 "\"%s\" %s.%s (%d): couldn't match \"%s\".",
975 filename, prefix, entry, i, sval);
976 ok = FALSE;
977 }
978 if (!valid_advance(padvance)) {
979 ruleset_error(NULL, LOG_ERROR,
980 "\"%s\" %s.%s (%d): \"%s\" is removed.",
981 filename, prefix, entry, i, sval);
982 ok = FALSE;
983 }
984
985 if (ok) {
986 output[i] = advance_number(padvance);
987 log_debug("\"%s\" %s.%s (%d): %s (%d)", filename, prefix, entry, i, sval,
988 advance_number(padvance));
989 }
990 }
991 }
992 FC_FREE(slist);
993
994 return ok;
995}
996
997/**********************************************************************/
1004 static bool lookup_building_list(struct section_file *file,
1005 const char *prefix, const char *entry,
1006 int *output, const char *filename)
1007{
1008 const char **slist;
1009 size_t nval;
1010 int i;
1011 bool ok = TRUE;
1012
1013 /* pre-fill with B_LAST: */
1014 for (i = 0; i < MAX_NUM_BUILDING_LIST; i++) {
1015 output[i] = B_LAST;
1016 }
1017 slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry);
1018 if (nval > MAX_NUM_BUILDING_LIST) {
1019 ruleset_error(NULL, LOG_ERROR,
1020 "\"%s\": string vector %s.%s too long (%d, max %d)",
1021 filename, prefix, entry, (int) nval, MAX_NUM_BUILDING_LIST);
1022 ok = FALSE;
1023 } else if (nval == 0 || (nval == 1 && strcmp(slist[0], "") == 0)) {
1024 if (slist != NULL) {
1025 FC_FREE(slist);
1026 }
1027 return TRUE;
1028 }
1029 if (ok) {
1030 for (i = 0; i < nval; i++) {
1031 const char *sval = slist[i];
1032 struct impr_type *pimprove = improvement_by_rule_name(sval);
1033
1034 if (NULL == pimprove) {
1035 ruleset_error(NULL, LOG_ERROR,
1036 "\"%s\" %s.%s (%d): couldn't match \"%s\".",
1037 filename, prefix, entry, i, sval);
1038 ok = FALSE;
1039 break;
1040 }
1041 output[i] = improvement_number(pimprove);
1042 log_debug("%s.%s,%d %s %d", prefix, entry, i, sval, output[i]);
1043 }
1044 }
1045 free(slist);
1046
1047 return ok;
1048}
1049
1050/**********************************************************************/
1056 static bool lookup_unit_type(struct section_file *file,
1057 const char *prefix,
1058 const char *entry,
1059 const struct unit_type **result,
1060 const char *filename,
1061 const char *description)
1062{
1063 const char *sval;
1064
1065 sval = secfile_lookup_str_default(file, "None", "%s.%s", prefix, entry);
1066
1067 if (strcmp(sval, "None") == 0) {
1068 *result = NULL;
1069 } else {
1070 *result = unit_type_by_rule_name(sval);
1071 if (*result == NULL) {
1072 ruleset_error(NULL, LOG_ERROR,
1073 "\"%s\" %s %s: couldn't match \"%s\".",
1074 filename, (description ? description : prefix), entry, sval);
1075
1076 return FALSE;
1077 }
1078 }
1079
1080 return TRUE;
1081}
1082
1083/**********************************************************************/
1087 static struct government *lookup_government(struct section_file *file,
1088 const char *entry,
1089 const char *filename,
1090 struct government *fallback)
1091{
1092 const char *sval;
1093 struct government *gov;
1094
1095 sval = secfile_lookup_str_default(file, NULL, "%s", entry);
1096 if (!sval) {
1097 gov = fallback;
1098 } else {
1099 gov = government_by_rule_name(sval);
1100 }
1101 if (!gov) {
1102 ruleset_error(NULL, LOG_ERROR,
1103 "\"%s\" %s: couldn't match \"%s\".",
1104 filename, entry, sval);
1105 }
1106 return gov;
1107}
1108
1109/**********************************************************************/
1112 static char *lookup_string(struct section_file *file, const char *prefix,
1113 const char *suffix)
1114{
1115 const char *sval = secfile_lookup_str(file, "%s.%s", prefix, suffix);
1116
1117 if (NULL != sval) {
1118 char copy[strlen(sval) + 1];
1119
1120 strcpy(copy, sval);
1121 remove_leading_trailing_spaces(copy);
1122 if (strlen(copy) > 0) {
1123 return fc_strdup(copy);
1124 }
1125 }
1126 return NULL;
1127}
1128
1129/**********************************************************************/
1132 static struct strvec *lookup_strvec(struct section_file *file,
1133 const char *prefix, const char *suffix)
1134{
1135 size_t dim;
1136 const char **vec = secfile_lookup_str_vec(file, &dim,
1137 "%s.%s", prefix, suffix);
1138
1139 if (NULL != vec) {
1140 struct strvec *dest = strvec_new();
1141
1142 strvec_store(dest, vec, dim);
1143 free(vec);
1144 return dest;
1145 }
1146 return NULL;
1147}
1148
1149/**********************************************************************/
1152 static struct extra_type *lookup_resource(const char *filename,
1153 const char *name,
1154 const char *jsection)
1155{
1156 struct extra_type *pres;
1157
1158 pres = extra_type_by_rule_name(name);
1159
1160 if (pres == NULL) {
1161 ruleset_error(NULL, LOG_ERROR,
1162 "\"%s\" [%s] has unknown \"%s\".",
1163 filename, jsection, name);
1164 }
1165
1166 return pres;
1167}
1168
1169/**********************************************************************/
1173 static bool lookup_terrain(struct section_file *file,
1174 const char *entry,
1175 const char *filename,
1176 struct terrain *pthis,
1177 struct terrain **result,
1178 bool null_acceptable)
1179{
1180 const int j = terrain_index(pthis);
1181 const char *jsection = &terrain_sections[j * MAX_SECTION_LABEL];
1182 const char *name = secfile_lookup_str(file, "%s.%s", jsection, entry);
1183 struct terrain *pterr;
1184
1185 if (NULL == name && !null_acceptable) {
1186 return FALSE;
1187 }
1188
1189 if (NULL == name
1190 || *name == '\0'
1191 || (0 == strcmp(name, "none"))
1192 || (0 == strcmp(name, "no"))) {
1193 *result = T_NONE;
1194
1195 return TRUE;
1196 }
1197 if (0 == strcmp(name, "yes")) {
1198 *result = pthis;
1199
1200 return TRUE;
1201 }
1202
1203 pterr = terrain_by_rule_name(name);
1204 *result = pterr;
1205
1206 if (pterr == NULL) {
1207 ruleset_error(NULL, LOG_ERROR,
1208 "\"%s\" [%s] has unknown \"%s\".",
1209 secfile_name(file), jsection, name);
1210 return FALSE;
1211 }
1212
1213 return TRUE;
1214}
1215
1216/**********************************************************************/
1223 static bool lookup_time(const struct section_file *secfile, int *turns,
1224 const char *sec_name, const char *property_name,
1225 const char *filename, const char *item_name,
1226 bool *ok)
1227{
1228 /* Assumes that PACKET_UNIT_INFO.activity_count in packets.def is UINT16 */
1229 const int max_turns = 65535 / ACTIVITY_FACTOR;
1230
1231 if (!secfile_lookup_int(secfile, turns, "%s.%s", sec_name, property_name)) {
1232 return FALSE;
1233 }
1234
1235 if (*turns > max_turns) {
1236 ruleset_error(NULL, LOG_ERROR,
1237 "\"%s\": \"%s\": \"%s\" value %d too large (max %d)",
1238 filename, item_name ? item_name : sec_name,
1239 property_name, *turns, max_turns);
1240 *ok = FALSE;
1241 }
1242
1243 return TRUE; /* we found _something */
1244}
1245
1246/**********************************************************************/
1249 static bool ruleset_load_names(struct name_translation *pname,
1250 const char *domain,
1251 struct section_file *file,
1252 const char *sec_name)
1253{
1254 const char *name = secfile_lookup_str(file, "%s.name", sec_name);
1255 const char *rule_name = secfile_lookup_str(file, "%s.rule_name", sec_name);
1256
1257 if (!name) {
1258 ruleset_error(NULL, LOG_ERROR,
1259 "\"%s\" [%s]: no \"name\" specified.",
1260 secfile_name(file), sec_name);
1261 return FALSE;
1262 }
1263
1264 names_set(pname, domain, name, rule_name);
1265
1266 return TRUE;
1267}
1268
1269/**********************************************************************/
1272 static void ruleset_load_traits(struct trait_limits *out,
1273 struct section_file *file,
1274 const char *secname, const char *field_prefix)
1275{
1276 enum trait tr;
1277
1278 /* FIXME: Use specenum trait names without duplicating them here.
1279 * Just needs to take care of case.
1280 * This list is also duplicated in rulesave.c:save_traits() */
1281 const char *trait_names[] = {
1282 "expansionist",
1283 "trader",
1284 "aggressive",
1285 "builder",
1286 NULL
1287 };
1288
1289 for (tr = trait_begin(); tr != trait_end() && trait_names[tr] != NULL; tr = trait_next(tr)) {
1290 out[tr].min = secfile_lookup_int_default(file, -1, "%s.%s%s_min",
1291 secname,
1292 field_prefix,
1293 trait_names[tr]);
1294 out[tr].max = secfile_lookup_int_default(file, -1, "%s.%s%s_max",
1295 secname,
1296 field_prefix,
1297 trait_names[tr]);
1298 out[tr].fixed = secfile_lookup_int_default(file, -1, "%s.%s%s_default",
1299 secname,
1300 field_prefix,
1301 trait_names[tr]);
1302 }
1303
1304 fc_assert(tr == trait_end()); /* number of trait_names correct */
1305}
1306
1307/**********************************************************************/
1311 static bool load_game_names(struct section_file *file,
1312 struct rscompat_info *compat)
1313{
1314 struct section_list *sec;
1315 int nval;
1316 const char *filename = secfile_name(file);
1317 bool ok = TRUE;
1318
1319 /* section: datafile */
1320 compat->version = rscompat_check_capabilities(file, filename, compat);
1321 if (compat->version <= 0) {
1322 return FALSE;
1323 }
1324
1325 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
1326 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
1327
1328 sec = secfile_sections_by_name_prefix(file, ACHIEVEMENT_SECTION_PREFIX);
1329 nval = (NULL != sec ? section_list_size(sec) : 0);
1330 if (nval > MAX_ACHIEVEMENT_TYPES) {
1331 int num = nval; /* No "size_t" to printf */
1332
1333 ruleset_error(NULL, LOG_ERROR,
1334 "\"%s\": Too many achievement types (%d, max %d)",
1335 filename, num, MAX_ACHIEVEMENT_TYPES);
1336 ok = FALSE;
1337 } else {
1338 game.control.num_achievement_types = nval;
1339 }
1340
1341 if (ok) {
1342 achievements_iterate(pach) {
1343 const char *sec_name = section_name(section_list_get(sec, achievement_index(pach)));
1344
1345 if (!ruleset_load_names(&pach->name, NULL, file, sec_name)) {
1346 ruleset_error(NULL, LOG_ERROR,
1347 "\"%s\": Cannot load achievement names",
1348 filename);
1349 ok = FALSE;
1350 break;
1351 }
1352 } achievements_iterate_end;
1353 }
1354
1355 section_list_destroy(sec);
1356
1357 if (ok) {
1358 sec = secfile_sections_by_name_prefix(file, GOODS_SECTION_PREFIX);
1359
1360 nval = (NULL != sec ? section_list_size(sec) : 0);
1361 if (nval > MAX_GOODS_TYPES) {
1362 int num = nval; /* No "size_t" to printf */
1363
1364 ruleset_error(NULL, LOG_ERROR,
1365 "\"%s\": Too many goods types (%d, max %d)",
1366 filename, num, MAX_GOODS_TYPES);
1367 section_list_destroy(sec);
1368 ok = FALSE;
1369 } else if (nval < 1) {
1370 ruleset_error(NULL, LOG_ERROR,
1371 "\"%s\": At least one goods type needed",
1372 filename);
1373 section_list_destroy(sec);
1374 ok = FALSE;
1375 } else {
1376 game.control.num_goods_types = nval;
1377 }
1378
1379 if (ok) {
1380 goods_type_iterate(pgood) {
1381 const char *sec_name
1382 = section_name(section_list_get(sec, goods_index(pgood)));
1383
1384 if (!ruleset_load_names(&pgood->name, NULL, file, sec_name)) {
1385 ruleset_error(NULL, LOG_ERROR,
1386 "\"%s\": Cannot load goods names",
1387 filename);
1388 ok = FALSE;
1389 break;
1390 }
1391 } goods_type_iterate_end;
1392 }
1393 section_list_destroy(sec);
1394 }
1395
1396 if (ok) {
1397
1398 sec = secfile_sections_by_name_prefix(file, COUNTER_SECTION_PREFIX);
1399
1400 nval = (NULL != sec ? section_list_size(sec) : 0);
1401 if (nval > MAX_COUNTERS) {
1402 size_t num = nval;
1403
1404 ruleset_error(NULL, LOG_ERROR,
1405 "\"%s\": Too many counters (" SIZE_T_PRINTF ", max %d)",
1406 filename, num, MAX_COUNTERS);
1407 ok = FALSE;
1408 }
1409
1410 if (ok) {
1411 int count_idx;
1412
1413 game.control.num_counters = nval;
1414
1415 for (count_idx = 0; count_idx < nval; count_idx++) {
1416
1417 struct counter *pcount = counter_by_id(count_idx);
1418 const char *sec_name
1419 = section_name(section_list_get(sec, count_idx));
1420
1421 if (!ruleset_load_names(&pcount->name, NULL, file, sec_name)) {
1422 ruleset_error(NULL, LOG_ERROR,
1423 "\"%s\": Cannot load counters names",
1424 filename);
1425 ok = FALSE;
1426 break;
1427 }
1428 }
1429 }
1430
1431 section_list_destroy(sec);
1432 }
1433
1434 return ok;
1435}
1436
1437/**********************************************************************/
1441 static bool load_action_names(struct section_file *file,
1442 struct rscompat_info *compat)
1443{
1444 const char *filename = secfile_name(file);
1445 bool ok = TRUE;
1446
1447 if (!rscompat_check_cap_and_version(file, filename, compat)) {
1448 return FALSE;
1449 }
1450
1451 (void) secfile_entry_by_path(file, "datafile.description"); /* Unused */
1452 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* Unused */
1453
1454 return ok;
1455}
1456
1457/**********************************************************************/
1461 static bool load_tech_names(struct section_file *file,
1462 struct rscompat_info *compat)
1463{
1464 struct section_list *sec = NULL;
1465 /* Number of techs in the ruleset (means without A_NONE). */
1466 int num_techs = 0;
1467 int i;
1468 const char *filename = secfile_name(file);
1469 bool ok = TRUE;
1470 const char *flag;
1471
1472 if (!rscompat_check_cap_and_version(file, filename, compat)) {
1473 return FALSE;
1474 }
1475
1476 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
1477 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
1478
1479 /* User tech flag names */
1480 for (i = 0; (flag = secfile_lookup_str_default(file, NULL, "control.flags%d.name", i)) ;
1481 i++) {
1482 const char *helptxt = secfile_lookup_str_default(file, NULL, "control.flags%d.helptxt",
1483 i);
1484 if (tech_flag_id_by_name(flag, fc_strcasecmp) != tech_flag_id_invalid()) {
1485 ruleset_error(NULL, LOG_ERROR,
1486 "\"%s\": Duplicate tech flag name '%s'",
1487 filename, flag);
1488 ok = FALSE;
1489 break;
1490 }
1491 if (i > MAX_NUM_USER_TECH_FLAGS) {
1492 ruleset_error(NULL, LOG_ERROR,
1493 "\"%s\": Too many user tech flags!",
1494 filename);
1495 ok = FALSE;
1496 break;
1497 }
1498
1499 set_user_tech_flag_name(TECH_USER_1 + i, flag, helptxt);
1500 }
1501
1502 if (ok) {
1503 size_t nval;
1504
1505 for (; i < MAX_NUM_USER_TECH_FLAGS; i++) {
1506 set_user_tech_flag_name(TECH_USER_1 + i, NULL, NULL);
1507 }
1508
1509 /* Tech classes */
1510 sec = secfile_sections_by_name_prefix(file, TECH_CLASS_SECTION_PREFIX);
1511
1512 nval = (NULL != sec ? section_list_size(sec) : 0);
1513 if (nval > MAX_NUM_TECH_CLASSES) {
1514 int num = nval; /* No "size_t" to printf */
1515
1516 ruleset_error(NULL, LOG_ERROR,
1517 "\"%s\": Too many tech classes (%d, max %d)",
1518 filename, num, MAX_NUM_TECH_CLASSES);
1519 section_list_destroy(sec);
1520 ok = FALSE;
1521 } else {
1522 game.control.num_tech_classes = nval;
1523 }
1524
1525 if (ok) {
1526 tech_class_iterate(ptclass) {
1527 const char *sec_name
1528 = section_name(section_list_get(sec, tech_class_index(ptclass)));
1529
1530 if (!ruleset_load_names(&ptclass->name, NULL, file, sec_name)) {
1531 ruleset_error(NULL, LOG_ERROR, "\"%s\": Cannot load tech class names",
1532 filename);
1533 ok = FALSE;
1534 break;
1535 }
1536 } tech_class_iterate_end;
1537 }
1538 }
1539
1540 if (ok) {
1541 /* The techs: */
1542 sec = secfile_sections_by_name_prefix(file, ADVANCE_SECTION_PREFIX);
1543 if (NULL == sec || 0 == (num_techs = section_list_size(sec))) {
1544 ruleset_error(NULL, LOG_ERROR,
1545 "\"%s\": No Advances?!?", filename);
1546 ok = FALSE;
1547 } else {
1548 log_verbose("%d advances (including possibly unused)", num_techs);
1549 if (num_techs + A_FIRST > A_LAST) {
1550 ruleset_error(NULL, LOG_ERROR,
1551 "\"%s\": Too many advances (%d, max %d)",
1552 filename, num_techs, A_LAST - A_FIRST);
1553 ok = FALSE;
1554 }
1555 }
1556 }
1557
1558 if (ok) {
1559 game.control.num_tech_types = num_techs + A_FIRST; /* includes A_NONE */
1560
1561 i = 0;
1562 advance_iterate(adv) {
1563 if (!ruleset_load_names(&adv->name, NULL, file,
1564 section_name(section_list_get(sec, i)))) {
1565 ok = FALSE;
1566 break;
1567 }
1568 i++;
1569 } advance_iterate_end;
1570 }
1571 section_list_destroy(sec);
1572
1573 return ok;
1574}
1575
1576/**********************************************************************/
1579 static bool load_ruleset_techs(struct section_file *file,
1580 struct rscompat_info *compat)
1581{
1582 struct section_list *sec;
1583 const char **slist;
1584 int i;
1585 size_t nval;
1586 struct advance *a_none = advance_by_number(A_NONE);
1587 const char *filename = secfile_name(file);
1588 bool ok = TRUE;
1589
1590 sec = secfile_sections_by_name_prefix(file, TECH_CLASS_SECTION_PREFIX);
1591
1592 i = 0;
1593 tech_class_iterate(ptclass) {
1594 const char *sec_name = section_name(section_list_get(sec, i));
1595
1596 ptclass->cost_pct = secfile_lookup_int_default(file, 100, "%s.%s",
1597 sec_name, "cost_pct");
1598
1599 i++;
1600 } tech_class_iterate_end;
1601
1602 sec = secfile_sections_by_name_prefix(file, ADVANCE_SECTION_PREFIX);
1603
1604 i = 0;
1605 advance_iterate(a) {
1606 const char *sec_name = section_name(section_list_get(sec, i));
1607 const char *sval;
1608 int j, ival;
1609 struct requirement_vector *research_reqs;
1610
1611 if (!lookup_tech(file, &a->require[AR_ONE], sec_name, "req1",
1612 filename, rule_name_get(&a->name))
1613 || !lookup_tech(file, &a->require[AR_TWO], sec_name, "req2",
1614 filename, rule_name_get(&a->name))
1615 || !lookup_tech(file, &a->require[AR_ROOT], sec_name, "root_req",
1616 filename, rule_name_get(&a->name))) {
1617 ok = FALSE;
1618 break;
1619 }
1620
1621 if ((A_NEVER == a->require[AR_ONE] && A_NEVER != a->require[AR_TWO])
1622 || (A_NEVER != a->require[AR_ONE] && A_NEVER == a->require[AR_TWO])) {
1623 ruleset_error(NULL, LOG_ERROR,
1624 "\"%s\" [%s] \"%s\": \"Never\" with non-\"Never\".",
1625 filename, sec_name, rule_name_get(&a->name));
1626 ok = FALSE;
1627 break;
1628 }
1629 if (a_none == a->require[AR_ONE] && a_none != a->require[AR_TWO]) {
1630 ruleset_error(NULL, LOG_ERROR,
1631 "\"%s\" [%s] \"%s\": should have \"None\" second.",
1632 filename, sec_name, rule_name_get(&a->name));
1633 ok = FALSE;
1634 break;
1635 }
1636
1637 if (game.control.num_tech_classes == 0) {
1638 a->tclass = NULL;
1639 } else {
1640 const char *classname;
1641
1642 classname = lookup_string(file, sec_name, "class");
1643 if (classname != NULL) {
1644 classname = Q_(classname);
1645 a->tclass = tech_class_by_rule_name(classname);
1646 if (a->tclass == NULL) {
1647 ruleset_error(NULL, LOG_ERROR,
1648 "\"%s\" [%s] \"%s\": Unknown tech class \"%s\".",
1649 filename, sec_name, rule_name_get(&a->name), classname);
1650 ok = FALSE;
1651 break;
1652 }
1653 } else {
1654 a->tclass = NULL; /* Default */
1655 }
1656 }
1657
1658 research_reqs = lookup_req_list(file, compat, sec_name, "research_reqs",
1659 rule_name_get(&a->name));
1660 if (research_reqs == NULL) {
1661 ok = FALSE;
1662 break;
1663 }
1664
1665 requirement_vector_copy(&a->research_reqs, research_reqs);
1666
1667 BV_CLR_ALL(a->flags);
1668
1669 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec_name);
1670 for (j = 0; j < nval; j++) {
1671 sval = slist[j];
1672 if (strcmp(sval, "") == 0) {
1673 continue;
1674 }
1675 ival = tech_flag_id_by_name(sval, fc_strcasecmp);
1676 if (!tech_flag_id_is_valid(ival)) {
1677 ruleset_error(NULL, LOG_ERROR,
1678 "\"%s\" [%s] \"%s\": bad flag name \"%s\".",
1679 filename, sec_name, rule_name_get(&a->name), sval);
1680 ok = FALSE;
1681 break;
1682 } else {
1683 BV_SET(a->flags, ival);
1684 }
1685 }
1686 free(slist);
1687
1688 if (!ok) {
1689 break;
1690 }
1691
1692 sz_strlcpy(a->graphic_str,
1693 secfile_lookup_str_default(file, "-", "%s.graphic", sec_name));
1694 sz_strlcpy(a->graphic_alt,
1695 secfile_lookup_str_default(file, "-",
1696 "%s.graphic_alt", sec_name));
1697
1698 a->helptext = lookup_strvec(file, sec_name, "helptext");
1699 a->bonus_message = lookup_string(file, sec_name, "bonus_message");
1700 a->cost = secfile_lookup_int_default(file, -1, "%s.%s",
1701 sec_name, "cost");
1702 a->num_reqs = 0;
1703
1704 i++;
1705 } advance_iterate_end;
1706
1707 /* Propagate a root tech up into the tech tree. If a technology
1708 * X has Y has a root tech, then any technology requiring X (in the
1709 * normal way or as a root tech) also has Y as a root tech.
1710 * Later techs may gain a whole set of root techs in this way. The one
1711 * we store in AR_ROOT is a more or less arbitrary one of these,
1712 * also signalling that the set is non-empty; after this, you'll still
1713 * have to walk the tech tree to find them all. */
1714restart:
1715
1716 if (ok) {
1717 advance_iterate(a) {
1718 if (valid_advance(a)
1719 && A_NEVER != a->require[AR_ROOT]) {
1720 bool out_of_order = FALSE;
1721
1722 /* Now find any tech depending on this technology and update its
1723 * root_req. */
1724 advance_iterate(b) {
1725 if (valid_advance(b)
1726 && A_NEVER == b->require[AR_ROOT]
1727 && (a == b->require[AR_ONE] || a == b->require[AR_TWO])) {
1728 b->require[AR_ROOT] = a->require[AR_ROOT];
1729 b->inherited_root_req = TRUE;
1730 if (b < a) {
1731 out_of_order = TRUE;
1732 }
1733 }
1734 } advance_iterate_end;
1735
1736 if (out_of_order) {
1737 /* HACK: If we just changed the root_tech of a lower-numbered
1738 * technology, we need to go back so that we can propagate the
1739 * root_tech up to that technology's parents... */
1740 goto restart;
1741 }
1742 }
1743 } advance_iterate_end;
1744
1745 /* Now rename A_NEVER to A_NONE for consistency */
1746 advance_iterate_all(a) {
1747 if (A_NEVER == a->require[AR_ROOT]) {
1748 a->require[AR_ROOT] = a_none;
1749 }
1750 } advance_iterate_all_end;
1751
1752 /* Some more consistency checking:
1753 Non-removed techs depending on removed techs is too
1754 broken to fix by default, so die.
1755 */
1756 advance_iterate(a) {
1757 if (valid_advance(a)) {
1758 /* We check for recursive tech loops later,
1759 * in build_required_techs_helper. */
1760 if (!valid_advance(a->require[AR_ONE])) {
1761 ruleset_error(NULL, LOG_ERROR,
1762 "\"%s\" tech \"%s\": req1 leads to removed tech.",
1763 filename, advance_rule_name(a));
1764 ok = FALSE;
1765 break;
1766 }
1767 if (!valid_advance(a->require[AR_TWO])) {
1768 ruleset_error(NULL, LOG_ERROR,
1769 "\"%s\" tech \"%s\": req2 leads to removed tech.",
1770 filename, advance_rule_name(a));
1771 ok = FALSE;
1772 break;
1773 }
1774 }
1775 } advance_iterate_end;
1776 }
1777
1778 section_list_destroy(sec);
1779 if (ok) {
1780 secfile_check_unused(file);
1781 }
1782
1783 return ok;
1784}
1785
1786/**********************************************************************/
1790 static bool load_unit_names(struct section_file *file,
1791 struct rscompat_info *compat)
1792{
1793 struct section_list *sec = NULL;
1794 int nval = 0;
1795 int i;
1796 const char *filename = secfile_name(file);
1797 const char *flag;
1798 bool ok = TRUE;
1799
1800 if (!rscompat_check_cap_and_version(file, filename, compat)) {
1801 return FALSE;
1802 }
1803
1804 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
1805 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
1806
1807 /* User unit flag names */
1808 for (i = 0; (flag = secfile_lookup_str_default(file, NULL, "control.flags%d.name", i)) ;
1809 i++) {
1810 const char *helptxt = secfile_lookup_str_default(file, NULL, "control.flags%d.helptxt",
1811 i);
1812
1813 if (unit_type_flag_id_by_name(flag, fc_strcasecmp)
1814 != unit_type_flag_id_invalid()) {
1815 ruleset_error(NULL, LOG_ERROR,
1816 "\"%s\": Duplicate unit flag name '%s'",
1817 filename, flag);
1818 ok = FALSE;
1819 break;
1820 }
1821 if (i > MAX_NUM_USER_UNIT_FLAGS) {
1822 ruleset_error(NULL, LOG_ERROR,
1823 "\"%s\": Too many user unit type flags!",
1824 filename);
1825 ok = FALSE;
1826 break;
1827 }
1828
1829 set_user_unit_type_flag_name(UTYF_USER_FLAG_1 + i, flag, helptxt);
1830 }
1831
1832 if (ok) {
1833 /* Blank the remaining unit type user flags. */
1834 for (; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
1835 set_user_unit_type_flag_name(UTYF_USER_FLAG_1 + i, NULL, NULL);
1836 }
1837 }
1838
1839 if (ok) {
1840 /* User unit class flag names */
1841 for (i = 0;
1842 (flag = secfile_lookup_str_default(file, NULL,
1843 "control.class_flags%d.name",
1844 i));
1845 i++) {
1846 const char *helptxt = secfile_lookup_str_default(file, NULL,
1847 "control.class_flags%d.helptxt", i);
1848
1849 if (unit_class_flag_id_by_name(flag, fc_strcasecmp)
1850 != unit_class_flag_id_invalid()) {
1851 ruleset_error(NULL, LOG_ERROR,
1852 "\"%s\": Duplicate unit class flag name '%s'",
1853 filename, flag);
1854 ok = FALSE;
1855 break;
1856 }
1857 if (i > MAX_NUM_USER_UCLASS_FLAGS) {
1858 ruleset_error(NULL, LOG_ERROR,
1859 "\"%s\": Too many user unit class flags!",
1860 filename);
1861 ok = FALSE;
1862 break;
1863 }
1864
1865 set_user_unit_class_flag_name(UCF_USER_FLAG_1 + i, flag, helptxt);
1866 }
1867 }
1868
1869 if (ok) {
1870 /* Blank the remaining unit class user flags. */
1871 for (; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
1872 set_user_unit_class_flag_name(UCF_USER_FLAG_1 + i, NULL, NULL);
1873 }
1874 }
1875
1876 if (ok) {
1877 /* Unit classes */
1878 sec = secfile_sections_by_name_prefix(file, UNIT_CLASS_SECTION_PREFIX);
1879 if (NULL == sec || 0 == (nval = section_list_size(sec))) {
1880 ruleset_error(NULL, LOG_ERROR,
1881 "\"%s\": No unit classes?!?", filename);
1882 ok = FALSE;
1883 } else {
1884 log_verbose("%d unit classes", nval);
1885 if (nval > UCL_LAST) {
1886 ruleset_error(NULL, LOG_ERROR,
1887 "\"%s\": Too many unit classes (%d, max %d)",
1888 filename, nval, UCL_LAST);
1889 ok = FALSE;
1890 }
1891 }
1892 }
1893
1894 if (ok) {
1895 game.control.num_unit_classes = nval;
1896
1897 unit_class_iterate(punitclass) {
1898 const int pci = uclass_index(punitclass);
1899
1900 if (!ruleset_load_names(&punitclass->name, NULL, file,
1901 section_name(section_list_get(sec, pci)))) {
1902 ok = FALSE;
1903 break;
1904 }
1905 } unit_class_iterate_end;
1906 }
1907 section_list_destroy(sec);
1908 sec = NULL;
1909
1910 /* The names: */
1911 if (ok) {
1912 sec = secfile_sections_by_name_prefix(file, UNIT_SECTION_PREFIX);
1913 if (NULL == sec || 0 == (nval = section_list_size(sec))) {
1914 ruleset_error(NULL, LOG_ERROR,
1915 "\"%s\": No unit types?!?", filename);
1916 ok = FALSE;
1917 } else {
1918 log_verbose("%d unit types (including possibly unused)", nval);
1919 if (nval > U_LAST) {
1920 ruleset_error(NULL, LOG_ERROR,
1921 "\"%s\": Too many unit types (%d, max %d)",
1922 filename, nval, U_LAST);
1923 ok = FALSE;
1924 }
1925 }
1926 }
1927
1928 if (ok) {
1929 game.control.num_unit_types = nval;
1930
1931 unit_type_iterate(punittype) {
1932 const int utypei = utype_index(punittype);
1933 if (!ruleset_load_names(&punittype->name, NULL, file,
1934 section_name(section_list_get(sec, utypei)))) {
1935 ok = FALSE;
1936 break;
1937 }
1938 } unit_type_iterate_end;
1939 }
1940 section_list_destroy(sec);
1941
1942 return ok;
1943}
1944
1945/**********************************************************************/
1948 static bool load_ruleset_veteran(struct section_file *file,
1949 const char *path,
1950 struct veteran_system **vsystem, char *err,
1951 size_t err_len)
1952{
1953 const char **vlist_name;
1954 int *vlist_power, *vlist_raise, *vlist_wraise, *vlist_move;
1955 size_t count_name, count_power, count_raise, count_wraise, count_move;
1956 int i;
1957 bool ret = TRUE;
1958
1959 /* The pointer should be uninitialised. */
1960 if (*vsystem != NULL) {
1961 fc_snprintf(err, err_len, "Veteran system is defined?!");
1962 return FALSE;
1963 }
1964
1965 /* Load data. */
1966 vlist_name = secfile_lookup_str_vec(file, &count_name,
1967 "%s.veteran_names", path);
1968 vlist_power = secfile_lookup_int_vec(file, &count_power,
1969 "%s.veteran_power_fact", path);
1970 vlist_raise = secfile_lookup_int_vec(file, &count_raise,
1971 "%s.veteran_base_raise_chance", path);
1972 vlist_wraise = secfile_lookup_int_vec(file, &count_wraise,
1973 "%s.veteran_work_raise_chance",
1974 path);
1975 vlist_move = secfile_lookup_int_vec(file, &count_move,
1976 "%s.veteran_move_bonus", path);
1977
1978 if (count_name > MAX_VET_LEVELS) {
1979 ret = FALSE;
1980 fc_snprintf(err, err_len, "\"%s\": Too many veteran levels (section "
1981 "'%s': %lu, max %d)", secfile_name(file), path,
1982 (long unsigned)count_name, MAX_VET_LEVELS);
1983 } else if (count_name != count_power
1984 || count_name != count_raise
1985 || count_name != count_wraise
1986 || count_name != count_move) {
1987 ret = FALSE;
1988 fc_snprintf(err, err_len, "\"%s\": Different lengths for the veteran "
1989 "settings in section '%s'", secfile_name(file),
1990 path);
1991 } else if (count_name == 0) {
1992 /* Nothing defined. */
1993 *vsystem = NULL;
1994 } else {
1995 /* Generate the veteran system. */
1996 *vsystem = veteran_system_new((int)count_name);
1997
1998#define rs_sanity_veteran(_path, _entry, _i, _condition, _action) \
1999 if (_condition) { \
2000 log_error("Invalid veteran definition '%s.%s[%d]'!", \
2001 _path, _entry, _i); \
2002 log_debug("Failed check: '%s'. Update value: '%s'.", \
2003 #_condition, #_action); \
2004 _action; \
2005 }
2006 for (i = 0; i < count_name; i++) {
2007 /* Some sanity checks. */
2008 rs_sanity_veteran(path, "veteran_power_fact", i,
2009 (vlist_power[i] < 0), vlist_power[i] = 0);
2010 rs_sanity_veteran(path, "veteran_base_raise_chance", i,
2011 (vlist_raise[i] < 0), vlist_raise[i] = 0);
2012 rs_sanity_veteran(path, "veteran_work_raise_chance", i,
2013 (vlist_wraise[i] < 0), vlist_wraise[i] = 0);
2014 rs_sanity_veteran(path, "veteran_move_bonus", i,
2015 (vlist_move[i] < 0), vlist_move[i] = 0);
2016 if (i == 0) {
2017 /* First element.*/
2018 rs_sanity_veteran(path, "veteran_power_fact", i,
2019 (vlist_power[i] != 100), vlist_power[i] = 100);
2020 } else if (i == count_name - 1) {
2021 /* Last element. */
2022 rs_sanity_veteran(path, "veteran_power_fact", i,
2023 (vlist_power[i] < vlist_power[i - 1]),
2024 vlist_power[i] = vlist_power[i - 1]);
2025 rs_sanity_veteran(path, "veteran_base_raise_chance", i,
2026 (vlist_raise[i] != 0), vlist_raise[i] = 0);
2027 rs_sanity_veteran(path, "veteran_work_raise_chance", i,
2028 (vlist_wraise[i] != 0), vlist_wraise[i] = 0);
2029 } else {
2030 /* All elements inbetween. */
2031 rs_sanity_veteran(path, "veteran_power_fact", i,
2032 (vlist_power[i] < vlist_power[i - 1]),
2033 vlist_power[i] = vlist_power[i - 1]);
2034 rs_sanity_veteran(path, "veteran_base_raise_chance", i,
2035 (vlist_raise[i] > 100), vlist_raise[i] = 100);
2036 rs_sanity_veteran(path, "veteran_work_raise_chance", i,
2037 (vlist_wraise[i] > 100), vlist_wraise[i] = 100);
2038 }
2039
2040 veteran_system_definition(*vsystem, i, vlist_name[i], vlist_power[i],
2041 vlist_move[i], vlist_raise[i],
2042 vlist_wraise[i]);
2043 }
2044#undef rs_sanity_veteran
2045 }
2046
2047 if (vlist_name) {
2048 free(vlist_name);
2049 }
2050 if (vlist_power) {
2051 free(vlist_power);
2052 }
2053 if (vlist_raise) {
2054 free(vlist_raise);
2055 }
2056 if (vlist_wraise) {
2057 free(vlist_wraise);
2058 }
2059 if (vlist_move) {
2060 free(vlist_move);
2061 }
2062
2063 return ret;
2064}
2065
2066/**********************************************************************/
2069 static bool load_ruleset_units(struct section_file *file,
2070 struct rscompat_info *compat)
2071{
2072 int j, ival;
2073 size_t nval;
2074 struct section_list *sec, *csec;
2075 const char *sval, **slist;
2076 const char *filename = secfile_name(file);
2077 char msg[MAX_LEN_MSG];
2078 bool ok = TRUE;
2079
2080 if (!load_ruleset_veteran(file, "veteran_system", &game.veteran, msg,
2081 sizeof(msg))
2082 || game.veteran == NULL) {
2083 ruleset_error(NULL, LOG_ERROR,
2084 "Error loading the default veteran system: %s",
2085 msg);
2086 ok = FALSE;
2087 }
2088
2089 sec = secfile_sections_by_name_prefix(file, UNIT_SECTION_PREFIX);
2090 nval = (NULL != sec ? section_list_size(sec) : 0);
2091
2092 csec = secfile_sections_by_name_prefix(file, UNIT_CLASS_SECTION_PREFIX);
2093 nval = (NULL != csec ? section_list_size(csec) : 0);
2094
2095 if (ok) {
2096 unit_class_iterate(uc) {
2097 int i = uclass_index(uc);
2098 const char *sec_name = section_name(section_list_get(csec, i));
2099
2100 if (secfile_lookup_int(file, &uc->min_speed, "%s.min_speed", sec_name)) {
2101 uc->min_speed *= SINGLE_MOVE;
2102 } else {
2103 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
2104 ok = FALSE;
2105 break;
2106 }
2107 if (!secfile_lookup_int(file, &uc->hp_loss_pct,
2108 "%s.hp_loss_pct", sec_name)) {
2109 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
2110 ok = FALSE;
2111 break;
2112 }
2113
2114 uc->non_native_def_pct = secfile_lookup_int_default(file, 100,
2115 "%s.non_native_def_pct",
2116 sec_name);
2117
2118 BV_CLR_ALL(uc->flags);
2119 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec_name);
2120 for (j = 0; j < nval; j++) {
2121 sval = slist[j];
2122 if (strcmp(sval, "") == 0) {
2123 continue;
2124 }
2125
2126 if (compat->compat_mode && compat->version < RSFORMAT_3_3) {
2127 sval = rscompat_utype_flag_name_3_3(sval);
2128 }
2129
2130 ival = unit_class_flag_id_by_name(sval, fc_strcasecmp);
2131 if (!unit_class_flag_id_is_valid(ival)) {
2132 ok = FALSE;
2133 ival = unit_type_flag_id_by_name(sval, fc_strcasecmp);
2134 if (unit_type_flag_id_is_valid(ival)) {
2135 ruleset_error(NULL, LOG_ERROR,
2136 "\"%s\" unit_class \"%s\": unit_type flag \"%s\"!",
2137 filename, uclass_rule_name(uc), sval);
2138 } else {
2139 ruleset_error(NULL, LOG_ERROR,
2140 "\"%s\" unit_class \"%s\": bad flag name \"%s\".",
2141 filename, uclass_rule_name(uc), sval);
2142 }
2143 break;
2144 } else {
2145 BV_SET(uc->flags, ival);
2146 }
2147 }
2148 free(slist);
2149
2150 uc->helptext = lookup_strvec(file, sec_name, "helptext");
2151
2152 if (!ok) {
2153 break;
2154 }
2155 } unit_class_iterate_end;
2156 }
2157
2158 if (ok) {
2159 /* Tech and Gov requirements; per unit veteran system */
2160 unit_type_iterate(u) {
2161 const int i = utype_index(u);
2162 const struct section *psection = section_list_get(sec, i);
2163 const char *sec_name = section_name(psection);
2164 struct requirement_vector *reqs;
2165
2166 reqs = lookup_req_list(file, compat, sec_name, "reqs",
2167 utype_rule_name(u));
2168
2169 if (reqs == NULL) {
2170 ok = FALSE;
2171 break;
2172 }
2173
2174 requirement_vector_copy(&u->build_reqs, reqs);
2175
2176 if (!load_ruleset_veteran(file, sec_name, &u->veteran,
2177 msg, sizeof(msg))) {
2178 ruleset_error(NULL, LOG_ERROR,
2179 "Error loading the veteran system: %s",
2180 msg);
2181 ok = FALSE;
2182 break;
2183 }
2184
2185 if (!lookup_unit_type(file, sec_name, "obsolete_by",
2186 &u->obsoleted_by, filename,
2187 rule_name_get(&u->name))
2188 || !lookup_unit_type(file, sec_name, "convert_to",
2189 &u->converted_to, filename,
2190 rule_name_get(&u->name))) {
2191 ok = FALSE;
2192 break;
2193 }
2194 u->convert_time = 1; /* default */
2195 lookup_time(file, &u->convert_time, sec_name, "convert_time",
2196 filename, rule_name_get(&u->name), &ok);
2197 } unit_type_iterate_end;
2198 }
2199
2200 if (ok) {
2201 /* main stats: */
2202 unit_type_iterate(u) {
2203 const int i = utype_index(u);
2204 struct unit_class *pclass;
2205 const char *sec_name = section_name(section_list_get(sec, i));
2206 const char *str;
2207
2208 sval = secfile_lookup_str(file, "%s.class", sec_name);
2209 pclass = unit_class_by_rule_name(sval);
2210 if (!pclass) {
2211 ruleset_error(NULL, LOG_ERROR,
2212 "\"%s\" unit_type \"%s\": bad class \"%s\".",
2213 filename, utype_rule_name(u), sval);
2214 ok = FALSE;
2215 break;
2216 }
2217 u->uclass = pclass;
2218
2219 sz_strlcpy(u->sound_move,
2220 secfile_lookup_str_default(file, "-", "%s.sound_move",
2221 sec_name));
2222 sz_strlcpy(u->sound_move_alt,
2223 secfile_lookup_str_default(file, "-", "%s.sound_move_alt",
2224 sec_name));
2225 sz_strlcpy(u->sound_fight,
2226 secfile_lookup_str_default(file, "-", "%s.sound_fight",
2227 sec_name));
2228 sz_strlcpy(u->sound_fight_alt,
2229 secfile_lookup_str_default(file, "-", "%s.sound_fight_alt",
2230 sec_name));
2231
2232 if ((str = secfile_lookup_str(file, "%s.graphic", sec_name))) {
2233 sz_strlcpy(u->graphic_str, str);
2234 } else {
2235 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
2236 ok = FALSE;
2237 break;
2238 }
2239 sz_strlcpy(u->graphic_alt,
2240 secfile_lookup_str_default(file, "-", "%s.graphic_alt",
2241 sec_name));
2242 sz_strlcpy(u->graphic_alt2,
2243 secfile_lookup_str_default(file, "-", "%s.graphic_alt2",
2244 sec_name));
2245
2246 if (!secfile_lookup_int(file, &u->build_cost,
2247 "%s.build_cost", sec_name)
2248 || !secfile_lookup_int(file, &u->pop_cost,
2249 "%s.pop_cost", sec_name)
2250 || !secfile_lookup_int(file, &u->attack_strength,
2251 "%s.attack", sec_name)
2252 || !secfile_lookup_int(file, &u->defense_strength,
2253 "%s.defense", sec_name)
2254 || !secfile_lookup_int(file, &u->move_rate,
2255 "%s.move_rate", sec_name)
2256 || !secfile_lookup_int(file, &u->vision_radius_sq,
2257 "%s.vision_radius_sq", sec_name)
2258 || !secfile_lookup_int(file, &u->transport_capacity,
2259 "%s.transport_cap", sec_name)
2260 || !secfile_lookup_int(file, &u->hp,
2261 "%s.hitpoints", sec_name)
2262 || !secfile_lookup_int(file, &u->firepower,
2263 "%s.firepower", sec_name)
2264 || !secfile_lookup_int(file, &u->fuel,
2265 "%s.fuel", sec_name)
2266 || !secfile_lookup_int(file, &u->happy_cost,
2267 "%s.uk_happy", sec_name)) {
2268 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
2269 ok = FALSE;
2270 break;
2271 }
2272 u->move_rate *= SINGLE_MOVE;
2273
2274 if (u->firepower <= 0) {
2275 ruleset_error(NULL, LOG_ERROR,
2276 "\"%s\" unit_type \"%s\":"
2277 " firepower is %d,"
2278 " but must be at least 1. "
2279 " If you want no attack ability,"
2280 " set the unit's attack strength to 0.",
2281 filename, utype_rule_name(u), u->firepower);
2282 ok = FALSE;
2283 break;
2284 }
2285
2286 lookup_cbonus_list(u->bonuses, file, sec_name, "bonuses");
2287
2288 output_type_iterate(o) {
2289 u->upkeep[o] = secfile_lookup_int_default(file, 0, "%s.uk_%s",
2290 sec_name,
2291 get_output_identifier(o));
2292 } output_type_iterate_end;
2293
2294 slist = secfile_lookup_str_vec(file, &nval, "%s.cargo", sec_name);
2295 if (u->transport_capacity > 0) {
2296 if (nval == 0) {
2297 ruleset_error(NULL, LOG_ERROR,
2298 "\"%s\" unit type \"%s\" "
2299 "has transport_cap %d, but no cargo unit classes.",
2300 filename, utype_rule_name(u), u->transport_capacity);
2301 ok = FALSE;
2302 break;
2303 }
2304 } else {
2305 if (nval > 0) {
2306 ruleset_error(NULL, LOG_ERROR,
2307 "\"%s\" unit type \"%s\" "
2308 "has cargo defined, but transport_cap is 0.",
2309 filename, utype_rule_name(u));
2310 ok = FALSE;
2311 break;
2312 }
2313 }
2314
2315 BV_CLR_ALL(u->cargo);
2316 for (j = 0; j < nval; j++) {
2317 struct unit_class *uclass = unit_class_by_rule_name(slist[j]);
2318
2319 if (!uclass) {
2320 ruleset_error(NULL, LOG_ERROR,
2321 "\"%s\" unit_type \"%s\":"
2322 "has unknown unit class %s as cargo.",
2323 filename, utype_rule_name(u), slist[j]);
2324 ok = FALSE;
2325 break;
2326 }
2327
2328 BV_SET(u->cargo, uclass_index(uclass));
2329 }
2330 free(slist);
2331
2332 if (!ok) {
2333 break;
2334 }
2335
2336 slist = secfile_lookup_str_vec(file, &nval, "%s.targets", sec_name);
2337 BV_CLR_ALL(u->targets);
2338 for (j = 0; j < nval; j++) {
2339 struct unit_class *uclass = unit_class_by_rule_name(slist[j]);
2340
2341 if (!uclass) {
2342 ruleset_error(NULL, LOG_ERROR,
2343 "\"%s\" unit_type \"%s\":"
2344 "has unknown unit class %s as target.",
2345 filename, utype_rule_name(u), slist[j]);
2346 ok = FALSE;
2347 break;
2348 }
2349
2350 BV_SET(u->targets, uclass_index(uclass));
2351 }
2352 free(slist);
2353
2354 if (!ok) {
2355 break;
2356 }
2357
2358 slist = secfile_lookup_str_vec(file, &nval, "%s.embarks", sec_name);
2359 BV_CLR_ALL(u->embarks);
2360 for (j = 0; j < nval; j++) {
2361 struct unit_class *uclass = unit_class_by_rule_name(slist[j]);
2362
2363 if (!uclass) {
2364 ruleset_error(NULL, LOG_ERROR,
2365 "\"%s\" unit_type \"%s\":"
2366 "has unknown unit class %s as embarkable.",
2367 filename, utype_rule_name(u), slist[j]);
2368 ok = FALSE;
2369 break;
2370 }
2371
2372 BV_SET(u->embarks, uclass_index(uclass));
2373 }
2374 free(slist);
2375
2376 if (!ok) {
2377 break;
2378 }
2379
2380 slist = secfile_lookup_str_vec(file, &nval, "%s.disembarks", sec_name);
2381 BV_CLR_ALL(u->disembarks);
2382 for (j = 0; j < nval; j++) {
2383 struct unit_class *uclass = unit_class_by_rule_name(slist[j]);
2384
2385 if (!uclass) {
2386 ruleset_error(NULL, LOG_ERROR,
2387 "\"%s\" unit_type \"%s\":"
2388 "has unknown unit class %s as disembarkable.",
2389 filename, utype_rule_name(u), slist[j]);
2390 ok = FALSE;
2391 break;
2392 }
2393
2394 BV_SET(u->disembarks, uclass_index(uclass));
2395 }
2396 free(slist);
2397
2398 if (!ok) {
2399 break;
2400 }
2401
2402 /* Set also all classes that are never unreachable as targets,
2403 * embarks, and disembarks. */
2404 unit_class_iterate(preachable) {
2405 if (!uclass_has_flag(preachable, UCF_UNREACHABLE)) {
2406 BV_SET(u->targets, uclass_index(preachable));
2407 BV_SET(u->embarks, uclass_index(preachable));
2408 BV_SET(u->disembarks, uclass_index(preachable));
2409 }
2410 } unit_class_iterate_end;
2411
2412 str = secfile_lookup_str_default(file, "Main", "%s.vision_layer",
2413 sec_name);
2414 u->vlayer = vision_layer_by_name(str, fc_strcasecmp);
2415 if (!vision_layer_is_valid(u->vlayer)) {
2416 ruleset_error(NULL, LOG_ERROR,
2417 "\"%s\" unit_type \"%s\":"
2418 "has unknown vision layer %s.",
2419 filename, utype_rule_name(u), str);
2420 ok = FALSE;
2421 break;
2422 }
2423
2424 u->helptext = lookup_strvec(file, sec_name, "helptext");
2425
2426 u->paratroopers_range = secfile_lookup_int_default(file,
2427 0, "%s.paratroopers_range", sec_name);
2428
2429 u->bombard_rate = secfile_lookup_int_default(file, 0,
2430 "%s.bombard_rate", sec_name);
2431 u->city_slots = secfile_lookup_int_default(file, 0,
2432 "%s.city_slots", sec_name);
2433 u->city_size = secfile_lookup_int_default(file, 1,
2434 "%s.city_size", sec_name);
2435
2436 sval = secfile_lookup_str_default(file, transp_def_type_name(TDT_ALIGHT),
2437 "%s.tp_defense", sec_name);
2438 u->tp_defense = transp_def_type_by_name(sval, fc_strcasecmp);
2439 if (!transp_def_type_is_valid(u->tp_defense)) {
2440 ruleset_error(NULL, LOG_ERROR,
2441 "\"%s\" unit_type \"%s\":"
2442 " bad tp_defense \"%s\".",
2443 filename, utype_rule_name(u), sval);
2444 ok = FALSE;
2445 break;
2446 }
2447 } unit_type_iterate_end;
2448 }
2449
2450 if (ok) {
2451 /* Flags */
2452 unit_type_iterate(u) {
2453 const int i = utype_index(u);
2454
2455 BV_CLR_ALL(u->flags);
2456 fc_assert(!utype_has_flag(u, UTYF_LAST_USER_FLAG - 1));
2457
2458 slist = secfile_lookup_str_vec(file, &nval, "%s.flags",
2459 section_name(section_list_get(sec, i)));
2460 for (j = 0; j < nval; j++) {
2461 sval = slist[j];
2462 if (0 == strcmp(sval, "")) {
2463 continue;
2464 }
2465 ival = unit_type_flag_id_by_name(sval, fc_strcasecmp);
2466 if (!unit_type_flag_id_is_valid(ival)) {
2467 ok = FALSE;
2468 ival = unit_class_flag_id_by_name(sval, fc_strcasecmp);
2469 if (unit_class_flag_id_is_valid(ival)) {
2470 ruleset_error(NULL, LOG_ERROR,
2471 "\"%s\" unit_type \"%s\": unit_class flag!",
2472 filename, utype_rule_name(u));
2473 } else {
2474 ruleset_error(NULL, LOG_ERROR,
2475 "\"%s\" unit_type \"%s\": bad flag name \"%s\".",
2476 filename, utype_rule_name(u), sval);
2477 }
2478 break;
2479 } else {
2480 BV_SET(u->flags, ival);
2481 }
2482 }
2483 free(slist);
2484
2485 if (!ok) {
2486 break;
2487 }
2488 } unit_type_iterate_end;
2489 }
2490
2491 /* Roles */
2492 if (ok) {
2493 unit_type_iterate(u) {
2494 const int i = utype_index(u);
2495
2496 BV_CLR_ALL(u->roles);
2497
2498 slist = secfile_lookup_str_vec(file, &nval, "%s.roles",
2499 section_name(section_list_get(sec, i)));
2500 for (j = 0; j < nval; j++) {
2501 sval = slist[j];
2502 if (strcmp(sval, "") == 0) {
2503 continue;
2504 }
2505 ival = unit_role_id_by_name(sval, fc_strcasecmp);
2506 if (!unit_role_id_is_valid(ival)) {
2507 ruleset_error(NULL, LOG_ERROR,
2508 "\"%s\" unit_type \"%s\": bad role name \"%s\".",
2509 filename, utype_rule_name(u), sval);
2510 ok = FALSE;
2511 break;
2512 } else {
2513 BV_SET(u->roles, ival - L_FIRST);
2514 }
2515 fc_assert(utype_has_role(u, ival));
2516 }
2517 free(slist);
2518 } unit_type_iterate_end;
2519 }
2520
2521 if (ok) {
2522 /* Some more consistency checking: */
2523 unit_type_iterate(u) {
2524 unit_tech_reqs_iterate(u, padv) {
2525 if (!valid_advance(padv)) {
2526 ruleset_error(NULL, LOG_ERROR,
2527 "\"%s\" unit_type \"%s\": depends on removed tech \"%s\".",
2528 filename, utype_rule_name(u),
2529 advance_rule_name(padv));
2530 ok = FALSE;
2531 break;
2532 }
2533 } unit_tech_reqs_iterate_end;
2534
2535 if (!ok) {
2536 break;
2537 }
2538 } unit_type_iterate_end;
2539 }
2540
2541 section_list_destroy(csec);
2542 section_list_destroy(sec);
2543
2544 if (ok) {
2545 secfile_check_unused(file);
2546 }
2547
2548 return ok;
2549}
2550
2551/**********************************************************************/
2555 static bool load_building_names(struct section_file *file,
2556 struct rscompat_info *compat)
2557{
2558 struct section_list *sec;
2559 int i, nval = 0;
2560 const char *filename = secfile_name(file);
2561 bool ok = TRUE;
2562 const char *flag;
2563
2564 if (!rscompat_check_cap_and_version(file, filename, compat)) {
2565 return FALSE;
2566 }
2567
2568 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
2569 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
2570
2571 /* The names: */
2572 sec = secfile_sections_by_name_prefix(file, BUILDING_SECTION_PREFIX);
2573 if (NULL == sec || 0 == (nval = section_list_size(sec))) {
2574 ruleset_error(NULL, LOG_ERROR,
2575 "\"%s\": No improvements?!?", filename);
2576 ok = FALSE;
2577 } else {
2578 log_verbose("%d improvement types (including possibly unused)", nval);
2579 if (nval > B_LAST) {
2580 ruleset_error(NULL, LOG_ERROR,
2581 "\"%s\": Too many improvements (%d, max %d)",
2582 filename, nval, B_LAST);
2583 ok = FALSE;
2584 }
2585 }
2586
2587 if (ok) {
2588 game.control.num_impr_types = nval;
2589
2590 for (i = 0; i < nval; i++) {
2591 struct impr_type *b = improvement_by_number(i);
2592
2593 if (!ruleset_load_names(&b->name, NULL, file, section_name(section_list_get(sec, i)))) {
2594 ok = FALSE;
2595 break;
2596 }
2597 }
2598 }
2599
2600 /* User building flag names */
2601 for (i = 0;
2602 (flag = secfile_lookup_str_default(file, NULL,
2603 "control.building_flags%d.name",
2604 i));
2605 i++) {
2606 const char *helptxt = secfile_lookup_str_default(file, NULL,
2607 "control.building_flags%d.helptxt", i);
2608
2609 if (impr_flag_id_by_name(flag, fc_strcasecmp)
2610 != impr_flag_id_invalid()) {
2611 ruleset_error(NULL, LOG_ERROR,
2612 "\"%s\": Duplicate building flag name '%s'",
2613 filename, flag);
2614 ok = FALSE;
2615 break;
2616 }
2617 if (i > MAX_NUM_USER_BUILDING_FLAGS) {
2618 ruleset_error(NULL, LOG_ERROR,
2619 "\"%s\": Too many user building flags!",
2620 filename);
2621 ok = FALSE;
2622 break;
2623 }
2624
2625 set_user_impr_flag_name(IF_USER_FLAG_1 + i, flag, helptxt);
2626 }
2627
2628 section_list_destroy(sec);
2629
2630 return ok;
2631}
2632
2633/**********************************************************************/
2636 static bool load_ruleset_buildings(struct section_file *file,
2637 struct rscompat_info *compat)
2638{
2639 struct section_list *sec;
2640 const char *item;
2641 int i, nval;
2642 const char *filename = secfile_name(file);
2643 bool ok = TRUE;
2644
2645 sec = secfile_sections_by_name_prefix(file, BUILDING_SECTION_PREFIX);
2646 nval = (NULL != sec ? section_list_size(sec) : 0);
2647
2648 for (i = 0; i < nval && ok; i++) {
2649 struct impr_type *b = improvement_by_number(i);
2650 const char *sec_name = section_name(section_list_get(sec, i));
2651 struct requirement_vector *reqs =
2652 lookup_req_list(file, compat, sec_name, "reqs",
2653 improvement_rule_name(b));
2654
2655 if (reqs == NULL) {
2656 ok = FALSE;
2657 break;
2658 } else {
2659 const char *sval, **slist;
2660 int j, ival;
2661 size_t nflags;
2662
2663 item = secfile_lookup_str(file, "%s.genus", sec_name);
2664 b->genus = impr_genus_id_by_name(item, fc_strcasecmp);
2665 if (!impr_genus_id_is_valid(b->genus)) {
2666 ruleset_error(NULL, LOG_ERROR,
2667 "\"%s\" improvement \"%s\": couldn't match "
2668 "genus \"%s\".", filename,
2669 improvement_rule_name(b), item);
2670 ok = FALSE;
2671 break;
2672 }
2673
2674 slist = secfile_lookup_str_vec(file, &nflags, "%s.flags", sec_name);
2675 BV_CLR_ALL(b->flags);
2676
2677 for (j = 0; j < nflags; j++) {
2678 sval = slist[j];
2679 if (strcmp(sval, "") == 0) {
2680 continue;
2681 }
2682 ival = impr_flag_id_by_name(sval, fc_strcasecmp);
2683 if (!impr_flag_id_is_valid(ival)) {
2684 ruleset_error(NULL, LOG_ERROR,
2685 "\"%s\" improvement \"%s\": bad flag name \"%s\".",
2686 filename, improvement_rule_name(b), sval);
2687 ok = FALSE;
2688 break;
2689 } else {
2690 BV_SET(b->flags, ival);
2691 }
2692 }
2693 free(slist);
2694
2695 if (!ok) {
2696 break;
2697 }
2698
2699 requirement_vector_copy(&b->reqs, reqs);
2700
2701 {
2702 struct requirement_vector *obs_reqs =
2703 lookup_req_list(file, compat, sec_name, "obsolete_by",
2704 improvement_rule_name(b));
2705
2706 if (obs_reqs == NULL) {
2707 ok = FALSE;
2708 break;
2709 } else {
2710 requirement_vector_copy(&b->obsolete_by, obs_reqs);
2711 }
2712 }
2713
2714 if (!secfile_lookup_int(file, &b->build_cost,
2715 "%s.build_cost", sec_name)
2716 || !secfile_lookup_int(file, &b->upkeep,
2717 "%s.upkeep", sec_name)
2718 || !secfile_lookup_int(file, &b->sabotage,
2719 "%s.sabotage", sec_name)) {
2720 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
2721 ok = FALSE;
2722 break;
2723 }
2724
2725 sz_strlcpy(b->graphic_str,
2726 secfile_lookup_str_default(file, "-",
2727 "%s.graphic", sec_name));
2728 sz_strlcpy(b->graphic_alt,
2729 secfile_lookup_str_default(file, "-",
2730 "%s.graphic_alt", sec_name));
2731 sz_strlcpy(b->graphic_alt2,
2732 secfile_lookup_str_default(file, "-",
2733 "%s.graphic_alt2", sec_name));
2734
2735 sz_strlcpy(b->soundtag,
2736 secfile_lookup_str_default(file, "-",
2737 "%s.sound", sec_name));
2738 sz_strlcpy(b->soundtag_alt,
2739 secfile_lookup_str_default(file, "-",
2740 "%s.sound_alt", sec_name));
2741 sz_strlcpy(b->soundtag_alt2,
2742 secfile_lookup_str_default(file, "-",
2743 "%s.sound_alt2", sec_name));
2744 b->helptext = lookup_strvec(file, sec_name, "helptext");
2745 }
2746 }
2747
2748 section_list_destroy(sec);
2749 if (ok) {
2750 secfile_check_unused(file);
2751 }
2752
2753 return ok;
2754}
2755
2756/**********************************************************************/
2760 static bool load_terrain_names(struct section_file *file,
2761 struct rscompat_info *compat)
2762{
2763 int nval = 0;
2764 struct section_list *sec = NULL;
2765 const char *flag;
2766 int i;
2767 const char *filename = secfile_name(file);
2768 bool ok = TRUE;
2769
2770 if (!rscompat_check_cap_and_version(file, filename, compat)) {
2771 return FALSE;
2772 }
2773
2774 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
2775 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
2776
2777 /* User terrain flag names */
2778 for (i = 0; (flag = secfile_lookup_str_default(file, NULL, "control.flags%d.name", i)) ;
2779 i++) {
2780 const char *helptxt = secfile_lookup_str_default(file, NULL, "control.flags%d.helptxt",
2781 i);
2782
2783 if (terrain_flag_id_by_name(flag, fc_strcasecmp)
2784 != terrain_flag_id_invalid()) {
2785 ruleset_error(NULL, LOG_ERROR,
2786 "\"%s\": Duplicate terrain flag name '%s'",
2787 filename, flag);
2788 ok = FALSE;
2789 break;
2790 }
2791 if (i > MAX_NUM_USER_TER_FLAGS) {
2792 ruleset_error(NULL, LOG_ERROR,
2793 "\"%s\": Too many user terrain flags!",
2794 filename);
2795 ok = FALSE;
2796 break;
2797 }
2798
2799 set_user_terrain_flag_name(TER_USER_1 + i, flag, helptxt);
2800 }
2801
2802 if (ok) {
2803 /* Blank the remaining terrain user flag slots. */
2804 for (; i < MAX_NUM_USER_TER_FLAGS; i++) {
2805 set_user_terrain_flag_name(TER_USER_1 + i, NULL, NULL);
2806 }
2807 }
2808
2809 /* User extra flag names */
2810 for (i = 0;
2811 (flag = secfile_lookup_str_default(file, NULL,
2812 "control.extra_flags%d.name",
2813 i));
2814 i++) {
2815 const char *helptxt = secfile_lookup_str_default(file, NULL,
2816 "control.extra_flags%d.helptxt", i);
2817
2818 if (extra_flag_id_by_name(flag, fc_strcasecmp)
2819 != extra_flag_id_invalid()) {
2820 ruleset_error(NULL, LOG_ERROR,
2821 "\"%s\": Duplicate extra flag name '%s'",
2822 filename, flag);
2823 ok = FALSE;
2824 break;
2825 }
2826 if (i > MAX_NUM_USER_EXTRA_FLAGS) {
2827 ruleset_error(NULL, LOG_ERROR,
2828 "\"%s\": Too many user extra flags!",
2829 filename);
2830 ok = FALSE;
2831 break;
2832 }
2833
2834 set_user_extra_flag_name(EF_USER_FLAG_1 + i, flag, helptxt);
2835 }
2836
2837 if (ok) {
2838 /* Blank the remaining extra user flag slots. */
2839 for (; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
2840 set_user_extra_flag_name(EF_USER_FLAG_1 + i, NULL, NULL);
2841 }
2842
2843 /* Terrain names */
2844
2845 sec = secfile_sections_by_name_prefix(file, TERRAIN_SECTION_PREFIX);
2846 if (NULL == sec || 0 == (nval = section_list_size(sec))) {
2847 ruleset_error(NULL, LOG_ERROR,
2848 "\"%s\": ruleset doesn't have any terrains.",
2849 filename);
2850 ok = FALSE;
2851 } else {
2852 if (nval > MAX_NUM_TERRAINS) {
2853 ruleset_error(NULL, LOG_ERROR,
2854 "\"%s\": Too many terrains (%d, max %d)",
2855 filename, nval, MAX_NUM_TERRAINS);
2856 ok = FALSE;
2857 }
2858 }
2859 }
2860
2861 if (ok) {
2862 game.control.terrain_count = nval;
2863
2864 /* avoid re-reading files */
2865 if (terrain_sections) {
2866 free(terrain_sections);
2867 }
2868 terrain_sections = fc_calloc(nval, MAX_SECTION_LABEL);
2869
2870 terrain_type_iterate(pterrain) {
2871 const int terri = terrain_index(pterrain);
2872 const char *sec_name = section_name(section_list_get(sec, terri));
2873
2874 if (!ruleset_load_names(&pterrain->name, NULL, file, sec_name)) {
2875 ok = FALSE;
2876 break;
2877 }
2878
2879 section_strlcpy(&terrain_sections[terri * MAX_SECTION_LABEL], sec_name);
2880 } terrain_type_iterate_end;
2881 }
2882
2883 section_list_destroy(sec);
2884 sec = NULL;
2885
2886 /* extra names */
2887
2888 if (ok) {
2889 sec = secfile_sections_by_name_prefix(file, EXTRA_SECTION_PREFIX);
2890 nval = (NULL != sec ? section_list_size(sec) : 0);
2891 if (nval > MAX_EXTRA_TYPES) {
2892 ruleset_error(NULL, LOG_ERROR,
2893 "\"%s\": Too many extra types (%d, max %d)",
2894 filename, nval, MAX_EXTRA_TYPES);
2895 ok = FALSE;
2896 }
2897 }
2898
2899 if (ok) {
2900 int idx;
2901
2902 game.control.num_extra_types = nval;
2903
2904 if (extra_sections) {
2905 free(extra_sections);
2906 }
2907 extra_sections = fc_calloc(nval, MAX_SECTION_LABEL);
2908
2909 if (ok) {
2910 for (idx = 0; idx < nval; idx++) {
2911 const char *sec_name = section_name(section_list_get(sec, idx));
2912 struct extra_type *pextra = extra_by_number(idx);
2913
2914 if (!ruleset_load_names(&pextra->name, NULL, file, sec_name)) {
2915 ok = FALSE;
2916 break;
2917 }
2918 section_strlcpy(&extra_sections[idx * MAX_SECTION_LABEL], sec_name);
2919 }
2920 }
2921 }
2922
2923 section_list_destroy(sec);
2924 sec = NULL;
2925
2926 /* Base names */
2927
2928 if (ok) {
2929 sec = secfile_sections_by_name_prefix(file, BASE_SECTION_PREFIX);
2930 nval = (NULL != sec ? section_list_size(sec) : 0);
2931 if (nval > MAX_EXTRA_TYPES) {
2932 ruleset_error(NULL, LOG_ERROR,
2933 "\"%s\": Too many base types (%d, max %d)",
2934 filename, nval, MAX_EXTRA_TYPES);
2935 ok = FALSE;
2936 }
2937
2938 game.control.num_base_types = nval;
2939 }
2940
2941 if (ok) {
2942 int idx;
2943
2944 if (base_sections) {
2945 free(base_sections);
2946 }
2947 base_sections = fc_calloc(nval, MAX_SECTION_LABEL);
2948
2949 /* Cannot use base_type_iterate() before bases are added to
2950 * EC_BASE caused_by list. Have to get them by extra_type_by_rule_name() */
2951 for (idx = 0; idx < nval; idx++) {
2952 const char *sec_name = section_name(section_list_get(sec, idx));
2953 const char *base_name = secfile_lookup_str(file, "%s.extra", sec_name);
2954
2955 if (base_name != NULL) {
2956 struct extra_type *pextra = extra_type_by_rule_name(base_name);
2957
2958 if (pextra != NULL) {
2959 base_type_init(pextra, idx);
2960 section_strlcpy(&base_sections[idx * MAX_SECTION_LABEL], sec_name);
2961 } else {
2962 ruleset_error(NULL, LOG_ERROR,
2963 "No extra definition matching base definition \"%s\"",
2964 base_name);
2965 ok = FALSE;
2966 }
2967 } else {
2968 ruleset_error(NULL, LOG_ERROR,
2969 "Base section \"%s\" does not associate base with any extra",
2970 sec_name);
2971 ok = FALSE;
2972 }
2973 }
2974 }
2975
2976 section_list_destroy(sec);
2977 sec = NULL;
2978
2979 /* Road names */
2980
2981 if (ok) {
2982 sec = secfile_sections_by_name_prefix(file, ROAD_SECTION_PREFIX);
2983 nval = (NULL != sec ? section_list_size(sec) : 0);
2984 if (nval > MAX_EXTRA_TYPES) {
2985 ruleset_error(NULL, LOG_ERROR,
2986 "\"%s\": Too many road types (%d, max %d)",
2987 filename, nval, MAX_EXTRA_TYPES);
2988 ok = FALSE;
2989 }
2990
2991 game.control.num_road_types = nval;
2992 }
2993
2994 if (ok) {
2995 int idx;
2996
2997 if (road_sections) {
2998 free(road_sections);
2999 }
3000 road_sections = fc_calloc(nval, MAX_SECTION_LABEL);
3001
3002 /* Cannot use extra_type_by_cause_iterate(EC_ROAD) before roads are added to
3003 * EC_ROAD caused_by list. Have to get them by extra_type_by_rule_name() */
3004 for (idx = 0; idx < nval; idx++) {
3005 const char *sec_name = section_name(section_list_get(sec, idx));
3006 const char *road_name = secfile_lookup_str(file, "%s.extra", sec_name);
3007
3008 if (road_name != NULL) {
3009 struct extra_type *pextra = extra_type_by_rule_name(road_name);
3010
3011 if (pextra != NULL) {
3012 road_type_init(pextra, idx);
3013 section_strlcpy(&road_sections[idx * MAX_SECTION_LABEL], sec_name);
3014 } else {
3015 ruleset_error(NULL, LOG_ERROR,
3016 "No extra definition matching road definition \"%s\"",
3017 road_name);
3018 ok = FALSE;
3019 }
3020 } else {
3021 ruleset_error(NULL, LOG_ERROR,
3022 "Road section \"%s\" does not associate road with any extra",
3023 sec_name);
3024 ok = FALSE;
3025 }
3026 }
3027 }
3028
3029 section_list_destroy(sec);
3030 sec = NULL;
3031
3032 /* Resource names */
3033 if (ok) {
3034 sec = secfile_sections_by_name_prefix(file, RESOURCE_SECTION_PREFIX);
3035 nval = (NULL != sec ? section_list_size(sec) : 0);
3036 if (nval > MAX_EXTRA_TYPES) {
3037 ruleset_error(NULL, LOG_ERROR,
3038 "\"%s\": Too many resource types (%d, max %d)",
3039 filename, nval, MAX_EXTRA_TYPES);
3040 ok = FALSE;
3041 }
3042
3043 game.control.num_resource_types = nval;
3044 }
3045
3046 if (ok) {
3047 int idx;
3048
3049 if (resource_sections) {
3050 free(resource_sections);
3051 }
3052 resource_sections = fc_calloc(nval, MAX_SECTION_LABEL);
3053
3054 /* Cannot use resource_type_iterate() before resource are added to
3055 * EC_RESOURCE caused_by list. Have to get them by extra_type_by_rule_name() */
3056 for (idx = 0; idx < nval; idx++) {
3057 const char *sec_name = section_name(section_list_get(sec, idx));
3058 const char *resource_name;
3059 struct extra_type *pextra = NULL;
3060
3061 resource_name = secfile_lookup_str_default(file, NULL, "%s.extra", sec_name);
3062
3063 if (resource_name != NULL) {
3064 pextra = extra_type_by_rule_name(resource_name);
3065
3066 if (pextra != NULL) {
3067 resource_type_init(pextra);
3068 section_strlcpy(&resource_sections[idx * MAX_SECTION_LABEL], sec_name);
3069 } else {
3070 ruleset_error(NULL, LOG_ERROR,
3071 "No extra definition matching resource definition \"%s\"",
3072 resource_name);
3073 ok = FALSE;
3074 }
3075 } else {
3076 ruleset_error(NULL, LOG_ERROR,
3077 "Resource section %s does not list extra this resource belongs to.",
3078 sec_name);
3079 ok = FALSE;
3080 }
3081 }
3082 }
3083
3084 section_list_destroy(sec);
3085
3086 return ok;
3087}
3088
3089/**********************************************************************/
3092 static bool load_ruleset_terrain(struct section_file *file,
3093 struct rscompat_info *compat)
3094{
3095 size_t nval, nval2;
3096 int j;
3097 bool compat_road = FALSE;
3098 bool compat_rail = FALSE;
3099 bool compat_river = FALSE;
3100 const char **res;
3101 const char *filename = secfile_name(file);
3102 const char *text;
3103 int *res_freq;
3104 bool ok = TRUE;
3105
3106 /* parameters */
3107
3108 terrain_control.ocean_reclaim_requirement_pct
3109 = secfile_lookup_int_default(file, 101,
3110 "parameters.ocean_reclaim_requirement");
3111 terrain_control.land_channel_requirement_pct
3112 = secfile_lookup_int_default(file, 101,
3113 "parameters.land_channel_requirement");
3114 terrain_control.terrain_thaw_requirement_pct
3115 = secfile_lookup_int_default(file, 101,
3116 "parameters.thaw_requirement");
3117 terrain_control.terrain_freeze_requirement_pct
3118 = secfile_lookup_int_default(file, 101,
3119 "parameters.freeze_requirement");
3120 terrain_control.lake_max_size
3121 = secfile_lookup_int_default(file, 0,
3122 "parameters.lake_max_size");
3123 terrain_control.min_start_native_area
3124 = secfile_lookup_int_default(file, 0,
3125 "parameters.min_start_native_area");
3126 terrain_control.move_fragments
3127 = secfile_lookup_int_default(file, 3,
3128 "parameters.move_fragments");
3129 if (terrain_control.move_fragments < 1) {
3130 ruleset_error(NULL, LOG_ERROR,
3131 "\"%s\": move_fragments must be at least 1",
3132 filename);
3133 ok = FALSE;
3134 }
3135 init_move_fragments();
3136 terrain_control.igter_cost
3137 = secfile_lookup_int_default(file, 1,
3138 "parameters.igter_cost");
3139 if (terrain_control.igter_cost < 1) {
3140 ruleset_error(NULL, LOG_ERROR,
3141 "\"%s\": igter_cost must be at least 1",
3142 filename);
3143 ok = FALSE;
3144 }
3145 terrain_control.infrapoints = FALSE; /* This will be updated if we find
3146 * an placeable extra. */
3147
3148 terrain_control.pythagorean_diagonal
3149 = secfile_lookup_bool_default(file, RS_DEFAULT_PYTHAGOREAN_DIAGONAL,
3150 "parameters.pythagorean_diagonal");
3151
3152 wld.map.server.ocean_resources
3153 = secfile_lookup_bool_default(file, FALSE,
3154 "parameters.ocean_resources");
3155
3156 text = secfile_lookup_str_default(file,
3157 N_("?gui_type:Build Type A Base"),
3158 "extraui.ui_name_base_fortress");
3159 sz_strlcpy(terrain_control.gui_type_base0, text);
3160
3161 text = secfile_lookup_str_default(file,
3162 N_("?gui_type:Build Type B Base"),
3163 "extraui.ui_name_base_airbase");
3164 sz_strlcpy(terrain_control.gui_type_base1, text);
3165
3166 if (ok) {
3167 /* Terrain details */
3168
3169 terrain_type_iterate(pterrain) {
3170 const char **slist;
3171 const int i = terrain_index(pterrain);
3172 const char *tsection = &terrain_sections[i * MAX_SECTION_LABEL];
3173 const char *cstr;
3174 const char *ename;
3175
3176 sz_strlcpy(pterrain->graphic_str,
3177 secfile_lookup_str(file, "%s.graphic", tsection));
3178 sz_strlcpy(pterrain->graphic_alt,
3179 secfile_lookup_str_default(file, "-",
3180 "%s.graphic_alt", tsection));
3181 sz_strlcpy(pterrain->graphic_alt2,
3182 secfile_lookup_str_default(file, "-",
3183 "%s.graphic_alt2", tsection));
3184
3185 pterrain->identifier
3186 = secfile_lookup_str(file, "%s.identifier", tsection)[0];
3187 if ('\0' == pterrain->identifier) {
3188 ruleset_error(NULL, LOG_ERROR,
3189 "\"%s\" [%s] identifier missing value.",
3190 filename, tsection);
3191 ok = FALSE;
3192 break;
3193 }
3194 if (TERRAIN_UNKNOWN_IDENTIFIER == pterrain->identifier) {
3195 ruleset_error(NULL, LOG_ERROR,
3196 "\"%s\" [%s] cannot use '%c' as an identifier;"
3197 " it is reserved for unknown terrain.",
3198 filename, tsection, pterrain->identifier);
3199 ok = FALSE;
3200 break;
3201 }
3202 for (j = T_FIRST; j < i; j++) {
3203 if (pterrain->identifier == terrain_by_number(j)->identifier) {
3204 ruleset_error(NULL, LOG_ERROR,
3205 "\"%s\" [%s] has the same identifier as [%s].",
3206 filename, tsection,
3207 &terrain_sections[j * MAX_SECTION_LABEL]);
3208 ok = FALSE;
3209 break;
3210 }
3211 }
3212
3213 if (!ok) {
3214 break;
3215 }
3216
3217 cstr = secfile_lookup_str(file, "%s.class", tsection);
3218 pterrain->tclass = terrain_class_by_name(cstr, fc_strcasecmp);
3219 if (!terrain_class_is_valid(pterrain->tclass)) {
3220 ruleset_error(NULL, LOG_ERROR,
3221 "\"%s\": [%s] unknown class \"%s\"",
3222 filename, tsection, cstr);
3223 ok = FALSE;
3224 break;
3225 }
3226
3227 if (!secfile_lookup_int(file, &pterrain->movement_cost,
3228 "%s.movement_cost", tsection)
3229 || !secfile_lookup_int(file, &pterrain->defense_bonus,
3230 "%s.defense_bonus", tsection)) {
3231 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
3232 ok = FALSE;
3233 break;
3234 }
3235
3236 output_type_iterate(o) {
3237 pterrain->output[o]
3238 = secfile_lookup_int_default(file, 0, "%s.%s", tsection,
3239 get_output_identifier(o));
3240 } output_type_iterate_end;
3241
3242 res = secfile_lookup_str_vec(file, &nval, "%s.resources", tsection);
3243 res_freq = secfile_lookup_int_vec(file, &nval2,
3244 "%s.resource_freq", tsection);
3245 if (nval2 > 0 && nval2 != nval) {
3246 ruleset_error(NULL, LOG_ERROR,
3247 "\"%s\": [%s] Different lengths for resources "
3248 "and resource frequencies",
3249 filename, tsection);
3250 ok = FALSE;
3251 }
3252 pterrain->resources = fc_calloc(nval + 1, sizeof(*pterrain->resources));
3253 pterrain->resource_freq = fc_calloc(nval + 1,
3254 sizeof(*pterrain->resource_freq));
3255 for (j = 0; j < nval; j++) {
3256 pterrain->resources[j] = lookup_resource(filename, res[j], tsection);
3257 if (pterrain->resources[j] == NULL) {
3258 ok = FALSE;
3259 break;
3260 }
3261 pterrain->resource_freq[j] = j < nval2
3262 ? res_freq[j]
3263 : RESOURCE_FREQUENCY_DEFAULT;
3264 if (pterrain->resource_freq[j] < RESOURCE_FREQUENCY_MINIMUM
3265 || pterrain->resource_freq[j] > RESOURCE_FREQUENCY_MAXIMUM) {
3266 ruleset_error(NULL, LOG_ERROR,
3267 "\"%s\": [%s] Resource frequency '%d' "
3268 "outside allowed range",
3269 filename, tsection,
3270 pterrain->resource_freq[j]);
3271 ok = FALSE;
3272 break;
3273 }
3274 }
3275 pterrain->resources[nval] = NULL;
3276 /* Terminating zero technically not necessary */
3277 pterrain->resource_freq[nval] = 0;
3278 free(res);
3279 res = NULL;
3280 free(res_freq);
3281 res_freq = NULL;
3282
3283 if (!ok) {
3284 break;
3285 }
3286
3287 output_type_iterate(o) {
3288 pterrain->road_output_incr_pct[o]
3289 = secfile_lookup_int_default(file, 0, "%s.road_%s_incr_pct",
3290 tsection, get_output_identifier(o));
3291 } output_type_iterate_end;
3292
3293 if (!lookup_time(file, &pterrain->base_time, tsection, "base_time",
3294 filename, NULL, &ok)
3295 || !lookup_time(file, &pterrain->road_time, tsection, "road_time",
3296 filename, NULL, &ok)) {
3297 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
3298 ok = FALSE;
3299 break;
3300 }
3301
3302 if (!lookup_terrain(file, "cultivate_result", filename, pterrain,
3303 &pterrain->cultivate_result, FALSE)) {
3304 ruleset_error(NULL, LOG_ERROR, "%s: No cultivate_result", tsection);
3305 ok = FALSE;
3306 break;
3307 }
3308 if (pterrain->cultivate_result == pterrain) {
3309 ruleset_error(NULL, LOG_ERROR,
3310 "%s: Cultivating result in terrain itself.",
3311 tsection);
3312 ok = FALSE;
3313 break;
3314 }
3315 if (!secfile_lookup_int(file, &pterrain->irrigation_food_incr,
3316 "%s.irrigation_food_incr", tsection)
3317 || !lookup_time(file, &pterrain->irrigation_time,
3318 tsection, "irrigation_time", filename, NULL, &ok)) {
3319 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
3320 ok = FALSE;
3321 break;
3322 }
3323
3324 if (!lookup_terrain(file, "plant_result", filename, pterrain,
3325 &pterrain->plant_result, FALSE)) {
3326 ruleset_error(NULL, LOG_ERROR, "%s: No plant_result", tsection);
3327 ok = FALSE;
3328 break;
3329 }
3330 if (pterrain->plant_result == pterrain) {
3331 ruleset_error(NULL, LOG_ERROR,
3332 "%s: Planting result in terrain itself.",
3333 tsection);
3334 ok = FALSE;
3335 break;
3336 }
3337 if (!secfile_lookup_int(file, &pterrain->mining_shield_incr,
3338 "%s.mining_shield_incr", tsection)
3339 || !lookup_time(file, &pterrain->mining_time,
3340 tsection, "mining_time", filename, NULL, &ok)) {
3341 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
3342 ok = FALSE;
3343 break;
3344 }
3345
3346 if (!lookup_time(file, &pterrain->cultivate_time,
3347 tsection, "cultivate_time", filename, NULL, &ok)) {
3348 ruleset_error(NULL, LOG_ERROR,
3349 "%s: Missing cultivate_time", tsection);
3350 ok = FALSE;
3351 break;
3352 }
3353 if ((pterrain->cultivate_result != NULL
3354 && pterrain->cultivate_time <= 0)
3355 || (pterrain->cultivate_result == NULL
3356 && pterrain->cultivate_time > 0)) {
3357 ruleset_error(NULL, LOG_ERROR,
3358 "%s: cultivate_result and cultivate_time disagree "
3359 "whether cultivating is enabled", tsection);
3360 ok = FALSE;
3361 break;
3362 }
3363
3364 if (!lookup_time(file, &pterrain->plant_time,
3365 tsection, "plant_time", filename, NULL, &ok)) {
3366 ruleset_error(NULL, LOG_ERROR,
3367 "%s: Missing plant_time", tsection);
3368 ok = FALSE;
3369 break;
3370 }
3371 if ((pterrain->plant_result != NULL
3372 && pterrain->plant_time <= 0)
3373 || (pterrain->plant_result == NULL
3374 && pterrain->plant_time > 0)) {
3375 ruleset_error(NULL, LOG_ERROR,
3376 "%s: plant_result and plant_time disagree "
3377 "whether planting is enabled", tsection);
3378 ok = FALSE;
3379 break;
3380 }
3381
3382 if (!lookup_unit_type(file, tsection, "animal",
3383 &pterrain->animal, filename,
3384 rule_name_get(&pterrain->name))) {
3385 ok = FALSE;
3386 break;
3387 }
3388
3389 if (!lookup_terrain(file, "transform_result", filename, pterrain,
3390 &pterrain->transform_result, TRUE)) {
3391 ok = FALSE;
3392 break;
3393 }
3394 if (!lookup_time(file, &pterrain->transform_time,
3395 tsection, "transform_time", filename, NULL, &ok)) {
3396 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
3397 ok = FALSE;
3398 break;
3399 }
3400 if ((pterrain->transform_result != NULL
3401 && pterrain->transform_time <= 0)
3402 || (pterrain->transform_result == NULL
3403 && pterrain->transform_time > 0)) {
3404 ruleset_error(NULL, LOG_ERROR,
3405 "%s: transform_result and transform_time disagree "
3406 "whether transforming is enabled", tsection);
3407 ok = FALSE;
3408 break;
3409 }
3410
3411 pterrain->placing_time = 1; /* Default */
3412 lookup_time(file, &pterrain->placing_time,
3413 tsection, "placing_time", filename, NULL, &ok);
3414
3415 pterrain->pillage_time = 1; /* Default */
3416 lookup_time(file, &pterrain->pillage_time,
3417 tsection, "pillage_time", filename, NULL, &ok);
3418
3419 if (!lookup_terrain(file, "warmer_wetter_result", filename, pterrain,
3420 &pterrain->warmer_wetter_result, TRUE)
3421 || !lookup_terrain(file, "warmer_drier_result", filename, pterrain,
3422 &pterrain->warmer_drier_result, TRUE)
3423 || !lookup_terrain(file, "cooler_wetter_result", filename, pterrain,
3424 &pterrain->cooler_wetter_result, TRUE)
3425 || !lookup_terrain(file, "cooler_drier_result", filename, pterrain,
3426 &pterrain->cooler_drier_result, TRUE)) {
3427 ok = FALSE;
3428 break;
3429 }
3430
3431 /* Set default removal times */
3432 extra_type_iterate(pextra) {
3433 pterrain->extra_removal_times[extra_index(pextra)] = 0;
3434 } extra_type_iterate_end;
3435
3436 for (j = 0; (ename = secfile_lookup_str_default(file, NULL,
3437 "%s.extra_settings%d.extra",
3438 tsection, j)); j++) {
3439 const struct extra_type *pextra = extra_type_by_rule_name(ename);
3440
3441 if (pextra != NULL) {
3442 char time_sections[512];
3443
3444 fc_snprintf(time_sections, sizeof(time_sections),
3445 "%s.extra_settings%d", tsection, j);
3446
3447 lookup_time(file, &pterrain->extra_removal_times[extra_index(pextra)],
3448 time_sections, "removal_time", filename, NULL, &ok);
3449 } else {
3450 ruleset_error(NULL, LOG_ERROR,
3451 "\"%s\" [%s] has settings for unknown extra \"%s\".",
3452 filename, tsection, ename);
3453 ok = FALSE;
3454 break;
3455 }
3456 }
3457
3458 if (ok) {
3459 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", tsection);
3460 BV_CLR_ALL(pterrain->flags);
3461 for (j = 0; j < nval; j++) {
3462 const char *sval = slist[j];
3463 enum terrain_flag_id flag
3464 = terrain_flag_id_by_name(sval, fc_strcasecmp);
3465
3466 if (!terrain_flag_id_is_valid(flag)) {
3467 ruleset_error(NULL, LOG_ERROR,
3468 "\"%s\" [%s] has unknown flag \"%s\".",
3469 filename, tsection, sval);
3470 ok = FALSE;
3471 break;
3472 } else {
3473 BV_SET(pterrain->flags, flag);
3474 }
3475 }
3476
3477 free(slist);
3478 }
3479
3480 if (!ok) {
3481 break;
3482 }
3483
3484 {
3485 enum mapgen_terrain_property mtp;
3486
3487 for (mtp = mapgen_terrain_property_begin();
3488 mtp != mapgen_terrain_property_end();
3489 mtp = mapgen_terrain_property_next(mtp)) {
3490 pterrain->property[mtp]
3491 = secfile_lookup_int_default(file, 0, "%s.property_%s", tsection,
3492 mapgen_terrain_property_name(mtp));
3493 }
3494 }
3495
3496 slist = secfile_lookup_str_vec(file, &nval, "%s.native_to", tsection);
3497 BV_CLR_ALL(pterrain->native_to);
3498 for (j = 0; j < nval; j++) {
3499 struct unit_class *class = unit_class_by_rule_name(slist[j]);
3500
3501 if (!class) {
3502 ruleset_error(NULL, LOG_ERROR,
3503 "\"%s\" [%s] is native to unknown unit class \"%s\".",
3504 filename, tsection, slist[j]);
3505 ok = FALSE;
3506 break;
3507 } else {
3508 BV_SET(pterrain->native_to, uclass_index(class));
3509 }
3510 }
3511 free(slist);
3512
3513 if (!ok) {
3514 break;
3515 }
3516
3517 /* Get terrain color */
3518 {
3519 fc_assert_ret_val(pterrain->rgb == NULL, FALSE);
3520
3521 if (!rgbcolor_load(file, &pterrain->rgb, "%s.color", tsection)) {
3522 ruleset_error(NULL, LOG_ERROR,
3523 "Missing terrain color definition: %s",
3524 secfile_error());
3525 ok = FALSE;
3526 break;
3527 }
3528 }
3529
3530 pterrain->helptext = lookup_strvec(file, tsection, "helptext");
3531 } terrain_type_iterate_end;
3532 }
3533
3534 if (ok) {
3535 /* Extra details */
3536 extra_type_iterate(pextra) {
3537 BV_CLR_ALL(pextra->conflicts);
3538 } extra_type_iterate_end;
3539
3540 extra_type_iterate(pextra) {
3541 int eidx = extra_index(pextra);
3542 const char *section = &extra_sections[eidx * MAX_SECTION_LABEL];
3543 const char **slist;
3544 struct requirement_vector *reqs;
3545 const char *catname;
3546 int cj;
3547 enum extra_cause cause;
3548 enum extra_rmcause rmcause;
3549 const char *eus_name;
3550 const char *vis_req_name;
3551 const struct advance *vis_req;
3552
3553 catname = secfile_lookup_str(file, "%s.category", section);
3554 if (catname == NULL) {
3555 ruleset_error(NULL, LOG_ERROR,
3556 "\"%s\" extra \"%s\" has no category.",
3557 filename, extra_rule_name(pextra));
3558 ok = FALSE;
3559 break;
3560 }
3561 pextra->category = extra_category_by_name(catname, fc_strcasecmp);
3562 if (!extra_category_is_valid(pextra->category)) {
3563 ruleset_error(NULL, LOG_ERROR,
3564 "\"%s\" extra \"%s\" has invalid category \"%s\".",
3565 filename, extra_rule_name(pextra), catname);
3566 ok = FALSE;
3567 break;
3568 }
3569
3570 slist = secfile_lookup_str_vec(file, &nval, "%s.causes", section);
3571 pextra->causes = 0;
3572 for (cj = 0; cj < nval; cj++) {
3573 const char *sval = slist[cj];
3574 cause = extra_cause_by_name(sval, fc_strcasecmp);
3575
3576 if (!extra_cause_is_valid(cause)) {
3577 ruleset_error(NULL, LOG_ERROR,
3578 "\"%s\" extra \"%s\": unknown cause \"%s\".",
3579 filename, extra_rule_name(pextra), sval);
3580 ok = FALSE;
3581 break;
3582 } else {
3583 pextra->causes |= (1 << cause);
3584 extra_to_caused_by_list(pextra, cause);
3585 }
3586 }
3587
3588 if (pextra->causes == 0) {
3589 /* Extras that do not have any causes added to EC_NONE list */
3590 extra_to_caused_by_list(pextra, EC_NONE);
3591 }
3592
3593 if (!is_extra_caused_by(pextra, EC_BASE)
3594 && !is_extra_caused_by(pextra, EC_ROAD)
3595 && !is_extra_caused_by(pextra, EC_RESOURCE)) {
3596 /* Not a base, road, nor resource, so special */
3597 pextra->data.special_idx = extra_type_list_size(extra_type_list_by_cause(EC_SPECIAL));
3598 extra_to_caused_by_list(pextra, EC_SPECIAL);
3599 }
3600
3601 free(slist);
3602
3603 slist = secfile_lookup_str_vec(file, &nval, "%s.rmcauses", section);
3604 pextra->rmcauses = 0;
3605 for (j = 0; j < nval; j++) {
3606 const char *sval = slist[j];
3607
3608 rmcause = extra_rmcause_by_name(sval, fc_strcasecmp);
3609
3610 if (!extra_rmcause_is_valid(rmcause)) {
3611 ruleset_error(NULL, LOG_ERROR,
3612 "\"%s\" extra \"%s\": unknown rmcause \"%s\".",
3613 filename, extra_rule_name(pextra), sval);
3614 ok = FALSE;
3615 break;
3616 } else {
3617 pextra->rmcauses |= (1 << rmcause);
3618 extra_to_removed_by_list(pextra, rmcause);
3619 }
3620 }
3621
3622 free(slist);
3623
3624 sz_strlcpy(pextra->activity_gfx,
3625 secfile_lookup_str_default(file, "-",
3626 "%s.activity_gfx", section));
3627 sz_strlcpy(pextra->act_gfx_alt,
3628 secfile_lookup_str_default(file, "-",
3629 "%s.act_gfx_alt", section));
3630 sz_strlcpy(pextra->act_gfx_alt2,
3631 secfile_lookup_str_default(file, "-",
3632 "%s.act_gfx_alt2", section));
3633 sz_strlcpy(pextra->rmact_gfx,
3634 secfile_lookup_str_default(file, "-",
3635 "%s.rmact_gfx", section));
3636 sz_strlcpy(pextra->rmact_gfx_alt,
3637 secfile_lookup_str_default(file, "-",
3638 "%s.rmact_gfx_alt", section));
3639 sz_strlcpy(pextra->rmact_gfx_alt2,
3640 secfile_lookup_str_default(file, "-",
3641 "%s.rmact_gfx_alt2", section));
3642 sz_strlcpy(pextra->graphic_str,
3643 secfile_lookup_str_default(file, "-", "%s.graphic", section));
3644 sz_strlcpy(pextra->graphic_alt,
3645 secfile_lookup_str_default(file, "-",
3646 "%s.graphic_alt", section));
3647
3648 reqs = lookup_req_list(file, compat, section, "reqs", extra_rule_name(pextra));
3649 if (reqs == NULL) {
3650 ok = FALSE;
3651 break;
3652 }
3653 requirement_vector_copy(&pextra->reqs, reqs);
3654
3655 reqs = lookup_req_list(file, compat, section, "rmreqs", extra_rule_name(pextra));
3656 if (reqs == NULL) {
3657 ok = FALSE;
3658 break;
3659 }
3660 requirement_vector_copy(&pextra->rmreqs, reqs);
3661
3662 reqs = lookup_req_list(file, compat, section, "appearance_reqs", extra_rule_name(pextra));
3663 if (reqs == NULL) {
3664 ok = FALSE;
3665 break;
3666 }
3667 requirement_vector_copy(&pextra->appearance_reqs, reqs);
3668
3669 reqs = lookup_req_list(file, compat, section, "disappearance_reqs", extra_rule_name(pextra));
3670 if (reqs == NULL) {
3671 ok = FALSE;
3672 break;
3673 }
3674 requirement_vector_copy(&pextra->disappearance_reqs, reqs);
3675
3676 pextra->buildable = secfile_lookup_bool_default(file,
3677 is_extra_caused_by_worker_action(pextra),
3678 "%s.buildable", section);
3679 pextra->generated = secfile_lookup_bool_default(file, TRUE,
3680 "%s.generated", section);
3681
3682 pextra->build_time = 0; /* default */
3683 lookup_time(file, &pextra->build_time, section, "build_time",
3684 filename, extra_rule_name(pextra), &ok);
3685 pextra->build_time_factor = secfile_lookup_int_default(file, 1,
3686 "%s.build_time_factor", section);
3687 pextra->removal_time = 0; /* default */
3688 lookup_time(file, &pextra->removal_time, section, "removal_time",
3689 filename, extra_rule_name(pextra), &ok);
3690 pextra->removal_time_factor = secfile_lookup_int_default(file, 1,
3691 "%s.removal_time_factor", section);
3692 pextra->infracost = secfile_lookup_int_default(file, 0,
3693 "%s.infracost", section);
3694 if (pextra->infracost > 0) {
3695 terrain_control.infrapoints = TRUE;
3696 }
3697
3698 pextra->defense_bonus = secfile_lookup_int_default(file, 0,
3699 "%s.defense_bonus",
3700 section);
3701 if (pextra->defense_bonus != 0) {
3702 if (extra_has_flag(pextra, EF_NATURAL_DEFENSE)) {
3703 extra_to_caused_by_list(pextra, EC_NATURAL_DEFENSIVE);
3704 } else {
3705 extra_to_caused_by_list(pextra, EC_DEFENSIVE);
3706 }
3707 }
3708
3709 eus_name = secfile_lookup_str_default(file, "Normal", "%s.unit_seen", section);
3710 pextra->eus = extra_unit_seen_type_by_name(eus_name, fc_strcasecmp);
3711 if (!extra_unit_seen_type_is_valid(pextra->eus)) {
3712 ruleset_error(NULL, LOG_ERROR,
3713 "\"%s\" extra \"%s\" has illegal unit_seen value \"%s\".",
3714 filename, extra_rule_name(pextra), eus_name);
3715 ok = FALSE;
3716 break;
3717 }
3718 if (pextra->eus == EUS_HIDDEN) {
3719 extra_type_list_append(extra_type_list_of_unit_hiders(), pextra);
3720 }
3721
3722 pextra->appearance_chance = secfile_lookup_int_default(file, RS_DEFAULT_EXTRA_APPEARANCE,
3723 "%s.appearance_chance",
3724 section);
3725 pextra->disappearance_chance = secfile_lookup_int_default(file,
3726 RS_DEFAULT_EXTRA_DISAPPEARANCE,
3727 "%s.disappearance_chance",
3728 section);
3729
3730 pextra->no_aggr_near_city = secfile_lookup_int_default(file, -1,
3731 "%s.no_aggr_near_city",
3732 section);
3733
3734 slist = secfile_lookup_str_vec(file, &nval, "%s.native_to", section);
3735 BV_CLR_ALL(pextra->native_to);
3736 for (j = 0; j < nval; j++) {
3737 struct unit_class *uclass = unit_class_by_rule_name(slist[j]);
3738
3739 if (uclass == NULL) {
3740 ruleset_error(NULL, LOG_ERROR,
3741 "\"%s\" extra \"%s\" is native to unknown unit class \"%s\".",
3742 filename, extra_rule_name(pextra), slist[j]);
3743 ok = FALSE;
3744 break;
3745 } else {
3746 BV_SET(pextra->native_to, uclass_index(uclass));
3747 }
3748 }
3749 free(slist);
3750
3751 if (!ok) {
3752 break;
3753 }
3754
3755 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", section);
3756 BV_CLR_ALL(pextra->flags);
3757 for (j = 0; j < nval; j++) {
3758 const char *sval = slist[j];
3759 enum extra_flag_id flag;
3760
3761 flag = extra_flag_id_by_name(sval, fc_strcasecmp);
3762
3763 if (!extra_flag_id_is_valid(flag)) {
3764 ruleset_error(NULL, LOG_ERROR,
3765 "\"%s\" extra \"%s\": unknown flag \"%s\".",
3766 filename, extra_rule_name(pextra), sval);
3767 ok = FALSE;
3768 break;
3769 } else {
3770 BV_SET(pextra->flags, flag);
3771 }
3772 }
3773 free(slist);
3774
3775 if (pextra->no_aggr_near_city >= 0) {
3776 extra_to_caused_by_list(pextra, EC_NOT_AGGRESSIVE);
3777 }
3778
3779 if (extra_has_flag(pextra, EF_CAUSE_ZOC)) {
3780 extra_type_list_append(extra_type_list_of_zoccers(), pextra);
3781 }
3782
3783 if (!ok) {
3784 break;
3785 }
3786
3787 slist = secfile_lookup_str_vec(file, &nval, "%s.conflicts", section);
3788 for (j = 0; j < nval; j++) {
3789 const char *sval = slist[j];
3790 struct extra_type *pextra2 = extra_type_by_rule_name(sval);
3791
3792 if (pextra2 == NULL) {
3793 ruleset_error(NULL, LOG_ERROR,
3794 "\"%s\" extra \"%s\": unknown conflict extra \"%s\".",
3795 filename, extra_rule_name(pextra), sval);
3796 ok = FALSE;
3797 break;
3798 } else {
3799 BV_SET(pextra->conflicts, extra_index(pextra2));
3800 BV_SET(pextra2->conflicts, extra_index(pextra));
3801 }
3802 }
3803
3804 free(slist);
3805
3806 if (!ok) {
3807 break;
3808 }
3809
3810 slist = secfile_lookup_str_vec(file, &nval, "%s.hidden_by", section);
3811 BV_CLR_ALL(pextra->hidden_by);
3812 for (j = 0; j < nval; j++) {
3813 const char *sval = slist[j];
3814 const struct extra_type *top = extra_type_by_rule_name(sval);
3815
3816 if (top == NULL) {
3817 ruleset_error(NULL, LOG_ERROR,
3818 "\"%s\" extra \"%s\" hidden by unknown extra \"%s\".",
3819 filename, extra_rule_name(pextra), sval);
3820 ok = FALSE;
3821 break;
3822 } else {
3823 BV_SET(pextra->hidden_by, extra_index(top));
3824 }
3825 }
3826 free(slist);
3827
3828 if (!ok) {
3829 break;
3830 }
3831
3832 slist = secfile_lookup_str_vec(file, &nval, "%s.bridged_over", section);
3833 BV_CLR_ALL(pextra->bridged_over);
3834 for (j = 0; j < nval; j++) {
3835 const char *sval = slist[j];
3836 const struct extra_type *top = extra_type_by_rule_name(sval);
3837
3838 if (top == NULL) {
3839 ruleset_error(NULL, LOG_ERROR,
3840 "\"%s\" extra \"%s\" bridged over unknown extra \"%s\".",
3841 filename, extra_rule_name(pextra), sval);
3842 ok = FALSE;
3843 break;
3844 } else {
3845 BV_SET(pextra->bridged_over, extra_index(top));
3846 }
3847 }
3848 free(slist);
3849
3850 if (!ok) {
3851 break;
3852 }
3853
3854 vis_req_name = secfile_lookup_str_default(file, "None",
3855 "%s.visibility_req", section);
3856 vis_req = advance_by_rule_name(vis_req_name);
3857
3858 if (vis_req == NULL) {
3859 ruleset_error(NULL, LOG_ERROR,
3860 "\"%s\" %s: unknown visibility_req %s.",
3861 filename, section, vis_req_name);
3862 ok = FALSE;
3863 break;
3864 }
3865
3866 pextra->visibility_req = advance_number(vis_req);
3867
3868 pextra->helptext = lookup_strvec(file, section, "helptext");
3869 } extra_type_iterate_end;
3870 }
3871
3872 if (ok) {
3873 int i = 0;
3874 /* Resource details */
3875
3876 extra_type_by_cause_iterate(EC_RESOURCE, presource) {
3877 char identifier[MAX_LEN_NAME];
3878 const char *id;
3879 const char *rsection = &resource_sections[i * MAX_SECTION_LABEL];
3880
3881 if (!presource->data.resource) {
3882 ruleset_error(NULL, LOG_ERROR,
3883 "\"%s\" extra \"%s\" has \"Resource\" cause but no "
3884 "corresponding [resource_*] section",
3885 filename, extra_rule_name(presource));
3886 ok = FALSE;
3887 break;
3888 }
3889
3890 output_type_iterate (o) {
3891 presource->data.resource->output[o] =
3892 secfile_lookup_int_default(file, 0, "%s.%s", rsection,
3893 get_output_identifier(o));
3894 } output_type_iterate_end;
3895
3896 id = secfile_lookup_str_default(file, NULL, "%s.identifier", rsection);
3897
3898 if (id == NULL) {
3899 presource->data.resource->id_old_save = '\0';
3900 } else {
3901 sz_strlcpy(identifier, id);
3902
3903 presource->data.resource->id_old_save = identifier[0];
3904 if (RESOURCE_NULL_IDENTIFIER == presource->data.resource->id_old_save) {
3905 ruleset_error(NULL, LOG_ERROR,
3906 "\"%s\" [%s] identifier missing value.",
3907 filename, rsection);
3908 ok = FALSE;
3909 break;
3910 }
3911 if (RESOURCE_NONE_IDENTIFIER == presource->data.resource->id_old_save) {
3912 ruleset_error(NULL, LOG_ERROR,
3913 "\"%s\" [%s] cannot use '%c' as an identifier;"
3914 " it is reserved.",
3915 filename, rsection, presource->data.resource->id_old_save);
3916 ok = FALSE;
3917 break;
3918 }
3919 }
3920
3921 if (!ok) {
3922 break;
3923 }
3924
3925 i++;
3926 } extra_type_by_cause_iterate_end;
3927
3928 for (j = 0; ok && j < game.control.num_resource_types; j++) {
3929 const char *section = &resource_sections[j * MAX_SECTION_LABEL];
3930 const char *extra_name = secfile_lookup_str(file, "%s.extra", section);
3931 struct extra_type *pextra = extra_type_by_rule_name(extra_name);
3932
3933 if (!is_extra_caused_by(pextra, EC_RESOURCE)) {
3934 ruleset_error(NULL, LOG_ERROR,
3935 "\"%s\" resource section [%s]: extra \"%s\" does not "
3936 "have \"Resource\" in its causes",
3937 filename, section, extra_name);
3938 ok = FALSE;
3939 }
3940 }
3941 }
3942
3943 if (ok) {
3944 /* This can't be part of previous loop as we don't want random data from previous
3945 * ruleset to play havoc on us when we have only some resource identifiers loaded
3946 * from the new ruleset. */
3947 extra_type_by_cause_iterate(EC_RESOURCE, pres) {
3948 if (pres->data.resource->id_old_save != '\0') {
3949 extra_type_by_cause_iterate(EC_RESOURCE, pres2) {
3950 if (pres->data.resource->id_old_save == pres2->data.resource->id_old_save
3951 && pres != pres2) {
3952 ruleset_error(NULL, LOG_ERROR,
3953 "\"%s\" [%s] has the same identifier as [%s].",
3954 filename,
3955 extra_rule_name(pres),
3956 extra_rule_name(pres2));
3957 ok = FALSE;
3958 break;
3959 }
3960 } extra_type_by_cause_iterate_end;
3961
3962 if (!ok) {
3963 break;
3964 }
3965 }
3966 } extra_type_by_cause_iterate_end;
3967 }
3968
3969 if (ok) {
3970 /* Base details */
3971 extra_type_by_cause_iterate(EC_BASE, pextra) {
3972 struct base_type *pbase = extra_base_get(pextra);
3973 const char *section;
3974 const char *gui_str;
3975
3976 if (!pbase) {
3977 ruleset_error(NULL, LOG_ERROR,
3978 "\"%s\" extra \"%s\" has \"Base\" cause but no "
3979 "corresponding [base_*] section",
3980 filename, extra_rule_name(pextra));
3981 ok = FALSE;
3982 break;
3983 }
3984 section = &base_sections[base_number(pbase) * MAX_SECTION_LABEL];
3985
3986 gui_str = secfile_lookup_str(file, "%s.gui_type", section);
3987 pbase->gui_type = base_gui_type_by_name(gui_str, fc_strcasecmp);
3988 if (!base_gui_type_is_valid(pbase->gui_type)) {
3989 ruleset_error(NULL, LOG_ERROR,
3990 "\"%s\" base \"%s\": unknown gui_type \"%s\".",
3991 filename, extra_rule_name(pextra), gui_str);
3992 ok = FALSE;
3993 break;
3994 }
3995
3996 pbase->border_sq = secfile_lookup_int_default(file, -1, "%s.border_sq",
3997 section);
3998 pbase->vision_main_sq = secfile_lookup_int_default(file, -1,
3999 "%s.vision_main_sq",
4000 section);
4001 pbase->vision_invis_sq = secfile_lookup_int_default(file, -1,
4002 "%s.vision_invis_sq",
4003 section);
4004 pbase->vision_subs_sq = secfile_lookup_int_default(file, -1,
4005 "%s.vision_subs_sq",
4006 section);
4007
4008 if (!ok) {
4009 break;
4010 }
4011
4012 if (territory_claiming_base(pbase)) {
4013 extra_type_list_append(extra_type_list_of_terr_claimers(), pextra);
4014
4015 extra_type_by_cause_iterate(EC_BASE, pextra2) {
4016 struct base_type *pbase2;
4017
4018 if (pextra == pextra2) {
4019 /* End of the fully initialized bases iteration. */
4020 break;
4021 }
4022
4023 pbase2 = extra_base_get(pextra2);
4024 if (territory_claiming_base(pbase2)) {
4025 BV_SET(pextra->conflicts, extra_index(pextra2));
4026 BV_SET(pextra2->conflicts, extra_index(pextra));
4027 }
4028 } extra_type_by_cause_iterate_end;
4029 }
4030 } extra_type_by_cause_iterate_end;
4031
4032 for (j = 0; ok && j < game.control.num_base_types; j++) {
4033 const char *section = &base_sections[j * MAX_SECTION_LABEL];
4034 const char *extra_name = secfile_lookup_str(file, "%s.extra", section);
4035 struct extra_type *pextra = extra_type_by_rule_name(extra_name);
4036
4037 if (!is_extra_caused_by(pextra, EC_BASE)) {
4038 ruleset_error(NULL, LOG_ERROR,
4039 "\"%s\" base section [%s]: extra \"%s\" does not have "
4040 "\"Base\" in its causes",
4041 filename, section, extra_name);
4042 ok = FALSE;
4043 }
4044 }
4045 }
4046
4047 if (ok) {
4048 extra_type_by_cause_iterate(EC_ROAD, pextra) {
4049 struct road_type *proad = extra_road_get(pextra);
4050 const char *section;
4051 const char **slist;
4052 const char *special;
4053 const char *modestr;
4054 struct requirement_vector *reqs;
4055 const char *gui_str;
4056
4057 if (!proad) {
4058 ruleset_error(NULL, LOG_ERROR,
4059 "\"%s\" extra \"%s\" has \"Road\" cause but no "
4060 "corresponding [road_*] section",
4061 filename, extra_rule_name(pextra));
4062 ok = FALSE;
4063 break;
4064 }
4065 section = &road_sections[road_number(proad) * MAX_SECTION_LABEL];
4066
4067 gui_str = secfile_lookup_str(file, "%s.gui_type", section);
4068 proad->gui_type = road_gui_type_by_name(gui_str, fc_strcasecmp);
4069 if (!road_gui_type_is_valid(proad->gui_type)) {
4070 ruleset_error(NULL, LOG_ERROR,
4071 "\"%s\" road \"%s\": unknown gui_type \"%s\".",
4072 filename, extra_rule_name(pextra), gui_str);
4073 ok = FALSE;
4074 break;
4075 }
4076
4077 reqs = lookup_req_list(file, compat, section, "first_reqs", extra_rule_name(pextra));
4078 if (reqs == NULL) {
4079 ok = FALSE;
4080 break;
4081 }
4082 requirement_vector_copy(&proad->first_reqs, reqs);
4083
4084 if (!secfile_lookup_int(file, &proad->move_cost,
4085 "%s.move_cost", section)) {
4086 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4087 ok = FALSE;
4088 break;
4089 }
4090
4091 modestr = secfile_lookup_str_default(file, "FastAlways", "%s.move_mode",
4092 section);
4093 proad->move_mode = road_move_mode_by_name(modestr, fc_strcasecmp);
4094 if (!road_move_mode_is_valid(proad->move_mode)) {
4095 ruleset_error(NULL, LOG_ERROR,
4096 "Illegal move_mode \"%s\" for road \"%s\"",
4097 modestr, extra_rule_name(pextra));
4098 ok = FALSE;
4099 break;
4100 }
4101
4102 output_type_iterate(o) {
4103 proad->tile_incr_const[o] =
4104 secfile_lookup_int_default(file, 0, "%s.%s_incr_const",
4105 section, get_output_identifier(o));
4106 proad->tile_incr[o] =
4107 secfile_lookup_int_default(file, 0, "%s.%s_incr",
4108 section, get_output_identifier(o));
4109 proad->tile_bonus[o] =
4110 secfile_lookup_int_default(file, 0, "%s.%s_bonus",
4111 section, get_output_identifier(o));
4112 } output_type_iterate_end;
4113
4114 special = secfile_lookup_str_default(file, "None", "%s.compat_special", section);
4115 if (!fc_strcasecmp(special, "Road")) {
4116 if (compat_road) {
4117 ruleset_error(NULL, LOG_ERROR,
4118 "Multiple roads marked as compatibility \"Road\"");
4119 ok = FALSE;
4120 }
4121 compat_road = TRUE;
4122 proad->compat = ROCO_ROAD;
4123 } else if (!fc_strcasecmp(special, "Railroad")) {
4124 if (compat_rail) {
4125 ruleset_error(NULL, LOG_ERROR,
4126 "Multiple roads marked as compatibility \"Railroad\"");
4127 ok = FALSE;
4128 }
4129 compat_rail = TRUE;
4130 proad->compat = ROCO_RAILROAD;
4131 } else if (!fc_strcasecmp(special, "River")) {
4132 if (compat_river) {
4133 ruleset_error(NULL, LOG_ERROR,
4134 "Multiple roads marked as compatibility \"River\"");
4135 ok = FALSE;
4136 }
4137 compat_river = TRUE;
4138 proad->compat = ROCO_RIVER;
4139 } else if (!fc_strcasecmp(special, "None")) {
4140 proad->compat = ROCO_NONE;
4141 } else {
4142 ruleset_error(NULL, LOG_ERROR,
4143 "Illegal compatibility special \"%s\" for road %s",
4144 special, extra_rule_name(pextra));
4145 ok = FALSE;
4146 }
4147
4148 if (!ok) {
4149 break;
4150 }
4151
4152 slist = secfile_lookup_str_vec(file, &nval, "%s.integrates", section);
4153 BV_CLR_ALL(proad->integrates);
4154 for (j = 0; j < nval; j++) {
4155 const char *sval = slist[j];
4156 struct extra_type *textra = extra_type_by_rule_name(sval);
4157 struct road_type *top = NULL;
4158
4159 if (textra != NULL) {
4160 top = extra_road_get(textra);
4161 }
4162
4163 if (top == NULL) {
4164 ruleset_error(NULL, LOG_ERROR,
4165 "\"%s\" road \"%s\" integrates with unknown road \"%s\".",
4166 filename, extra_rule_name(pextra), sval);
4167 ok = FALSE;
4168 break;
4169 } else {
4170 BV_SET(proad->integrates, road_number(top));
4171 }
4172 }
4173 free(slist);
4174
4175 if (!ok) {
4176 break;
4177 }
4178
4179 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", section);
4180 BV_CLR_ALL(proad->flags);
4181 for (j = 0; j < nval; j++) {
4182 const char *sval = slist[j];
4183 enum road_flag_id flag = road_flag_id_by_name(sval, fc_strcasecmp);
4184
4185 if (!road_flag_id_is_valid(flag)) {
4186 ruleset_error(NULL, LOG_ERROR,
4187 "\"%s\" road \"%s\": unknown flag \"%s\".",
4188 filename, extra_rule_name(pextra), sval);
4189 ok = FALSE;
4190 break;
4191 } else {
4192 BV_SET(proad->flags, flag);
4193 }
4194 }
4195 free(slist);
4196
4197 if (!ok) {
4198 break;
4199 }
4200 } extra_type_by_cause_iterate_end;
4201
4202 for (j = 0; ok && j < game.control.num_road_types; j++) {
4203 const char *section = &road_sections[j * MAX_SECTION_LABEL];
4204 const char *extra_name = secfile_lookup_str(file, "%s.extra", section);
4205 struct extra_type *pextra = extra_type_by_rule_name(extra_name);
4206
4207 if (!is_extra_caused_by(pextra, EC_ROAD)) {
4208 ruleset_error(NULL, LOG_ERROR,
4209 "\"%s\" road section [%s]: extra \"%s\" does not have "
4210 "\"Road\" in its causes",
4211 filename, section, extra_name);
4212 ok = FALSE;
4213 }
4214 }
4215 }
4216
4217 if (ok) {
4218 extra_type_iterate(pextra) {
4219 pextra->bridged = extra_type_list_new();
4220 extra_type_iterate(pbridged) {
4221 if (BV_ISSET(pextra->bridged_over, pbridged->id)) {
4222 extra_type_list_append(pextra->bridged, pbridged);
4223 }
4224 } extra_type_iterate_end;
4225 } extra_type_iterate_end;
4226 }
4227
4228 if (ok) {
4229 secfile_check_unused(file);
4230 }
4231
4232 return ok;
4233}
4234
4235/**********************************************************************/
4239 static bool load_government_names(struct section_file *file,
4240 struct rscompat_info *compat)
4241{
4242 int nval = 0;
4243 struct section_list *sec;
4244 const char *filename = secfile_name(file);
4245 bool ok = TRUE;
4246
4247 if (!rscompat_check_cap_and_version(file, filename, compat)) {
4248 return FALSE;
4249 }
4250
4251 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
4252 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
4253
4254 sec = secfile_sections_by_name_prefix(file, GOVERNMENT_SECTION_PREFIX);
4255 if (NULL == sec || 0 == (nval = section_list_size(sec))) {
4256 ruleset_error(NULL, LOG_ERROR, "\"%s\": No governments?!?", filename);
4257 ok = FALSE;
4258 } else if (nval > G_LAST) {
4259 ruleset_error(NULL, LOG_ERROR,
4260 "\"%s\": Too many governments (%d, max %d)",
4261 filename, nval, G_LAST);
4262 ok = FALSE;
4263 }
4264
4265 if (ok) {
4266 governments_alloc(nval);
4267
4268 /* Government names are needed early so that get_government_by_name will
4269 * work. */
4270 governments_iterate(gov) {
4271 const char *sec_name =
4272 section_name(section_list_get(sec, government_index(gov)));
4273
4274 if (!ruleset_load_names(&gov->name, NULL, file, sec_name)) {
4275 ok = FALSE;
4276 break;
4277 }
4278 } governments_iterate_end;
4279 }
4280
4281 section_list_destroy(sec);
4282
4283 if (ok) {
4284 sec = secfile_sections_by_name_prefix(file, MULTIPLIER_SECTION_PREFIX);
4285 nval = (NULL != sec ? section_list_size(sec) : 0);
4286
4287 if (nval > MAX_NUM_MULTIPLIERS) {
4288 ruleset_error(NULL, LOG_ERROR,
4289 "\"%s\": Too many multipliers (%d, max %d)",
4290 filename, nval, MAX_NUM_MULTIPLIERS);
4291
4292 ok = FALSE;
4293 } else {
4294 game.control.num_multipliers = nval;
4295 }
4296
4297 if (ok) {
4298 multipliers_iterate(pmul) {
4299 const char *sec_name =
4300 section_name(section_list_get(sec, multiplier_index(pmul)));
4301
4302 if (!ruleset_load_names(&pmul->name, NULL, file, sec_name)) {
4303 ruleset_error(NULL, LOG_ERROR,
4304 "\"%s\": Cannot load multiplier names",
4305 filename);
4306 ok = FALSE;
4307 break;
4308 }
4309 } multipliers_iterate_end;
4310 }
4311 }
4312
4313 section_list_destroy(sec);
4314
4315 return ok;
4316}
4317
4318/**********************************************************************/
4321 static bool load_ruleset_governments(struct section_file *file,
4322 struct rscompat_info *compat)
4323{
4324 struct section_list *sec;
4325 const char *filename = secfile_name(file);
4326 bool ok = TRUE;
4327
4328 sec = secfile_sections_by_name_prefix(file, GOVERNMENT_SECTION_PREFIX);
4329
4330 game.government_during_revolution
4331 = lookup_government(file, "governments.during_revolution", filename, NULL);
4332 if (game.government_during_revolution == NULL) {
4333 ok = FALSE;
4334 }
4335
4336 if (ok) {
4337 game.info.government_during_revolution_id =
4338 government_number(game.government_during_revolution);
4339
4340 /* easy ones: */
4341 governments_iterate(g) {
4342 const int i = government_index(g);
4343 const char *sec_name = section_name(section_list_get(sec, i));
4344 struct requirement_vector *reqs =
4345 lookup_req_list(file, compat, sec_name, "reqs", government_rule_name(g));
4346
4347 if (reqs == NULL) {
4348 ok = FALSE;
4349 break;
4350 }
4351
4352 if (NULL != secfile_entry_lookup(file, "%s.ai_better", sec_name)) {
4353 char entry[100];
4354
4355 fc_snprintf(entry, sizeof(entry), "%s.ai_better", sec_name);
4356 g->ai.better = lookup_government(file, entry, filename, NULL);
4357 if (g->ai.better == NULL) {
4358 ok = FALSE;
4359 break;
4360 }
4361 } else {
4362 g->ai.better = NULL;
4363 }
4364 requirement_vector_copy(&g->reqs, reqs);
4365
4366 sz_strlcpy(g->graphic_str,
4367 secfile_lookup_str(file, "%s.graphic", sec_name));
4368 sz_strlcpy(g->graphic_alt,
4369 secfile_lookup_str(file, "%s.graphic_alt", sec_name));
4370
4371 g->helptext = lookup_strvec(file, sec_name, "helptext");
4372 } governments_iterate_end;
4373 }
4374
4375
4376 if (ok) {
4377 /* titles */
4378 governments_iterate(g) {
4379 const char *sec_name =
4380 section_name(section_list_get(sec, government_index(g)));
4381 const char *male, *female;
4382
4383 if (!(male = secfile_lookup_str(file, "%s.ruler_male_title", sec_name))
4384 || !(female = secfile_lookup_str(file, "%s.ruler_female_title",
4385 sec_name))) {
4386 ruleset_error(NULL, LOG_ERROR,
4387 "Lack of default ruler titles for "
4388 "government \"%s\" (nb %d): %s",
4389 government_rule_name(g), government_number(g),
4390 secfile_error());
4391 ok = FALSE;
4392 break;
4393 } else if (NULL == government_ruler_title_new(g, NULL, male, female)) {
4394 ruleset_error(NULL, LOG_ERROR,
4395 "Lack of default ruler titles for "
4396 "government \"%s\" (nb %d).",
4397 government_rule_name(g), government_number(g));
4398 ok = FALSE;
4399 break;
4400 }
4401 } governments_iterate_end;
4402 }
4403
4404 section_list_destroy(sec);
4405
4406 if (ok) {
4407 sec = secfile_sections_by_name_prefix(file, MULTIPLIER_SECTION_PREFIX);
4408 multipliers_iterate(pmul) {
4409 int id = multiplier_index(pmul);
4410 const char *sec_name = section_name(section_list_get(sec, id));
4411 struct requirement_vector *reqs;
4412
4413 if (!secfile_lookup_int(file, &pmul->start, "%s.start", sec_name)) {
4414 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4415 ok = FALSE;
4416 break;
4417 }
4418 if (!secfile_lookup_int(file, &pmul->stop, "%s.stop", sec_name)) {
4419 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4420 ok = FALSE;
4421 break;
4422 }
4423 if (pmul->stop <= pmul->start) {
4424 ruleset_error(NULL, LOG_ERROR,
4425 "Multiplier \"%s\" stop (%d) must be greater "
4426 "than start (%d)", multiplier_rule_name(pmul),
4427 pmul->stop, pmul->start);
4428 ok = FALSE;
4429 break;
4430 }
4431 if (!secfile_lookup_int(file, &pmul->step, "%s.step", sec_name)) {
4432 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4433 ok = FALSE;
4434 break;
4435 }
4436 if (((pmul->stop - pmul->start) % pmul->step) != 0) {
4437 ruleset_error(NULL, LOG_ERROR,
4438 "Multiplier \"%s\" step (%d) does not fit "
4439 "exactly into interval start-stop (%d to %d)",
4440 multiplier_rule_name(pmul), pmul->step,
4441 pmul->start, pmul->stop);
4442 ok = FALSE;
4443 break;
4444 }
4445 if (!secfile_lookup_int(file, &pmul->def, "%s.default", sec_name)) {
4446 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4447 ok = FALSE;
4448 break;
4449 }
4450 if (pmul->def < pmul->start || pmul->def > pmul->stop) {
4451 ruleset_error(NULL, LOG_ERROR,
4452 "Multiplier \"%s\" default (%d) not within "
4453 "legal range (%d to %d)", multiplier_rule_name(pmul),
4454 pmul->def, pmul->start, pmul->stop);
4455 ok = FALSE;
4456 break;
4457 }
4458 if (((pmul->def - pmul->start) % pmul->step) != 0) {
4459 ruleset_error(NULL, LOG_ERROR,
4460 "Multiplier \"%s\" default (%d) not legal "
4461 "with respect to step size %d",
4462 multiplier_rule_name(pmul), pmul->def, pmul->step);
4463 ok = FALSE;
4464 break;
4465 }
4466 pmul->offset = secfile_lookup_int_default(file, 0,
4467 "%s.offset", sec_name);
4468 pmul->factor = secfile_lookup_int_default(file, 100,
4469 "%s.factor", sec_name);
4470 if (pmul->factor == 0) {
4471 ruleset_error(NULL, LOG_ERROR,
4472 "Multiplier \"%s\" scaling factor must "
4473 "not be zero", multiplier_rule_name(pmul));
4474 ok = FALSE;
4475 break;
4476 }
4477
4478 pmul->minimum_turns = secfile_lookup_int_default(file, 0,
4479 "%s.minimum_turns",
4480 sec_name);
4481
4482 reqs = lookup_req_list(file, compat, sec_name, "reqs",
4483 multiplier_rule_name(pmul));
4484 if (reqs == NULL) {
4485 ok = FALSE;
4486 break;
4487 }
4488 requirement_vector_copy(&pmul->reqs, reqs);
4489
4490 pmul->helptext = lookup_strvec(file, sec_name, "helptext");
4491 } multipliers_iterate_end;
4492 section_list_destroy(sec);
4493 }
4494
4495 if (ok) {
4496 secfile_check_unused(file);
4497 }
4498
4499 return ok;
4500}
4501
4502/**********************************************************************/
4513 static void send_ruleset_control(struct conn_list *dest)
4514{
4515 int desc_left = game.control.desc_length;
4516 int idx = 0;
4517
4518 lsend_packet_ruleset_control(dest, &(game.control));
4519
4520 if (game.ruleset_summary != NULL) {
4521 struct packet_ruleset_summary summary;
4522
4523 sz_strlcpy(summary.text, game.ruleset_summary);
4524
4525 lsend_packet_ruleset_summary(dest, &summary);
4526 }
4527
4528 while (desc_left > 0) {
4529 struct packet_ruleset_description_part part;
4530 int this_len = desc_left;
4531
4532 if (this_len > MAX_LEN_CONTENT - 21) {
4533 this_len = MAX_LEN_CONTENT - 1;
4534 }
4535
4536 part.text[this_len] = '\0';
4537
4538 strncpy(part.text, &game.ruleset_description[idx], this_len);
4539 idx += this_len;
4540 desc_left -= this_len;
4541
4542 lsend_packet_ruleset_description_part(dest, &part);
4543 }
4544}
4545
4546/**********************************************************************/
4551 static const char *check_leader_names(struct nation_type *pnation)
4552{
4553 nation_leader_list_iterate(nation_leaders(pnation), pleader) {
4554 const char *name = nation_leader_name(pleader);
4555
4556 nation_leader_list_iterate(nation_leaders(pnation), prev_leader) {
4557 if (prev_leader == pleader) {
4558 break;
4559 } else if (0 == fc_strcasecmp(name, nation_leader_name(prev_leader))) {
4560 return name;
4561 }
4562 } nation_leader_list_iterate_end;
4563 } nation_leader_list_iterate_end;
4564 return NULL;
4565}
4566
4567/**********************************************************************/
4571 static bool load_nation_names(struct section_file *file,
4572 struct rscompat_info *compat)
4573{
4574 struct section_list *sec;
4575 int j;
4576 bool ok = TRUE;
4577 const char *filename = secfile_name(file);
4578
4579 if (!rscompat_check_cap_and_version(file, filename, compat)) {
4580 return FALSE;
4581 }
4582
4583 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
4584 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
4585
4586 sec = secfile_sections_by_name_prefix(file, NATION_SECTION_PREFIX);
4587 if (NULL == sec) {
4588 ruleset_error(NULL, LOG_ERROR,
4589 "No available nations in this ruleset!");
4590 ok = FALSE;
4591 } else if (section_list_size(sec) > MAX_NUM_NATIONS) {
4592 ruleset_error(NULL, LOG_ERROR,
4593 "Too many nations (max %d, we have %d)!",
4594 MAX_NUM_NATIONS, section_list_size(sec));
4595 ok = FALSE;
4596 } else {
4597 game.control.nation_count = section_list_size(sec);
4598 nations_alloc(game.control.nation_count);
4599
4600 nations_iterate(pl) {
4601 const int i = nation_index(pl);
4602 const char *sec_name = section_name(section_list_get(sec, i));
4603 const char *domain = secfile_lookup_str_default(file, NULL,
4604 "%s.translation_domain", sec_name);
4605 const char *noun_plural = secfile_lookup_str(file,
4606 "%s.plural", sec_name);
4607
4608
4609 if (domain == NULL) {
4610 domain = "freeciv-nations";
4611 }
4612
4613 if (!strcmp("freeciv-core", domain)) {
4614 pl->translation_domain = NULL;
4615 } else if (!strcmp("freeciv-nations", domain)) {
4616 pl->translation_domain = fc_strdup(domain);
4617 } else {
4618 ruleset_error(NULL, LOG_ERROR,
4619 "Unsupported translation domain \"%s\" for %s",
4620 domain, sec_name);
4621 ok = FALSE;
4622 break;
4623 }
4624
4625 if (!ruleset_load_names(&pl->adjective, pl->translation_domain, file, sec_name)) {
4626 ok = FALSE;
4627 break;
4628 }
4629 name_set(&pl->noun_plural, pl->translation_domain, noun_plural);
4630
4631 /* Check if nation name is already defined. */
4632 for (j = 0; j < i && ok; j++) {
4633 struct nation_type *n2 = nation_by_number(j);
4634
4635 /* Compare strings after stripping off qualifiers -- we don't want
4636 * two nations to end up with identical adjectives displayed to users.
4637 * (This check only catches English, not localisations, of course.) */
4638 if (0 == strcmp(Qn_(untranslated_name(&n2->adjective)),
4639 Qn_(untranslated_name(&pl->adjective)))) {
4640 ruleset_error(NULL, LOG_ERROR,
4641 "Two nations defined with the same adjective \"%s\": "
4642 "in section \'%s\' and section \'%s\'",
4643 Qn_(untranslated_name(&pl->adjective)),
4644 section_name(section_list_get(sec, j)), sec_name);
4645 ok = FALSE;
4646 } else if (!strcmp(rule_name_get(&n2->adjective),
4647 rule_name_get(&pl->adjective))) {
4648 /* We cannot have the same rule name, as the game needs them to be
4649 * distinct. */
4650 ruleset_error(NULL, LOG_ERROR,
4651 "Two nations defined with the same rule_name \"%s\": "
4652 "in section \'%s\' and section \'%s\'",
4653 rule_name_get(&pl->adjective),
4654 section_name(section_list_get(sec, j)), sec_name);
4655 ok = FALSE;
4656 } else if (0 == strcmp(Qn_(untranslated_name(&n2->noun_plural)),
4657 Qn_(untranslated_name(&pl->noun_plural)))) {
4658 /* We don't want identical English plural names either. */
4659 ruleset_error(NULL, LOG_ERROR,
4660 "Two nations defined with the same plural name \"%s\": "
4661 "in section \'%s\' and section \'%s\'",
4662 Qn_(untranslated_name(&pl->noun_plural)),
4663 section_name(section_list_get(sec, j)), sec_name);
4664 ok = FALSE;
4665 }
4666 }
4667 if (!ok) {
4668 break;
4669 }
4670 } nations_iterate_end;
4671 }
4672
4673 section_list_destroy(sec);
4674
4675 if (ok) {
4676 sec = secfile_sections_by_name_prefix(file, NATION_GROUP_SECTION_PREFIX);
4677 if (sec != NULL) {
4678 game.control.num_nation_groups = section_list_size(sec);
4679
4680 section_list_iterate(sec, psection) {
4681 struct nation_group *pgroup;
4682 const char *name;
4683
4684 name = secfile_lookup_str(file, "%s.name", section_name(psection));
4685 if (NULL == name) {
4686 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
4687 ok = FALSE;
4688 break;
4689 }
4690 pgroup = nation_group_new(name);
4691 if (pgroup == NULL) {
4692 ok = FALSE;
4693 break;
4694 }
4695 } section_list_iterate_end;
4696 section_list_destroy(sec);
4697 sec = NULL;
4698 }
4699 }
4700
4701 return ok;
4702}
4703
4704/**********************************************************************/
4707 static bool is_on_allowed_list(const char *name, const char **list, size_t len)
4708{
4709 int i;
4710
4711 for (i = 0; i < len; i++) {
4712 if (!fc_strcasecmp(name, list[i])) {
4713 return TRUE;
4714 }
4715 }
4716 return FALSE;
4717}
4718
4719/**********************************************************************/
4723 static bool load_city_name_list(struct section_file *file,
4724 struct nation_type *pnation,
4725 const char *secfile_str1,
4726 const char *secfile_str2,
4727 const char **allowed_terrains,
4728 size_t atcount)
4729{
4730 size_t dim, j;
4731 bool ok = TRUE;
4732 const char **cities = secfile_lookup_str_vec(file, &dim, "%s.%s",
4733 secfile_str1, secfile_str2);
4734
4735 /* Each string will be of the form "<cityname> (<label>, <label>, ...)".
4736 * The cityname is just the name for this city, while each "label" matches
4737 * a terrain type for the city (or "river"), with a preceeding ! to negate
4738 * it. The parentheses are optional (but necessary to have the settings,
4739 * of course). Our job is now to parse it. */
4740 for (j = 0; j < dim; j++) {
4741 size_t len = strlen(cities[j]);
4742 char city_name[len + 1], *p, *next, *end;
4743 struct nation_city *pncity;
4744
4745 sz_strlcpy(city_name, cities[j]);
4746
4747 /* Now we wish to determine values for all of the city labels. A value
4748 * of NCP_NONE means no preference (which is necessary so that the use
4749 * of this is optional); NCP_DISLIKE means the label is negated and
4750 * NCP_LIKE means it's labelled. Mostly the parsing just involves
4751 * a lot of ugly string handling... */
4752 if ((p = strchr(city_name, '('))) {
4753 *p++ = '\0';
4754
4755 if (!(end = strchr(p, ')'))) {
4756 ruleset_error(NULL, LOG_ERROR,
4757 "\"%s\" [%s] %s: city name \"%s\" "
4758 "unmatched parenthesis.", secfile_name(file),
4759 secfile_str1, secfile_str2, cities[j]);
4760 ok = FALSE;
4761 } else {
4762 for (*end++ = '\0'; '\0' != *end; end++) {
4763 if (!fc_isspace(*end)) {
4764 ruleset_error(NULL, LOG_ERROR,
4765 "\"%s\" [%s] %s: city name \"%s\" "
4766 "contains characters after last parenthesis.",
4767 secfile_name(file), secfile_str1, secfile_str2,
4768 cities[j]);
4769 ok = FALSE;
4770 break;
4771 }
4772 }
4773 }
4774 }
4775
4776 /* Build the nation_city. */
4777 remove_leading_trailing_spaces(city_name);
4778 if (check_cityname(city_name)) {
4779 /* The ruleset contains a name that is too long. This shouldn't
4780 * happen - if it does, the author should get immediate feedback. */
4781 ruleset_error(NULL, LOG_ERROR,
4782 "\"%s\" [%s] %s: city name \"%s\" is too long.",
4783 secfile_name(file),
4784 secfile_str1, secfile_str2, city_name);
4785 ok = FALSE;
4786 city_name[MAX_LEN_CITYNAME - 1] = '\0';
4787 }
4788 pncity = nation_city_new(pnation, city_name);
4789
4790 if (NULL != p) {
4791 /* Handle the labels one at a time. */
4792 do {
4793 enum nation_city_preference prefer;
4794
4795 if ((next = strchr(p, ','))) {
4796 *next = '\0';
4797 }
4798 remove_leading_trailing_spaces(p);
4799
4800 /* The ! is used to mark a negative, which is recorded with
4801 * NCP_DISLIKE. Otherwise we use a NCP_LIKE.
4802 */
4803 if (*p == '!') {
4804 p++;
4805 prefer = NCP_DISLIKE;
4806 } else {
4807 prefer = NCP_LIKE;
4808 }
4809
4810 if (0 == fc_strcasecmp(p, "river")) {
4811 if (game.server.ruledit.allowed_terrains != NULL
4812 && !is_on_allowed_list(p,
4813 game.server.ruledit.allowed_terrains, atcount)) {
4814 ruleset_error(NULL, LOG_ERROR,
4815 "\"%s\" [%s] %s: city \"%s\" "
4816 "has terrain hint \"%s\" not in allowed_terrains.",
4817 secfile_name(file), secfile_str1, secfile_str2,
4818 city_name, p);
4819 ok = FALSE;
4820 } else {
4821 nation_city_set_river_preference(pncity, prefer);
4822 }
4823 } else {
4824 const struct terrain *pterrain = terrain_by_rule_name(p);
4825
4826 if (NULL == pterrain) {
4827 /* Try with removing frequent trailing 's'. */
4828 size_t l = strlen(p);
4829
4830 if (0 < l && 's' == fc_tolower(p[l - 1])) {
4831 char saved = p[l - 1];
4832
4833 p[l - 1] = '\0';
4834 pterrain = terrain_by_rule_name(p);
4835 if (pterrain == NULL) {
4836 /* Didn't help, restore for later allowed_terrains check */
4837 p[l - 1] = saved;
4838 }
4839 }
4840 }
4841
4842 /* Nationset may have been devised with a specific set of terrains
4843 * in mind which don't quite match this ruleset, in which case we
4844 * (a) quietly ignore any hints mentioned that don't happen to be in
4845 * the current ruleset, (b) enforce that terrains mentioned by nations
4846 * must be on the list */
4847 if (pterrain != NULL && game.server.ruledit.allowed_terrains != NULL) {
4848 if (!is_on_allowed_list(p,
4849 game.server.ruledit.allowed_terrains, atcount)) {
4850 /* Terrain exists, but not intended for these nations */
4851 ruleset_error(NULL, LOG_ERROR,
4852 "\"%s\" [%s] %s: city \"%s\" "
4853 "has terrain hint \"%s\" not in allowed_terrains.",
4854 secfile_name(file), secfile_str1, secfile_str2,
4855 city_name, p);
4856 ok = FALSE;
4857 break;
4858 }
4859 } else if (!pterrain) {
4860 /* Terrain doesn't exist; only complain if it's not on any list */
4861 if (game.server.ruledit.allowed_terrains == NULL
4862 || !is_on_allowed_list(p,
4863 game.server.ruledit.allowed_terrains, atcount)) {
4864 ruleset_error(NULL, LOG_ERROR,
4865 "\"%s\" [%s] %s: city \"%s\" "
4866 "has unknown terrain hint \"%s\".",
4867 secfile_name(file), secfile_str1, secfile_str2,
4868 city_name, p);
4869 ok = FALSE;
4870 break;
4871 }
4872 }
4873 if (NULL != pterrain) {
4874 nation_city_set_terrain_preference(pncity, pterrain, prefer);
4875 }
4876 }
4877
4878 p = next ? next + 1 : NULL;
4879 } while (NULL != p && '\0' != *p);
4880 }
4881 }
4882
4883 if (NULL != cities) {
4884 free(cities);
4885 }
4886
4887 return ok;
4888}
4889
4890/**********************************************************************/
4893 static bool load_ruleset_nations(struct section_file *file,
4894 struct rscompat_info *compat)
4895{
4896 struct government *gov;
4897 int j;
4898 size_t dim;
4899 char temp_name[MAX_LEN_NAME];
4900 const char **vec;
4901 const char *name, *bad_leader;
4902 const char *sval;
4903 int default_set;
4904 const char *filename = secfile_name(file);
4905 struct section_list *sec = NULL;
4906 enum trait tr;
4907 bool ok = TRUE;
4908
4909 name = secfile_lookup_str_default(file, NULL, "ruledit.nationlist");
4910 if (name != NULL) {
4911 game.server.ruledit.nationlist = fc_strdup(name);
4912 }
4913 vec = secfile_lookup_str_vec(file, &game.server.ruledit.embedded_nations_count,
4914 "ruledit.embedded_nations");
4915
4916 if (vec != NULL) {
4917 /* Copy to persistent vector */
4918 game.server.ruledit.embedded_nations
4919 = fc_malloc(game.server.ruledit.embedded_nations_count * sizeof(char *));
4920
4921 for (j = 0; j < game.server.ruledit.embedded_nations_count; j++) {
4922 game.server.ruledit.embedded_nations[j] = fc_strdup(vec[j]);
4923 }
4924
4925 free(vec);
4926 }
4927
4928 game.default_government = NULL;
4929
4930 ruleset_load_traits(game.server.default_traits, file, "default_traits", "");
4931 for (tr = trait_begin(); tr != trait_end(); tr = trait_next(tr)) {
4932 if (game.server.default_traits[tr].min < 0) {
4933 game.server.default_traits[tr].min = TRAIT_DEFAULT_VALUE;
4934 }
4935 if (game.server.default_traits[tr].max < 0) {
4936 game.server.default_traits[tr].max = TRAIT_DEFAULT_VALUE;
4937 }
4938 if (game.server.default_traits[tr].fixed < 0) {
4939 int diff = game.server.default_traits[tr].max - game.server.default_traits[tr].min;
4940
4941 /* TODO: Should sometimes round the a / 2 = x.5 results up */
4942 game.server.default_traits[tr].fixed = diff / 2 + game.server.default_traits[tr].min;
4943 }
4944 if (game.server.default_traits[tr].max < game.server.default_traits[tr].min) {
4945 ruleset_error(NULL, LOG_ERROR,
4946 "Default values for trait %s not sane.",
4947 trait_name(tr));
4948 ok = FALSE;
4949 break;
4950 }
4951 }
4952
4953 if (ok) {
4954 vec = secfile_lookup_str_vec(file, &game.server.ruledit.ag_count,
4955 "compatibility.allowed_govs");
4956 if (vec != NULL) {
4957 /* Copy to persistent vector */
4958 game.server.ruledit.nc_agovs
4959 = fc_malloc(game.server.ruledit.ag_count * sizeof(char *));
4960 game.server.ruledit.allowed_govs =
4961 (const char **)game.server.ruledit.nc_agovs;
4962
4963 for (j = 0; j < game.server.ruledit.ag_count; j++) {
4964 game.server.ruledit.allowed_govs[j] = fc_strdup(vec[j]);
4965 }
4966
4967 free(vec);
4968 }
4969
4970 vec = secfile_lookup_str_vec(file, &game.server.ruledit.at_count,
4971 "compatibility.allowed_terrains");
4972 if (vec != NULL) {
4973 /* Copy to persistent vector */
4974 game.server.ruledit.nc_aterrs
4975 = fc_malloc(game.server.ruledit.at_count * sizeof(char *));
4976 game.server.ruledit.allowed_terrains =
4977 (const char **)game.server.ruledit.nc_aterrs;
4978
4979 for (j = 0; j < game.server.ruledit.at_count; j++) {
4980 game.server.ruledit.allowed_terrains[j] = fc_strdup(vec[j]);
4981 }
4982
4983 free(vec);
4984 }
4985
4986 vec = secfile_lookup_str_vec(file, &game.server.ruledit.as_count,
4987 "compatibility.allowed_styles");
4988 if (vec != NULL) {
4989 /* Copy to persistent vector */
4990 game.server.ruledit.nc_astyles
4991 = fc_malloc(game.server.ruledit.as_count * sizeof(char *));
4992 game.server.ruledit.allowed_styles =
4993 (const char **)game.server.ruledit.nc_astyles;
4994
4995 for (j = 0; j < game.server.ruledit.as_count; j++) {
4996 game.server.ruledit.allowed_styles[j] = fc_strdup(vec[j]);
4997 }
4998
4999 free(vec);
5000 }
5001
5002 sval = secfile_lookup_str_default(file, NULL,
5003 "compatibility.default_government");
5004 /* We deliberately don't check this against allowed_govs. It's only
5005 * specified once so not vulnerable to typos, and may usefully be set in
5006 * a specific ruleset to a gov not explicitly known by the nation set. */
5007 if (sval != NULL) {
5008 game.default_government = government_by_rule_name(sval);
5009 if (game.default_government == NULL) {
5010 ruleset_error(NULL, LOG_ERROR,
5011 "Tried to set unknown government type \"%s\" as default_government!",
5012 sval);
5013 ok = FALSE;
5014 } else {
5015 game.info.default_government_id
5016 = government_number(game.default_government);
5017 }
5018 }
5019 }
5020
5021 if (ok) {
5022 sec = secfile_sections_by_name_prefix(file, NATION_SET_SECTION_PREFIX);
5023 if (sec != NULL) {
5024 game.control.num_nation_sets = section_list_size(sec);
5025
5026 section_list_iterate(sec, psection) {
5027 const char *set_name, *set_rule_name, *set_description;
5028
5029 set_name = secfile_lookup_str(file, "%s.name", section_name(psection));
5030 set_rule_name =
5031 secfile_lookup_str(file, "%s.rule_name", section_name(psection));
5032 set_description = secfile_lookup_str_default(file, "", "%s.description",
5033 section_name(psection));
5034 if (NULL == set_name || NULL == set_rule_name) {
5035 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
5036 ok = FALSE;
5037 break;
5038 }
5039 if (nation_set_new(set_name, set_rule_name, set_description) == NULL) {
5040 ok = FALSE;
5041 break;
5042 }
5043 } section_list_iterate_end;
5044 section_list_destroy(sec);
5045 sec = NULL;
5046 } else {
5047 ruleset_error(NULL, LOG_ERROR,
5048 "At least one nation set [" NATION_SET_SECTION_PREFIX "_*] "
5049 "must be defined.");
5050 ok = FALSE;
5051 }
5052 }
5053
5054 if (ok) {
5055 /* Default set that every nation is a member of. */
5056 sval = secfile_lookup_str_default(file, NULL,
5057 "compatibility.default_nationset");
5058 if (sval != NULL) {
5059 const struct nation_set *pset = nation_set_by_rule_name(sval);
5060 if (pset != NULL) {
5061 default_set = nation_set_number(pset);
5062 } else {
5063 ruleset_error(NULL, LOG_ERROR,
5064 "Unknown default_nationset \"%s\".", sval);
5065 ok = FALSE;
5066 }
5067 } else if (nation_set_count() == 1) {
5068 /* If there's only one set defined, every nation is implicitly a
5069 * member of that set. */
5070 default_set = 0;
5071 } else {
5072 /* No default nation set; every nation must explicitly specify at
5073 * least one set to be a member of. */
5074 default_set = -1;
5075 }
5076 }
5077
5078 if (ok) {
5079 sec = secfile_sections_by_name_prefix(file, NATION_GROUP_SECTION_PREFIX);
5080 if (sec) {
5081 section_list_iterate(sec, psection) {
5082 struct nation_group *pgroup;
5083 bool hidden;
5084
5085 name = secfile_lookup_str(file, "%s.name", section_name(psection));
5086 pgroup = nation_group_by_rule_name(name);
5087 if (pgroup == NULL) {
5088 ok = FALSE;
5089 break;
5090 }
5091
5092 hidden = secfile_lookup_bool_default(file, FALSE, "%s.hidden",
5093 section_name(psection));
5094 nation_group_set_hidden(pgroup, hidden);
5095
5096 if (!secfile_lookup_int(file, &j, "%s.match", section_name(psection))) {
5097 ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error());
5098 ok = FALSE;
5099 break;
5100 }
5101 nation_group_set_match(pgroup, j);
5102 } section_list_iterate_end;
5103 section_list_destroy(sec);
5104 sec = NULL;
5105 }
5106 }
5107
5108 if (ok) {
5109 sec = secfile_sections_by_name_prefix(file, NATION_SECTION_PREFIX);
5110 nations_iterate(pnation) {
5111 struct nation_type *pconflict;
5112 const int i = nation_index(pnation);
5113 char tmp[200] = "\0";
5114 const char *barb_type;
5115 const char *sec_name = section_name(section_list_get(sec, i));
5116 const char *legend;
5117
5118 /* Nation sets and groups. */
5119 if (default_set >= 0) {
5120 nation_set_list_append(pnation->sets,
5121 nation_set_by_number(default_set));
5122 }
5123 vec = secfile_lookup_str_vec(file, &dim, "%s.groups", sec_name);
5124 for (j = 0; j < dim; j++) {
5125 struct nation_set *pset = nation_set_by_rule_name(vec[j]);
5126 struct nation_group *pgroup = nation_group_by_rule_name(vec[j]);
5127
5128 fc_assert(pset == NULL || pgroup == NULL);
5129
5130 if (NULL != pset) {
5131 nation_set_list_append(pnation->sets, pset);
5132 } else if (NULL != pgroup) {
5133 nation_group_list_append(pnation->groups, pgroup);
5134 } else {
5135 /* For nation authors, this would probably be considered an error.
5136 * But it can happen normally. The civ1 compatibility ruleset only
5137 * uses the nations that were in civ1, so not all of the links will
5138 * exist. */
5139 log_verbose("Nation %s: Unknown set/group \"%s\".",
5140 nation_rule_name(pnation), vec[j]);
5141 }
5142 }
5143 if (NULL != vec) {
5144 free(vec);
5145 }
5146 if (nation_set_list_size(pnation->sets) < 1) {
5147 ruleset_error(NULL, LOG_ERROR,
5148 "Nation %s is not a member of any nation set",
5149 nation_rule_name(pnation));
5150 ok = FALSE;
5151 break;
5152 }
5153
5154 /* Nation conflicts. */
5155 vec = secfile_lookup_str_vec(file, &dim, "%s.conflicts_with", sec_name);
5156 for (j = 0; j < dim; j++) {
5157 pconflict = nation_by_rule_name(vec[j]);
5158
5159 if (pnation == pconflict) {
5160 ruleset_error(NULL, LOG_ERROR,
5161 "Nation %s conflicts with itself",
5162 nation_rule_name(pnation));
5163 ok = FALSE;
5164 break;
5165 } else if (NULL != pconflict) {
5166 nation_list_append(pnation->server.conflicts_with, pconflict);
5167 } else {
5168 /* For nation authors, this would probably be considered an error.
5169 * But it can happen normally. The civ1 compatibility ruleset only
5170 * uses the nations that were in civ1, so not all of the links will
5171 * exist. */
5172 log_verbose("Nation %s: conflicts_with nation \"%s\" is unknown.",
5173 nation_rule_name(pnation), vec[j]);
5174 }
5175 }
5176 if (NULL != vec) {
5177 free(vec);
5178 }
5179 if (!ok) {
5180 break;
5181 }
5182
5183 /* Nation leaders. */
5184 for (j = 0; j < MAX_NUM_LEADERS; j++) {
5185 const char *sexstr;
5186 sex_t sex;
5187 bool is_male = FALSE;
5188
5189 name = secfile_lookup_str(file, "%s.leaders%d.name", sec_name, j);
5190 if (NULL == name) {
5191 /* No more to read. */
5192 break;
5193 }
5194
5195 if (check_name(name)) {
5196 /* The ruleset contains a name that is too long. This shouldn't
5197 * happen - if it does, the author should get immediate feedback */
5198 sz_strlcpy(temp_name, name);
5199 ruleset_error(NULL, LOG_ERROR,
5200 "Nation %s: leader name \"%s\" is too long.",
5201 nation_rule_name(pnation), name);
5202 ok = FALSE;
5203 break;
5204 }
5205
5206 sexstr = secfile_lookup_str(file, "%s.leaders%d.sex", sec_name, j);
5207 if (NULL == sexstr) {
5208 ruleset_error(NULL, LOG_ERROR,
5209 "Nation %s: leader \"%s\": %s.",
5210 nation_rule_name(pnation), name, secfile_error());
5211 ok = FALSE;
5212 break;
5213 }
5214
5215 sex = sex_by_name(sexstr);
5216
5217 switch (sex) {
5218 case SEX_MALE:
5219 is_male = TRUE;
5220 break;
5221 case SEX_FEMALE:
5222 is_male = FALSE;
5223 break;
5224 case SEX_UNKNOWN:
5225 ruleset_error(NULL, LOG_ERROR,
5226 "Nation %s: leader \"%s\" has unsupported "
5227 "sex variant \"%s\".",
5228 nation_rule_name(pnation), name, sexstr);
5229 ok = FALSE;
5230 break;
5231 }
5232
5233 if (ok) {
5234 (void) nation_leader_new(pnation, name, is_male);
5235 }
5236 }
5237 if (!ok) {
5238 break;
5239 }
5240
5241 /* Check the number of leaders. */
5242 if (MAX_NUM_LEADERS == j) {
5243 /* Too much leaders, get the real number defined in the ruleset. */
5244 while (NULL != secfile_entry_lookup(file, "%s.leaders%d.name",
5245 sec_name, j)) {
5246 j++;
5247 }
5248 ruleset_error(NULL, LOG_ERROR,
5249 "Nation %s: Too many leaders; max is %d",
5250 nation_rule_name(pnation), MAX_NUM_LEADERS);
5251 ok = FALSE;
5252 break;
5253 } else if (0 == j) {
5254 ruleset_error(NULL, LOG_ERROR,
5255 "Nation %s: no leaders; at least one is required.",
5256 nation_rule_name(pnation));
5257 ok = FALSE;
5258 break;
5259 }
5260
5261 /* Check if leader name is not already defined in this nation. */
5262 if ((bad_leader = check_leader_names(pnation))) {
5263 ruleset_error(NULL, LOG_ERROR,
5264 "Nation %s: leader \"%s\" defined more than once.",
5265 nation_rule_name(pnation), bad_leader);
5266 ok = FALSE;
5267 break;
5268 }
5269
5270 /* Nation player color preference, if any */
5271 fc_assert_ret_val(pnation->server.rgb == NULL, FALSE);
5272 (void) rgbcolor_load(file, &pnation->server.rgb, "%s.color", sec_name);
5273
5274 /* Load nation traits */
5275 ruleset_load_traits(pnation->server.traits, file, sec_name, "trait_");
5276 for (tr = trait_begin(); tr != trait_end(); tr = trait_next(tr)) {
5277 bool server_traits_used = TRUE;
5278
5279 if (pnation->server.traits[tr].min < 0) {
5280 pnation->server.traits[tr].min = game.server.default_traits[tr].min;
5281 } else {
5282 server_traits_used = FALSE;
5283 }
5284 if (pnation->server.traits[tr].max < 0) {
5285 pnation->server.traits[tr].max = game.server.default_traits[tr].max;
5286 } else {
5287 server_traits_used = FALSE;
5288 }
5289 if (pnation->server.traits[tr].fixed < 0) {
5290 if (server_traits_used) {
5291 pnation->server.traits[tr].fixed = game.server.default_traits[tr].fixed;
5292 } else {
5293 int diff = pnation->server.traits[tr].max - pnation->server.traits[tr].min;
5294
5295 /* TODO: Should sometimes round the a / 2 = x.5 results up */
5296 pnation->server.traits[tr].fixed = diff / 2 + pnation->server.traits[tr].min;
5297 }
5298 }
5299 if (pnation->server.traits[tr].max < pnation->server.traits[tr].min) {
5300 ruleset_error(NULL, LOG_ERROR,
5301 "%s values for trait %s not sane.",
5302 nation_rule_name(pnation), trait_name(tr));
5303 ok = FALSE;
5304 break;
5305 }
5306 }
5307
5308 if (!ok) {
5309 break;
5310 }
5311
5312 pnation->is_playable =
5313 secfile_lookup_bool_default(file, TRUE, "%s.is_playable", sec_name);
5314
5315 /* Check barbarian type. Default is "None" meaning not a barbarian */
5316 barb_type = secfile_lookup_str_default(file, "None",
5317 "%s.barbarian_type", sec_name);
5318 pnation->barb_type = barbarian_type_by_name(barb_type, fc_strcasecmp);
5319 if (!barbarian_type_is_valid(pnation->barb_type)) {
5320 ruleset_error(NULL, LOG_ERROR,
5321 "Nation %s, barbarian_type is invalid (\"%s\")",
5322 nation_rule_name(pnation), barb_type);
5323 ok = FALSE;
5324 break;
5325 }
5326
5327 if (pnation->barb_type != NOT_A_BARBARIAN
5328 && pnation->is_playable) {
5329 /* We can't allow players to use barbarian nations, barbarians
5330 * may run out of nations */
5331 ruleset_error(NULL, LOG_ERROR,
5332 "Nation %s marked both barbarian and playable.",
5333 nation_rule_name(pnation));
5334 ok = FALSE;
5335 break;
5336 }
5337
5338 /* Flags */
5339 sz_strlcpy(pnation->flag_graphic_str,
5340 secfile_lookup_str_default(file, "-", "%s.flag", sec_name));
5341 sz_strlcpy(pnation->flag_graphic_alt,
5342 secfile_lookup_str_default(file, "-",
5343 "%s.flag_alt", sec_name));
5344
5345 /* Ruler titles */
5346 for (j = 0;; j++) {
5347 const char *male, *female;
5348
5349 name = secfile_lookup_str_default(file, NULL,
5350 "%s.ruler_titles%d.government",
5351 sec_name, j);
5352 if (NULL == name) {
5353 /* End of the list of ruler titles. */
5354 break;
5355 }
5356
5357 /* NB: even if the government doesn't exist, we load the entries for
5358 * the ruler titles to avoid warnings about unused entries. */
5359 male = secfile_lookup_str(file, "%s.ruler_titles%d.male_title",
5360 sec_name, j);
5361 female = secfile_lookup_str(file, "%s.ruler_titles%d.female_title",
5362 sec_name, j);
5363 gov = government_by_rule_name(name);
5364
5365 /* Nationset may have been devised with a specific set of govs in
5366 * mind which don't quite match this ruleset, in which case we
5367 * (a) quietly ignore any govs mentioned that don't happen to be in
5368 * the current ruleset, (b) enforce that govs mentioned by nations
5369 * must be on the list */
5370 if (gov != NULL && game.server.ruledit.allowed_govs != NULL) {
5371 if (!is_on_allowed_list(name,
5372 game.server.ruledit.allowed_govs,
5373 game.server.ruledit.ag_count)) {
5374 /* Gov exists, but not intended for these nations */
5375 gov = NULL;
5376 ruleset_error(NULL, LOG_ERROR,
5377 "Nation %s: government \"%s\" not in allowed_govs.",
5378 nation_rule_name(pnation), name);
5379 ok = FALSE;
5380 break;
5381 }
5382 } else if (!gov) {
5383 /* Gov doesn't exist; only complain if it's not on any list */
5384 if (game.server.ruledit.allowed_govs == NULL
5385 || !is_on_allowed_list(name,
5386 game.server.ruledit.allowed_govs,
5387 game.server.ruledit.ag_count)) {
5388 ruleset_error(NULL, LOG_ERROR,
5389 "Nation %s: government \"%s\" not found.",
5390 nation_rule_name(pnation), name);
5391 ok = FALSE;
5392 break;
5393 }
5394 }
5395 if (NULL != male && NULL != female) {
5396 if (gov) {
5397 (void) government_ruler_title_new(gov, pnation, male, female);
5398 }
5399 } else {
5400 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
5401 ok = FALSE;
5402 break;
5403 }
5404 }
5405 if (!ok) {
5406 break;
5407 }
5408
5409 /* City styles */
5410 name = secfile_lookup_str(file, "%s.style", sec_name);
5411 if (!name) {
5412 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
5413 ok = FALSE;
5414 break;
5415 }
5416 pnation->style = style_by_rule_name(name);
5417 if (pnation->style == NULL) {
5418 if (game.server.ruledit.allowed_styles == NULL
5419 || !is_on_allowed_list(name,
5420 game.server.ruledit.allowed_styles,
5421 game.server.ruledit.as_count)) {
5422 ruleset_error(NULL, LOG_ERROR,
5423 "Nation %s: Illegal style \"%s\"",
5424 nation_rule_name(pnation), name);
5425 ok = FALSE;
5426 break;
5427 } else {
5428 log_verbose("Nation %s: style \"%s\" not supported in this "
5429 "ruleset; using default.",
5430 nation_rule_name(pnation), name);
5431 pnation->style = style_by_number(0);
5432 }
5433 }
5434
5435 /* Civilwar nations */
5436 vec = secfile_lookup_str_vec(file, &dim,
5437 "%s.civilwar_nations", sec_name);
5438 for (j = 0; j < dim; j++) {
5439 pconflict = nation_by_rule_name(vec[j]);
5440
5441 /* No test for duplicate nations is performed. If there is a duplicate
5442 * entry it will just cause that nation to have an increased
5443 * probability of being chosen. */
5444 if (pconflict == pnation) {
5445 ruleset_error(NULL, LOG_ERROR,
5446 "Nation %s is its own civil war nation",
5447 nation_rule_name(pnation));
5448 ok = FALSE;
5449 break;
5450 } else if (NULL != pconflict) {
5451 nation_list_append(pnation->server.civilwar_nations, pconflict);
5452 nation_list_append(pconflict->server.parent_nations, pnation);
5453 } else {
5454 /* For nation authors, this would probably be considered an error.
5455 * But it can happen normally. The civ1 compatibility ruleset only
5456 * uses the nations that were in civ1, so not all of the links will
5457 * exist. */
5458 log_verbose("Nation %s: civil war nation \"%s\" is unknown.",
5459 nation_rule_name(pnation), vec[j]);
5460 }
5461 }
5462 if (NULL != vec) {
5463 free(vec);
5464 }
5465 if (!ok) {
5466 break;
5467 }
5468
5469 /* Load nation specific initial items */
5470 if (!lookup_tech_list(file, sec_name, "init_techs",
5471 pnation->init_techs, filename)) {
5472 ok = FALSE;
5473 break;
5474 }
5475 if (!lookup_building_list(file, sec_name, "init_buildings",
5476 pnation->init_buildings, filename)) {
5477 ok = FALSE;
5478 break;
5479 }
5480 if (!lookup_unit_list(file, sec_name, "init_units",
5481 pnation->init_units, filename)) {
5482 ok = FALSE;
5483 break;
5484 }
5485 fc_strlcat(tmp, sec_name, 200);
5486 fc_strlcat(tmp, ".init_government", 200);
5487 if (secfile_entry_by_path(file, tmp)) {
5488 pnation->init_government = lookup_government(file, tmp, filename,
5489 NULL);
5490 /* If specified, init_government has to be in this specific ruleset,
5491 * not just allowed_govs */
5492 if (pnation->init_government == NULL) {
5493 ok = FALSE;
5494 break;
5495 }
5496 /* ...but if a list of govs has been specified, enforce that this
5497 * nation's init_government is on the list. */
5498 if (game.server.ruledit.allowed_govs != NULL
5499 && !is_on_allowed_list(government_rule_name(pnation->init_government),
5500 game.server.ruledit.allowed_govs,
5501 game.server.ruledit.ag_count)) {
5502 ruleset_error(NULL, LOG_ERROR,
5503 "Nation %s: init_government \"%s\" not allowed.",
5504 nation_rule_name(pnation),
5505 government_rule_name(pnation->init_government));
5506 ok = FALSE;
5507 break;
5508 }
5509 }
5510
5511 /* Read default city names. */
5512 if (!load_city_name_list(file, pnation, sec_name, "cities",
5513 game.server.ruledit.allowed_terrains,
5514 game.server.ruledit.at_count)) {
5515 ok = FALSE;
5516 break;
5517 }
5518
5519 legend = secfile_lookup_str_default(file, "", "%s.legend", sec_name);
5520 pnation->legend = fc_strdup(legend);
5521 if (check_strlen(pnation->legend, MAX_LEN_MSG, NULL)) {
5522 ruleset_error(NULL, LOG_ERROR,
5523 "Nation %s: legend \"%s\" is too long.",
5524 nation_rule_name(pnation),
5525 pnation->legend);
5526 ok = FALSE;
5527 break;
5528 }
5529
5530 pnation->player = NULL;
5531 } nations_iterate_end;
5532 section_list_destroy(sec);
5533 sec = NULL;
5534 }
5535
5536 /* Clean up on aborted load */
5537 if (sec != NULL) {
5538 fc_assert(!ok);
5539 section_list_destroy(sec);
5540 }
5541
5542 if (ok) {
5543 secfile_check_unused(file);
5544 }
5545
5546 if (ok) {
5547 /* Update cached number of playable nations in the current set */
5548 count_playable_nations();
5549
5550 /* Sanity checks on all sets */
5551 nation_sets_iterate(pset) {
5552 int num_playable = 0, barb_land_count = 0, barb_sea_count = 0, barb_both_count = 0;
5553
5554 nations_iterate(pnation) {
5555 if (nation_is_in_set(pnation, pset)) {
5556 switch (nation_barbarian_type(pnation)) {
5557 case NOT_A_BARBARIAN:
5558 if (is_nation_playable(pnation)) {
5559 num_playable++;
5560 }
5561 break;
5562 case LAND_BARBARIAN:
5563 barb_land_count++;
5564 break;
5565 case SEA_BARBARIAN:
5566 barb_sea_count++;
5567 break;
5568 case ANIMAL_BARBARIAN:
5569 /* Animals are optional */
5570 break;
5571 case LAND_AND_SEA_BARBARIAN:
5572 barb_both_count++;
5573 break;
5574 default:
5575 fc_assert_ret_val(FALSE, FALSE);
5576 }
5577 }
5578 } nations_iterate_end;
5579 if (num_playable < 1) {
5580 ruleset_error(NULL, LOG_ERROR,
5581 "Nation set \"%s\" has no playable nations. "
5582 "At least one required!", nation_set_rule_name(pset));
5583 ok = FALSE;
5584 break;
5585 }
5586 if (barb_land_count == 0 && barb_both_count == 0) {
5587 ruleset_error(NULL, LOG_ERROR,
5588 "No land barbarian nation defined in set \"%s\". "
5589 "At least one required!", nation_set_rule_name(pset));
5590 ok = FALSE;
5591 break;
5592 }
5593 if (barb_sea_count == 0 && barb_both_count == 0) {
5594 ruleset_error(NULL, LOG_ERROR,
5595 "No sea barbarian nation defined in set \"%s\". "
5596 "At least one required!", nation_set_rule_name(pset));
5597 ok = FALSE;
5598 break;
5599 }
5600 } nation_sets_iterate_end;
5601 }
5602
5603 return ok;
5604}
5605
5606/**********************************************************************/
5610 static bool load_style_names(struct section_file *file,
5611 struct rscompat_info *compat)
5612{
5613 bool ok = TRUE;
5614 struct section_list *sec;
5615 const char *filename = secfile_name(file);
5616
5617 if (!rscompat_check_cap_and_version(file, filename, compat)) {
5618 return FALSE;
5619 }
5620
5621 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
5622 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
5623
5624 sec = secfile_sections_by_name_prefix(file, STYLE_SECTION_PREFIX);
5625 if (NULL == sec) {
5626 ruleset_error(NULL, LOG_ERROR,
5627 "No available nation styles in this ruleset!");
5628 ok = FALSE;
5629 } else {
5630 game.control.num_styles = section_list_size(sec);
5631
5632 styles_alloc(game.control.num_styles);
5633
5634 styles_iterate(ps) {
5635 const int i = style_index(ps);
5636 const char *sec_name = section_name(section_list_get(sec, i));
5637
5638 ruleset_load_names(&ps->name, NULL, file, sec_name);
5639 } styles_iterate_end;
5640 }
5641
5642 section_list_destroy(sec);
5643
5644 if (ok) {
5645 /* The citystyle sections: */
5646 int i = 0;
5647
5648 sec = secfile_sections_by_name_prefix(file, CITYSTYLE_SECTION_PREFIX);
5649 if (NULL != sec) {
5650 city_styles_alloc(section_list_size(sec));
5651 section_list_iterate(sec, style) {
5652 if (!ruleset_load_names(&city_styles[i].name, NULL, file, section_name(style))) {
5653 ok = FALSE;
5654 break;
5655 }
5656 i++;
5657 } section_list_iterate_end;
5658
5659 section_list_destroy(sec);
5660 } else {
5661 city_styles_alloc(0);
5662 }
5663 }
5664
5665 return ok;
5666}
5667
5668/**********************************************************************/
5671 static bool load_ruleset_styles(struct section_file *file,
5672 struct rscompat_info *compat)
5673{
5674 struct section_list *sec;
5675 int i;
5676 bool ok = TRUE;
5677
5678 /* City Styles ... */
5679
5680 sec = secfile_sections_by_name_prefix(file, CITYSTYLE_SECTION_PREFIX);
5681
5682 /* Get rest: */
5683 for (i = 0; i < game.control.num_city_styles; i++) {
5684 struct requirement_vector *reqs;
5685 const char *sec_name = section_name(section_list_get(sec, i));
5686
5687 sz_strlcpy(city_styles[i].graphic,
5688 secfile_lookup_str(file, "%s.graphic", sec_name));
5689 sz_strlcpy(city_styles[i].graphic_alt,
5690 secfile_lookup_str(file, "%s.graphic_alt", sec_name));
5691 sz_strlcpy(city_styles[i].citizens_graphic,
5692 secfile_lookup_str_default(file, "-",
5693 "%s.citizens_graphic", sec_name));
5694
5695 reqs = lookup_req_list(file, compat, sec_name, "reqs", city_style_rule_name(i));
5696 if (reqs == NULL) {
5697 ok = FALSE;
5698 break;
5699 }
5700 requirement_vector_copy(&city_styles[i].reqs, reqs);
5701 }
5702
5703 section_list_destroy(sec);
5704
5705 if (ok) {
5706 sec = secfile_sections_by_name_prefix(file, MUSICSTYLE_SECTION_PREFIX);
5707
5708 if (sec != NULL) {
5709 int musi;
5710
5711 game.control.num_music_styles = section_list_size(sec);
5712 music_styles_alloc(game.control.num_music_styles);
5713 musi = 0;
5714
5715 section_list_iterate(sec, psection) {
5716 struct requirement_vector *reqs;
5717 struct music_style *pmus = music_style_by_number(musi);
5718 const char *sec_name = section_name(psection);
5719
5720 sz_strlcpy(pmus->music_peaceful,
5721 secfile_lookup_str_default(file, "-",
5722 "%s.music_peaceful", sec_name));
5723 sz_strlcpy(pmus->music_combat,
5724 secfile_lookup_str_default(file, "-",
5725 "%s.music_combat", sec_name));
5726
5727 reqs = lookup_req_list(file, compat, sec_name, "reqs", "Music Style");
5728 if (reqs == NULL) {
5729 ok = FALSE;
5730 break;
5731 }
5732 requirement_vector_copy(&pmus->reqs, reqs);
5733
5734 musi++;
5735 } section_list_iterate_end;
5736 }
5737
5738 section_list_destroy(sec);
5739 }
5740
5741 return ok;
5742}
5743
5744/**********************************************************************/
5749 static bool load_action_auto_uflag_block(struct section_file *file,
5750 struct action_auto_perf *auto_perf,
5751 const char *uflags_path,
5752 const char *filename)
5753{
5754 /* Add each listed protected unit type flag as a !present
5755 * requirement. */
5756 if (secfile_entry_lookup(file, "%s", uflags_path)) {
5757 enum unit_type_flag_id *protecor_flag;
5758 size_t psize;
5759 int i;
5760
5761 protecor_flag =
5762 secfile_lookup_enum_vec(file, &psize, unit_type_flag_id,
5763 "%s", uflags_path);
5764
5765 if (!protecor_flag) {
5766 /* Entity exists but couldn't read it. */
5767 ruleset_error(NULL, LOG_ERROR,
5768 "\"%s\": %s: bad unit type flag list.",
5769 filename, uflags_path);
5770
5771 return FALSE;
5772 }
5773
5774 for (i = 0; i < psize; i++) {
5775 requirement_vector_append(&auto_perf->reqs,
5776 req_from_values(VUT_UTFLAG,
5777 REQ_RANGE_LOCAL,
5778 FALSE, FALSE, TRUE,
5779 protecor_flag[i]));
5780 }
5781
5782 free(protecor_flag);
5783 }
5784
5785 return TRUE;
5786}
5787
5788/**********************************************************************/
5792 static bool load_action_auto_actions(struct section_file *file,
5793 struct action_auto_perf *auto_perf,
5794 const char *actions_path,
5795 const char *filename)
5796{
5797 /* Read the alternative actions. */
5798 if (secfile_entry_lookup(file, "%s", actions_path)) {
5799 enum gen_action *unit_acts;
5800 size_t asize;
5801 int i;
5802
5803 unit_acts = secfile_lookup_enum_vec(file, &asize, gen_action,
5804 "%s", actions_path);
5805
5806 if (!unit_acts) {
5807 /* Entity exists but couldn't read it. */
5808 ruleset_error(NULL, LOG_ERROR,
5809 "\"%s\": %s: bad action list",
5810 filename, actions_path);
5811
5812 return FALSE;
5813 }
5814
5815 for (i = 0; i < asize; i++) {
5816 auto_perf->alternatives[i] = unit_acts[i];
5817 }
5818
5819 free(unit_acts);
5820 }
5821
5822 return TRUE;
5823}
5824
5825/**********************************************************************/
5828 static bool load_muuk_as_action_auto(struct section_file *file,
5829 struct action_auto_perf *auto_perf,
5830 const char *item,
5831 const char *filename)
5832{
5833 char uflags_path[100];
5834 char action_path[100];
5835
5836 fc_snprintf(uflags_path, sizeof(uflags_path),
5837 "missing_unit_upkeep.%s_protected", item);
5838 fc_snprintf(action_path, sizeof(action_path),
5839 "missing_unit_upkeep.%s_unit_act", item);
5840
5841 return (load_action_auto_uflag_block(file, auto_perf, uflags_path,
5842 filename)
5843 && load_action_auto_actions(file, auto_perf, action_path,
5844 filename));
5845}
5846
5847/**********************************************************************/
5850 static bool load_ruleset_cities(struct section_file *file,
5851 struct rscompat_info *compat)
5852{
5853 const char *filename = secfile_name(file);
5854 const char *item;
5855 struct section_list *sec;
5856 bool ok = TRUE;
5857
5858 if (!rscompat_check_cap_and_version(file, filename, compat)) {
5859 return FALSE;
5860 }
5861
5862 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
5863 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
5864
5865 /* Specialist options */
5866 sec = secfile_sections_by_name_prefix(file, SPECIALIST_SECTION_PREFIX);
5867 if (section_list_size(sec) >= SP_MAX) {
5868 ruleset_error(NULL, LOG_ERROR,
5869 "\"%s\": Too many specialists (%d, max %d).",
5870 filename, section_list_size(sec), SP_MAX);
5871 ok = FALSE;
5872 }
5873
5874 if (ok) {
5875 int i = 0;
5876 const char *tag;
5877
5878 game.control.num_specialist_types = section_list_size(sec);
5879
5880 section_list_iterate(sec, psection) {
5881 struct specialist *s = specialist_by_number(i);
5882 struct requirement_vector *reqs;
5883 const char *sec_name = section_name(psection);
5884
5885 if (!ruleset_load_names(&s->name, NULL, file, sec_name)) {
5886 ok = FALSE;
5887 break;
5888 }
5889
5890 item = secfile_lookup_str_default(file, untranslated_name(&s->name),
5891 "%s.short_name", sec_name);
5892 name_set(&s->abbreviation, NULL, item);
5893
5894 tag = secfile_lookup_str(file, "%s.graphic", sec_name);
5895 if (tag == NULL) {
5896 ruleset_error(NULL, LOG_ERROR,
5897 "\"%s\": No graphic tag for specialist at %s.",
5898 filename, sec_name);
5899 ok = FALSE;
5900 break;
5901 }
5902 sz_strlcpy(s->graphic_str, tag);
5903 sz_strlcpy(s->graphic_alt,
5904 secfile_lookup_str_default(file, "-",
5905 "%s.graphic_alt", sec_name));
5906
5907 reqs = lookup_req_list(file, compat, sec_name, "reqs", specialist_rule_name(s));
5908 if (reqs == NULL) {
5909 ok = FALSE;
5910 break;
5911 }
5912 requirement_vector_copy(&s->reqs, reqs);
5913
5914 s->helptext = lookup_strvec(file, sec_name, "helptext");
5915
5916 if (requirement_vector_size(&s->reqs) == 0 && DEFAULT_SPECIALIST == -1) {
5917 DEFAULT_SPECIALIST = i;
5918 }
5919 i++;
5920 } section_list_iterate_end;
5921 }
5922
5923 if (ok && DEFAULT_SPECIALIST == -1) {
5924 ruleset_error(NULL, LOG_ERROR,
5925 "\"%s\": must give a min_size of 0 for at least one "
5926 "specialist type.", filename);
5927 ok = FALSE;
5928 }
5929 section_list_destroy(sec);
5930 sec = NULL;
5931
5932 if (ok) {
5933 /* City Parameters */
5934
5935 game.info.celebratesize =
5936 secfile_lookup_int_default(file, GAME_DEFAULT_CELEBRATESIZE,
5937 "parameters.celebrate_size_limit");
5938 game.info.add_to_size_limit =
5939 secfile_lookup_int_default(file, GAME_DEFAULT_ADDTOSIZE, "parameters.add_to_size_limit");
5940 game.info.angrycitizen =
5941 secfile_lookup_bool_default(file, GAME_DEFAULT_ANGRYCITIZEN,
5942 "parameters.angry_citizens");
5943
5944 game.info.changable_tax =
5945 secfile_lookup_bool_default(file, GAME_DEFAULT_CHANGABLE_TAX, "parameters.changable_tax");
5946 game.info.forced_science =
5947 secfile_lookup_int_default(file, 0, "parameters.forced_science");
5948 game.info.forced_luxury =
5949 secfile_lookup_int_default(file, 100, "parameters.forced_luxury");
5950 game.info.forced_gold =
5951 secfile_lookup_int_default(file, 0, "parameters.forced_gold");
5952 if (game.info.forced_science + game.info.forced_luxury
5953 + game.info.forced_gold != 100) {
5954 ruleset_error(NULL, LOG_ERROR,
5955 "\"%s\": Forced taxes do not add up in ruleset!",
5956 filename);
5957 ok = FALSE;
5958 }
5959 }
5960
5961 if (ok) {
5962 /* civ1 & 2 didn't reveal tiles */
5963 game.server.vision_reveal_tiles =
5964 secfile_lookup_bool_default(file, GAME_DEFAULT_VISION_REVEAL_TILES,
5965 "parameters.vision_reveal_tiles");
5966
5967 game.info.pop_report_zeroes =
5968 secfile_lookup_int_default(file, 1, "parameters.pop_report_zeroes");
5969
5970 /* Citizens configuration. */
5971 game.info.citizen_nationality =
5972 secfile_lookup_bool_default(file, RS_DEFAULT_NATIONALITY,
5973 "citizen.nationality");
5974 game.info.unit_builders_nationality =
5975 secfile_lookup_bool_default(file, FALSE,
5976 "citizen.ubuilder_nationality");
5977 game.info.citizen_convert_speed =
5978 secfile_lookup_int_default(file, RS_DEFAULT_CONVERT_SPEED,
5979 "citizen.convert_speed");
5980 game.info.citizen_partisans_pct =
5981 secfile_lookup_int_default(file, 0, "citizen.partisans_pct");
5982 game.info.conquest_convert_pct =
5983 secfile_lookup_int_default(file, 0, "citizen.conquest_convert_pct");
5984 }
5985
5986 if (ok) {
5987 /* Missing unit upkeep. */
5988 struct action_auto_perf *auto_perf;
5989
5990 /* Can't pay food upkeep! */
5991 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_UPKEEP_FOOD);
5992 auto_perf->cause = AAPC_UNIT_UPKEEP;
5993
5994 /* This is about food upkeep. */
5995 requirement_vector_append(&auto_perf->reqs,
5996 req_from_str("OutputType", "Local",
5997 FALSE, TRUE, TRUE,
5998 "Food"));
5999
6000 /* Internally represented as an action auto performer rule. */
6001 if (!load_muuk_as_action_auto(file, auto_perf, "food", filename)) {
6002 ok = FALSE;
6003 }
6004
6005 game.info.muuk_food_wipe =
6006 secfile_lookup_bool_default(file, RS_DEFAULT_MUUK_FOOD_WIPE,
6007 "missing_unit_upkeep.food_wipe");
6008
6009 /* Can't pay gold upkeep! */
6010 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_UPKEEP_GOLD);
6011 auto_perf->cause = AAPC_UNIT_UPKEEP;
6012
6013 /* This is about gold upkeep. */
6014 requirement_vector_append(&auto_perf->reqs,
6015 req_from_str("OutputType", "Local",
6016 FALSE, TRUE, TRUE,
6017 "Gold"));
6018
6019 /* Internally represented as an action auto performer rule. */
6020 if (!load_muuk_as_action_auto(file, auto_perf, "gold", filename)) {
6021 ok = FALSE;
6022 }
6023
6024 game.info.muuk_gold_wipe =
6025 secfile_lookup_bool_default(file, RS_DEFAULT_MUUK_GOLD_WIPE,
6026 "missing_unit_upkeep.gold_wipe");
6027
6028 /* Can't pay shield upkeep! */
6029 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_UPKEEP_SHIELD);
6030 auto_perf->cause = AAPC_UNIT_UPKEEP;
6031
6032 /* This is about shield upkeep. */
6033 requirement_vector_append(&auto_perf->reqs,
6034 req_from_str("OutputType", "Local",
6035 FALSE, TRUE, TRUE,
6036 "Shield"));
6037
6038 /* Internally represented as an action auto performer rule. */
6039 if (!load_muuk_as_action_auto(file, auto_perf, "shield", filename)) {
6040 ok = FALSE;
6041 }
6042
6043 game.info.muuk_shield_wipe =
6044 secfile_lookup_bool_default(file, RS_DEFAULT_MUUK_SHIELD_WIPE,
6045 "missing_unit_upkeep.shield_wipe");
6046 }
6047
6048 if (ok) {
6049 secfile_check_unused(file);
6050 }
6051
6052 return ok;
6053}
6054
6055/**********************************************************************/
6058 static bool load_ruleset_effects(struct section_file *file,
6059 struct rscompat_info *compat)
6060{
6061 struct section_list *sec;
6062 const char *filename;
6063 bool ok = TRUE;
6064
6065 filename = secfile_name(file);
6066
6067 if (!rscompat_check_cap_and_version(file, filename, compat)) {
6068 return FALSE;
6069 }
6070
6071 (void) secfile_entry_by_path(file, "datafile.description"); /* unused */
6072 (void) secfile_entry_by_path(file, "datafile.ruledit"); /* unused */
6073
6074 sec = secfile_sections_by_name_prefix(file, UEFF_SECTION_PREFIX);
6075
6076 if (sec != NULL) {
6077 section_list_iterate(sec, psection) {
6078 const char *sec_name = section_name(psection);
6079 enum effect_type main_type;
6080 enum effect_type ai_valued_as;
6081 const char *type;
6082
6083 type = secfile_lookup_str(file, "%s.type", sec_name);
6084 if (type == NULL) {
6085 ruleset_error(NULL, LOG_ERROR,
6086 "\"%s\" [%s] missing effect type.",
6087 filename, sec_name);
6088 ok = FALSE;
6089 break;
6090 }
6091 main_type = effect_type_by_name(type, fc_strcasecmp);
6092 if (!effect_type_is_valid(main_type)) {
6093 ruleset_error(NULL, LOG_ERROR,
6094 "\"%s\" [%s] lists unknown effect type \"%s\".",
6095 filename, sec_name, type);
6096 ok = FALSE;
6097 break;
6098 }
6099 if (!is_user_effect(main_type)) {
6100 ruleset_error(NULL, LOG_ERROR,
6101 "\"%s\" [%s] type \"%s\" is not an user effect.",
6102 filename, sec_name, type);
6103 ok = FALSE;
6104 break;
6105 }
6106
6107 type = secfile_lookup_str(file, "%s.ai_valued_as", sec_name);
6108 if (type == NULL) {
6109 ruleset_error(NULL, LOG_ERROR,
6110 "\"%s\" [%s] missing ai_valued_as.",
6111 filename, sec_name);
6112 ok = FALSE;
6113 break;
6114 }
6115 ai_valued_as = effect_type_by_name(type, fc_strcasecmp);
6116 if (!effect_type_is_valid(ai_valued_as)) {
6117 ruleset_error(NULL, LOG_ERROR,
6118 "\"%s\" [%s] lists unknown ai_valued_as \"%s\".",
6119 filename, sec_name, type);
6120 ok = FALSE;
6121 break;
6122 }
6123 if (is_user_effect(ai_valued_as)) {
6124 ruleset_error(NULL, LOG_ERROR,
6125 "\"%s\" [%s] ai_valued_as \"%s\" is an user effect.",
6126 filename, sec_name, type);
6127 ok = FALSE;
6128 break;
6129 }
6130
6131 if (user_effect_ai_valued_as(main_type) != main_type) {
6132 /* It has been set already! */
6133 ruleset_error(NULL, LOG_ERROR,
6134 "\"%s\" [%s] Duplicate \"%s\" entry.",
6135 filename, sec_name, type);
6136 ok = FALSE;
6137 break;
6138 }
6139
6140 user_effect_ai_valued_set(main_type, ai_valued_as);
6141 } section_list_iterate_end;
6142
6143 section_list_destroy(sec);
6144 }
6145
6146 /* Parse effects and add them to the effects ruleset cache. */
6147 sec = secfile_sections_by_name_prefix(file, EFFECT_SECTION_PREFIX);
6148 section_list_iterate(sec, psection) {
6149 enum effect_type eff;
6150 int value;
6151 struct multiplier *pmul;
6152 struct effect *peffect;
6153 const char *sec_name = section_name(psection);
6154 struct requirement_vector *reqs;
6155 const char *type;
6156 const char *comment;
6157
6158 type = secfile_lookup_str(file, "%s.type", sec_name);
6159
6160 if (type == NULL) {
6161 ruleset_error(NULL, LOG_ERROR,
6162 "\"%s\" [%s] missing effect type.",
6163 filename, sec_name);
6164 ok = FALSE;
6165 break;
6166 }
6167
6168 eff = effect_type_by_name(type, fc_strcasecmp);
6169 if (!effect_type_is_valid(eff)) {
6170 ruleset_error(NULL, LOG_ERROR,
6171 "\"%s\" [%s] lists unknown effect type \"%s\".",
6172 filename, sec_name, type);
6173 ok = FALSE;
6174 break;
6175 }
6176
6177 value = secfile_lookup_int_default(file, 1, "%s.value", sec_name);
6178
6179 {
6180 const char *multiplier_name
6181 = secfile_lookup_str(file, "%s.multiplier", sec_name);
6182
6183 if (multiplier_name) {
6184 pmul = multiplier_by_rule_name(multiplier_name);
6185 if (!pmul) {
6186 ruleset_error(NULL, LOG_ERROR,
6187 "\"%s\" [%s] has unknown multiplier \"%s\".",
6188 filename, sec_name, multiplier_name);
6189 ok = FALSE;
6190 break;
6191 }
6192 } else {
6193 pmul = NULL;
6194 }
6195 }
6196
6197 peffect = effect_new(eff, value, pmul);
6198
6199 reqs = lookup_req_list(file, compat, sec_name, "reqs", type);
6200 if (reqs == NULL) {
6201 ok = FALSE;
6202 break;
6203 }
6204
6205 requirement_vector_iterate(reqs, preq) {
6206 effect_req_append(peffect, *preq);
6207 } requirement_vector_iterate_end;
6208
6209 comment = secfile_lookup_str_default(file, NULL, "%s.comment", sec_name);
6210
6211 if (comment != NULL) {
6212 peffect->rulesave.comment = fc_strdup(comment);
6213 }
6214
6215 } section_list_iterate_end;
6216 section_list_destroy(sec);
6217
6218 if (ok) {
6219 secfile_check_unused(file);
6220 }
6221
6222 return ok;
6223}
6224
6225/**********************************************************************/
6228static int secfile_lookup_int_default_min_max(struct section_file *file,
6229 int def, int min, int max,
6230 const char *path, ...)
6231 fc__attribute((__format__ (__printf__, 5, 6)));
6232 static int secfile_lookup_int_default_min_max(struct section_file *file,
6233 int def, int min, int max,
6234 const char *path, ...)
6235{
6236 char fullpath[256];
6237 int ival;
6238 va_list args;
6239
6240 va_start(args, path);
6241 fc_vsnprintf(fullpath, sizeof(fullpath), path, args);
6242 va_end(args);
6243
6244 if (!secfile_lookup_int(file, &ival, "%s", fullpath)) {
6245 ival = def;
6246 }
6247
6248 if (ival < min) {
6249 ruleset_error(NULL, LOG_ERROR,
6250 "\"%s\" should be in the interval [%d, %d] "
6251 "but is %d; using the minimal value.",
6252 fullpath, min, max, ival);
6253 ival = min;
6254 }
6255
6256 if (ival > max) {
6257 ruleset_error(NULL, LOG_ERROR,
6258 "\"%s\" should be in the interval [%d, %d] "
6259 "but is %d; using the maximal value.",
6260 fullpath, min, max, ival);
6261 ival = max;
6262 }
6263
6264 return ival;
6265}
6266
6267/**********************************************************************/
6270 static bool load_action_ui_name(struct section_file *file, int act,
6271 const char *entry_name)
6272{
6273 const char *text;
6274 const char *def = action_ui_name_default(act);
6275
6276 if (entry_name == NULL) {
6277 text = def;
6278 } else {
6279 text = secfile_lookup_str_default(file, def,
6280 "actions.%s", entry_name);
6281 }
6282
6283 sz_strlcpy(action_by_number(act)->ui_name, text);
6284
6285 return TRUE;
6286}
6287
6288/**********************************************************************/
6291 static bool load_action_range_max(struct section_file *file, action_id act)
6292{
6293 struct action *paction = action_by_number(act);
6294 const char *vname = action_max_range_ruleset_var_name(act);
6295
6296 if (vname != NULL) {
6297 struct entry *pentry;
6298 int max_range;
6299
6300 pentry = secfile_entry_lookup(file, "actions.%s", vname);
6301
6302 if (pentry == NULL) {
6303 max_range = actres_max_range_default(paction->result);
6304 } else {
6305 const char *custom;
6306
6307 if (entry_type_get(pentry) == ENTRY_INT
6308 && entry_int_get(pentry, &max_range)) {
6309 /* max_range already assigned */
6310 } else if (entry_type_get(pentry) == ENTRY_STR
6311 && entry_str_get(pentry, &custom)
6312 && !fc_strcasecmp(custom, RS_ACTION_NO_MAX_DISTANCE)) {
6313 max_range = ACTION_DISTANCE_UNLIMITED;
6314 } else {
6315 ruleset_error(NULL, LOG_ERROR, "Bad actions.%s",
6316 action_max_range_ruleset_var_name(act));
6317 action_by_number(act)->max_distance = actres_max_range_default(paction->result);
6318
6319 return FALSE;
6320 }
6321 }
6322
6323 action_by_number(act)->max_distance = max_range;
6324 }
6325
6326 return TRUE;
6327}
6328
6329/**********************************************************************/
6332 static bool load_action_range(struct section_file *file, action_id act)
6333{
6334 struct action *paction = action_by_number(act);
6335 const char *vname;
6336
6337 if (!load_action_range_max(file, act)) {
6338 return FALSE;
6339 }
6340
6341 vname = action_min_range_ruleset_var_name(act);
6342 if (vname != NULL) {
6343 /* Min range can be loaded from the ruleset. */
6344 action_by_number(act)->min_distance
6345 = secfile_lookup_int_default(file,
6346 actres_min_range_default(paction->result),
6347 "actions.%s",
6348 vname);
6349 }
6350
6351 return TRUE;
6352}
6353
6354/**********************************************************************/
6357 static bool load_action_kind(struct section_file *file, action_id act)
6358{
6359 struct action *paction = action_by_number(act);
6360
6361 if (action_target_kind_ruleset_var_name(act) == NULL) {
6362 /* Target kind can't be loaded from the ruleset. */
6363 }
6364
6365 action_by_number(act)->target_kind
6366 = secfile_lookup_enum_default(file,
6367 actres_target_kind_default(
6368 paction->result),
6369 action_target_kind,
6370 "actions.%s",
6371 action_target_kind_ruleset_var_name(act));
6372
6373 return TRUE;
6374}
6375
6376/**********************************************************************/
6379 static bool load_action_actor_consuming_always(struct section_file *file,
6380 action_id act)
6381{
6382 if (action_actor_consuming_always_ruleset_var_name(act) != NULL) {
6383 /* Actor consumption can be loaded from the ruleset. */
6384 action_by_number(act)->actor_consuming_always
6385 = secfile_lookup_bool_default(
6386 file, RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS, "actions.%s",
6387 action_actor_consuming_always_ruleset_var_name(act));
6388 }
6389
6390 return TRUE;
6391}
6392
6393/**********************************************************************/
6396 static bool load_action_blocked_by_list(struct section_file *file,
6397 const char *filename,
6398 struct action *paction)
6399{
6400 if (action_blocked_by_ruleset_var_name(paction) != NULL) {
6401 /* Action blocking can be loaded from the ruleset. */
6402
6403 char fullpath[1024];
6404
6405 fc_snprintf(fullpath, sizeof(fullpath), "actions.%s",
6406 action_blocked_by_ruleset_var_name(paction));
6407
6408 if (secfile_entry_by_path(file, fullpath)) {
6409 enum gen_action *blocking_actions;
6410 size_t asize;
6411 int j;
6412
6413 blocking_actions =
6414 secfile_lookup_enum_vec(file, &asize, gen_action, "%s", fullpath);
6415
6416 if (!blocking_actions) {
6417 /* Entity exists but couldn't read it. */
6418 ruleset_error(NULL, LOG_ERROR,
6419 "\"%s\": %s: bad action list",
6420 filename, fullpath);
6421
6422 return FALSE;
6423 }
6424
6425 for (j = 0; j < asize; j++) {
6426 BV_SET(paction->blocked_by, blocking_actions[j]);
6427 }
6428
6429 free(blocking_actions);
6430 }
6431 }
6432
6433 return TRUE;
6434}
6435
6436/**********************************************************************/
6440 static bool load_action_post_success_force(struct section_file *file,
6441 const char *filename,
6442 int performer_slot,
6443 struct action *paction)
6444{
6445 struct action_auto_perf *auto_perf;
6446 char action_list_path[100];
6447
6448 if (action_post_success_forced_ruleset_var_name(paction) == NULL) {
6449 /* Not relevant. */
6450 return TRUE;
6451 }
6452
6453 auto_perf = action_auto_perf_slot_number(performer_slot);
6454 auto_perf->cause = AAPC_POST_ACTION;
6455
6456 /* Limit auto performer to this action. */
6457 requirement_vector_append(&auto_perf->reqs,
6458 req_from_values(VUT_ACTION, REQ_RANGE_LOCAL,
6459 FALSE, TRUE, TRUE,
6460 paction->id));
6461
6462 /* Load the list of actions. */
6463 fc_snprintf(action_list_path, sizeof(action_list_path),
6464 "actions.%s",
6465 action_post_success_forced_ruleset_var_name(paction));
6466 if (!load_action_auto_actions(file, auto_perf,
6467 action_list_path, filename)) {
6468 return FALSE;
6469 }
6470
6471 return TRUE;
6472}
6473
6474/**********************************************************************/
6477 static bool lookup_bv_actions(struct section_file *file,
6478 const char *filename,
6479 bv_actions *target,
6480 const char *path)
6481{
6482 if (secfile_entry_by_path(file, path)) {
6483 enum gen_action *listed_actions;
6484 size_t asize;
6485 int j;
6486
6487 listed_actions = secfile_lookup_enum_vec(file, &asize, gen_action,
6488 "%s", path);
6489
6490 if (!listed_actions) {
6491 /* Entity exists but couldn't read it. */
6492 ruleset_error(NULL, LOG_ERROR, "\"%s\": %s: bad action list",
6493 filename, path);
6494
6495 return FALSE;
6496 }
6497
6498 for (j = 0; j < asize; j++) {
6499 BV_SET(*target, listed_actions[j]);
6500 }
6501
6502 free(listed_actions);
6503 }
6504
6505 return TRUE;
6506}
6507
6508/**********************************************************************/
6511 static bool load_ruleset_game(struct section_file *file, bool act,
6512 struct rscompat_info *compat)
6513{
6514 const char *sval, **svec;
6515 const char *filename;
6516 int *food_ini;
6517 int i;
6518 size_t teams;
6519 const char *pref_text;
6520 size_t gni_tmp;
6521 struct section_list *sec;
6522 size_t nval;
6523 const char *name;
6524 bool ok = TRUE;
6525
6526 if (file == NULL) {
6527 return FALSE;
6528 }
6529 filename = secfile_name(file);
6530
6531 name = secfile_lookup_str_default(file, NULL, "ruledit.description_file");
6532 if (name != NULL) {
6533 game.server.ruledit.description_file = fc_strdup(name);
6534 }
6535
6536 /* Section: tileset */
6537 pref_text = secfile_lookup_str_default(file, "", "tileset.preferred");
6538 if (pref_text[0] != '\0') {
6539 /* There was tileset suggestion */
6540 sz_strlcpy(game.control.preferred_tileset, pref_text);
6541 } else {
6542 /* No tileset suggestions */
6543 game.control.preferred_tileset[0] = '\0';
6544 }
6545
6546 /* Section: soundset */
6547 pref_text = secfile_lookup_str_default(file, "", "soundset.preferred");
6548 if (pref_text[0] != '\0') {
6549 /* There was soundset suggestion */
6550 sz_strlcpy(game.control.preferred_soundset, pref_text);
6551 } else {
6552 /* No soundset suggestions */
6553 game.control.preferred_soundset[0] = '\0';
6554 }
6555
6556 /* Section: musicset */
6557 pref_text = secfile_lookup_str_default(file, "", "musicset.preferred");
6558 if (pref_text[0] != '\0') {
6559 /* There was musicset suggestion */
6560 sz_strlcpy(game.control.preferred_musicset, pref_text);
6561 } else {
6562 /* No musicset suggestions */
6563 game.control.preferred_musicset[0] = '\0';
6564 }
6565
6566 /* Section: about */
6567 pref_text = secfile_lookup_str(file, "about.name");
6568 /* Ruleset/modpack name found */
6569 sz_strlcpy(game.control.name, pref_text);
6570
6571 pref_text = secfile_lookup_str_default(file, "", "about.version");
6572 if (pref_text[0] != '\0') {
6573 /* Ruleset/modpack version found */
6574 sz_strlcpy(game.control.version, pref_text);
6575 } else {
6576 /* No version information */
6577 game.control.version[0] = '\0';
6578 }
6579
6580 pref_text = secfile_lookup_str_default(file, "", "about.alt_dir");
6581 if (pref_text[0] != '\0') {
6582 /* Alt directory definition found. */
6583 sz_strlcpy(game.control.alt_dir, pref_text);
6584 } else {
6585 /* No alt directory information */
6586 game.control.alt_dir[0] = '\0';
6587 }
6588
6589 pref_text = secfile_lookup_str_default(file, "", "about.summary");
6590 if (pref_text[0] != '\0') {
6591 int len;
6592
6593 /* Ruleset/modpack summary found */
6594 len = strlen(pref_text);
6595 game.ruleset_summary = fc_malloc(len + 1);
6596 fc_strlcpy(game.ruleset_summary, pref_text, len + 1);
6597 } else {
6598 /* No summary */
6599 if (game.ruleset_summary != NULL) {
6600 free(game.ruleset_summary);
6601 game.ruleset_summary = NULL;
6602 }
6603 }
6604
6605 pref_text = secfile_lookup_str_default(file, "", "about.description");
6606 if (pref_text[0] != '\0') {
6607 int len;
6608
6609 /* Ruleset/modpack description found */
6610 len = strlen(pref_text);
6611 game.ruleset_description = fc_malloc(len + 1);
6612 fc_strlcpy(game.ruleset_description, pref_text, len + 1);
6613 game.control.desc_length = len;
6614 } else {
6615 /* No description */
6616 if (game.ruleset_description != NULL) {
6617 free(game.ruleset_description);
6618 game.ruleset_description = NULL;
6619 }
6620 game.control.desc_length = 0;
6621 }
6622
6623 pref_text = secfile_lookup_str_default(file, "", "about.capabilities");
6624 if (pref_text[0] != '\0') {
6625 int len = strlen(pref_text);
6626
6627 game.ruleset_capabilities = fc_malloc(len + 1);
6628 fc_strlcpy(game.ruleset_capabilities, pref_text, len +1);
6629 } else {
6630 game.ruleset_capabilities = fc_malloc(1);
6631 game.ruleset_capabilities[0] = '\0';
6632 }
6633
6634 /* Section: options */
6635 if (!lookup_tech_list(file, "options", "global_init_techs",
6636 game.rgame.global_init_techs, filename)) {
6637 ok = FALSE;
6638 }
6639
6640 if (ok) {
6641 if (!lookup_building_list(file, "options", "global_init_buildings",
6642 game.rgame.global_init_buildings, filename)) {
6643 ok = FALSE;
6644 }
6645 }
6646
6647 if (ok) {
6648 const char **slist;
6649 int j;
6650
6651 game.control.popup_tech_help = secfile_lookup_bool_default(file, FALSE,
6652 "options.popup_tech_help");
6653
6654 /* section: civstyle */
6655 game.info.base_pollution
6656 = secfile_lookup_int_default(file, RS_DEFAULT_BASE_POLLUTION,
6657 "civstyle.base_pollution");
6658
6659 game.info.gameloss_style = GAMELOSS_STYLE_CLASSICAL;
6660
6661 slist = secfile_lookup_str_vec(file, &nval, "civstyle.gameloss_style");
6662 for (j = 0; j < nval; j++) {
6663 enum gameloss_style style;
6664
6665 sval = slist[j];
6666 if (strcmp(sval, "") == 0) {
6667 continue;
6668 }
6669 style = gameloss_style_by_name(sval, fc_strcasecmp);
6670 if (!gameloss_style_is_valid(style)) {
6671 ruleset_error(NULL, LOG_ERROR,
6672 "\"%s\": bad value \"%s\" for gameloss_style.",
6673 filename, sval);
6674 ok = FALSE;
6675 break;
6676 } else {
6677 game.info.gameloss_style |= style;
6678 }
6679 }
6680 free(slist);
6681 }
6682
6683 if (ok) {
6684 game.info.happy_cost
6685 = secfile_lookup_int_def_min_max(file,
6686 RS_DEFAULT_HAPPY_COST,
6687 RS_MIN_HAPPY_COST,
6688 RS_MAX_HAPPY_COST,
6689 "civstyle.happy_cost");
6690 game.info.food_cost
6691 = secfile_lookup_int_default_min_max(file,
6692 RS_DEFAULT_FOOD_COST,
6693 RS_MIN_FOOD_COST,
6694 RS_MAX_FOOD_COST,
6695 "civstyle.food_cost");
6696 game.info.civil_war_enabled
6697 = secfile_lookup_bool_default(file, TRUE, "civstyle.civil_war_enabled");
6698
6699 game.info.civil_war_bonus_celebrating
6700 = secfile_lookup_int_default(file, RS_DEFAULT_CIVIL_WAR_CELEB,
6701 "civstyle.civil_war_bonus_celebrating");
6702
6703 game.info.civil_war_bonus_unhappy
6704 = secfile_lookup_int_default(file, RS_DEFAULT_CIVIL_WAR_UNHAPPY,
6705 "civstyle.civil_war_bonus_unhappy");
6706
6707 game.info.base_bribe_cost
6708 = secfile_lookup_int_default_min_max(file,
6709 RS_DEFAULT_BASE_BRIBE_COST,
6710 RS_MIN_BASE_BRIBE_COST,
6711 RS_MAX_BASE_BRIBE_COST,
6712 "civstyle.base_bribe_cost");
6713 game.server.ransom_gold
6714 = secfile_lookup_int_default_min_max(file,
6715 RS_DEFAULT_RANSOM_GOLD,
6716 RS_MIN_RANSOM_GOLD,
6717 RS_MAX_RANSOM_GOLD,
6718 "civstyle.ransom_gold");
6719 game.info.pillage_select
6720 = secfile_lookup_bool_default(file, RS_DEFAULT_PILLAGE_SELECT,
6721 "civstyle.pillage_select");
6722
6723 game.info.tech_steal_allow_holes
6724 = secfile_lookup_bool_default(file, RS_DEFAULT_TECH_STEAL_HOLES,
6725 "civstyle.tech_steal_allow_holes");
6726 game.info.tech_trade_allow_holes
6727 = secfile_lookup_bool_default(file, RS_DEFAULT_TECH_TRADE_HOLES,
6728 "civstyle.tech_trade_allow_holes");
6729 game.info.tech_trade_loss_allow_holes
6730 = secfile_lookup_bool_default(file, RS_DEFAULT_TECH_TRADE_LOSS_HOLES,
6731 "civstyle.tech_trade_loss_allow_holes");
6732 game.info.tech_parasite_allow_holes
6733 = secfile_lookup_bool_default(file, RS_DEFAULT_TECH_PARASITE_HOLES,
6734 "civstyle.tech_parasite_allow_holes");
6735 game.info.tech_loss_allow_holes
6736 = secfile_lookup_bool_default(file, RS_DEFAULT_TECH_LOSS_HOLES,
6737 "civstyle.tech_loss_allow_holes");
6738
6739 game.server.upgrade_veteran_loss
6740 = secfile_lookup_int_default_min_max(file,
6741 RS_DEFAULT_UPGRADE_VETERAN_LOSS,
6742 RS_MIN_UPGRADE_VETERAN_LOSS,
6743 RS_MAX_UPGRADE_VETERAN_LOSS,
6744 "civstyle.upgrade_veteran_loss");
6745 game.server.autoupgrade_veteran_loss
6746 = secfile_lookup_int_default_min_max(file,
6747 RS_DEFAULT_UPGRADE_VETERAN_LOSS,
6748 RS_MIN_UPGRADE_VETERAN_LOSS,
6749 RS_MAX_UPGRADE_VETERAN_LOSS,
6750 "civstyle.autoupgrade_veteran_loss");
6751
6752 game.info.base_tech_cost
6753 = secfile_lookup_int_default_min_max(file,
6754 RS_DEFAULT_BASE_TECH_COST,
6755 RS_MIN_BASE_TECH_COST,
6756 RS_MAX_BASE_TECH_COST,
6757 "research.base_tech_cost");
6758
6759 game.info.min_tech_cost
6760 = secfile_lookup_int_default_min_max(file,
6761 RS_DEFAULT_MIN_TECH_COST,
6762 RS_MIN_MIN_TECH_COST,
6763 RS_MAX_MIN_TECH_COST,
6764 "research.min_tech_cost");
6765
6766 food_ini = secfile_lookup_int_vec(file, &gni_tmp,
6767 "civstyle.granary_food_ini");
6768 game.info.granary_num_inis = (int) gni_tmp;
6769
6770 if (game.info.granary_num_inis > MAX_GRANARY_INIS) {
6771 ruleset_error(NULL, LOG_ERROR,
6772 "Too many granary_food_ini entries (%d, max %d)",
6773 game.info.granary_num_inis, MAX_GRANARY_INIS);
6774 ok = FALSE;
6775 } else if (game.info.granary_num_inis == 0) {
6776 log_error("No values for granary_food_ini. Using default "
6777 "value %d.", RS_DEFAULT_GRANARY_FOOD_INI);
6778 game.info.granary_num_inis = 1;
6779 game.info.granary_food_ini[0] = RS_DEFAULT_GRANARY_FOOD_INI;
6780 } else {
6781 int gi;
6782
6783 /* check for <= 0 entries */
6784 for (gi = 0; gi < game.info.granary_num_inis; gi++) {
6785 if (food_ini[gi] <= 0) {
6786 if (gi == 0) {
6787 food_ini[gi] = RS_DEFAULT_GRANARY_FOOD_INI;
6788 } else {
6789 food_ini[gi] = food_ini[gi - 1];
6790 }
6791 log_error("Bad value for granary_food_ini[%i]. Using %i.",
6792 gi, food_ini[gi]);
6793 }
6794 game.info.granary_food_ini[gi] = food_ini[gi];
6795 }
6796 }
6797 free(food_ini);
6798 }
6799
6800 if (ok) {
6801 game.info.granary_food_inc
6802 = secfile_lookup_int_default_min_max(file,
6803 RS_DEFAULT_GRANARY_FOOD_INC,
6804 RS_MIN_GRANARY_FOOD_INC,
6805 RS_MAX_GRANARY_FOOD_INC,
6806 "civstyle.granary_food_inc");
6807
6808 output_type_iterate(o) {
6809 game.info.min_city_center_output[o]
6810 = secfile_lookup_int_default_min_max(file,
6811 RS_DEFAULT_CITY_CENTER_OUTPUT,
6812 RS_MIN_CITY_CENTER_OUTPUT,
6813 RS_MAX_CITY_CENTER_OUTPUT,
6814 "civstyle.min_city_center_%s",
6815 get_output_identifier(o));
6816 } output_type_iterate_end;
6817 }
6818
6819 if (ok) {
6820 const char *tus_text;
6821
6822 game.server.init_vis_radius_sq
6823 = secfile_lookup_int_default_min_max(file,
6824 RS_DEFAULT_VIS_RADIUS_SQ,
6825 RS_MIN_VIS_RADIUS_SQ,
6826 RS_MAX_VIS_RADIUS_SQ,
6827 "civstyle.init_vis_radius_sq");
6828
6829 game.info.init_city_radius_sq
6830 = secfile_lookup_int_default_min_max(file,
6831 RS_DEFAULT_CITY_RADIUS_SQ,
6832 RS_MIN_CITY_RADIUS_SQ,
6833 RS_MAX_CITY_RADIUS_SQ,
6834 "civstyle.init_city_radius_sq");
6835
6836 tus_text = secfile_lookup_str_default(file, RS_DEFAULT_GOLD_UPKEEP_STYLE,
6837 "civstyle.gold_upkeep_style");
6838 game.info.gold_upkeep_style = gold_upkeep_style_by_name(tus_text,
6839 fc_strcasecmp);
6840 if (!gold_upkeep_style_is_valid(game.info.gold_upkeep_style)) {
6841 ruleset_error(NULL, LOG_ERROR,
6842 "Unknown gold upkeep style \"%s\"",
6843 tus_text);
6844 ok = FALSE;
6845 }
6846
6847 game.info.homeless_gold_upkeep
6848 = secfile_lookup_bool_default(file, FALSE, "civstyle.homeless_gold_upkeep");
6849
6850 if (game.info.homeless_gold_upkeep
6851 && game.info.gold_upkeep_style == GOLD_UPKEEP_CITY) {
6852 ruleset_error(NULL, LOG_ERROR,
6853 "Cannot have homeless_gold_upkeep while gold_upkeep_style \"City\".");
6854 ok = FALSE;
6855 }
6856
6857 game.info.granularity = secfile_lookup_int_default(file, 1,
6858 "civstyle.output_granularity");
6859
6860 game.info.airlift_from_always_enabled
6861 = secfile_lookup_bool_default(file, FALSE, "civstyle.airlift_from_always_enabled");
6862
6863 game.info.airlift_to_always_enabled
6864 = secfile_lookup_bool_default(file, TRUE, "civstyle.airlift_to_always_enabled");
6865
6866 /* section: wonder_visibility */
6867 if (ok) {
6868 const char *text;
6869
6870 text = secfile_lookup_str_default(file,
6871 RS_DEFAULT_SMALL_WONDER_VISIBILITY,
6872 "wonder_visibility.small_wonders");
6873
6874 game.info.small_wonder_visibility = wonder_visib_type_by_name(text,
6875 fc_strcasecmp);
6876 if (!wonder_visib_type_is_valid(game.info.small_wonder_visibility)) {
6877 ruleset_error(NULL, LOG_ERROR,
6878 "Unknown wonder visibility typpe \"%s\"",
6879 text);
6880 ok = FALSE;
6881 }
6882 }
6883
6884 /* section: illness */
6885 game.info.illness_on
6886 = secfile_lookup_bool_default(file, RS_DEFAULT_ILLNESS_ON,
6887 "illness.illness_on");
6888 game.info.illness_base_factor
6889 = secfile_lookup_int_default_min_max(file,
6890 RS_DEFAULT_ILLNESS_BASE_FACTOR,
6891 RS_MIN_ILLNESS_BASE_FACTOR,
6892 RS_MAX_ILLNESS_BASE_FACTOR,
6893 "illness.illness_base_factor");
6894 game.info.illness_min_size
6895 = secfile_lookup_int_default_min_max(file,
6896 RS_DEFAULT_ILLNESS_MIN_SIZE,
6897 RS_MIN_ILLNESS_MIN_SIZE,
6898 RS_MAX_ILLNESS_MIN_SIZE,
6899 "illness.illness_min_size");
6900 game.info.illness_trade_infection
6901 = secfile_lookup_int_default_min_max(file,
6902 RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT,
6903 RS_MIN_ILLNESS_TRADE_INFECTION_PCT,
6904 RS_MAX_ILLNESS_TRADE_INFECTION_PCT,
6905 "illness.illness_trade_infection");
6906 game.info.illness_pollution_factor
6907 = secfile_lookup_int_default_min_max(file,
6908 RS_DEFAULT_ILLNESS_POLLUTION_PCT,
6909 RS_MIN_ILLNESS_POLLUTION_PCT,
6910 RS_MAX_ILLNESS_POLLUTION_PCT,
6911 "illness.illness_pollution_factor");
6912
6913 /* section: incite_cost */
6914 game.server.base_incite_cost
6915 = secfile_lookup_int_default_min_max(file,
6916 RS_DEFAULT_INCITE_BASE_COST,
6917 RS_MIN_INCITE_BASE_COST,
6918 RS_MAX_INCITE_BASE_COST,
6919 "incite_cost.base_incite_cost");
6920 game.server.incite_improvement_factor
6921 = secfile_lookup_int_default_min_max(file,
6922 RS_DEFAULT_INCITE_IMPROVEMENT_FCT,
6923 RS_MIN_INCITE_IMPROVEMENT_FCT,
6924 RS_MAX_INCITE_IMPROVEMENT_FCT,
6925 "incite_cost.improvement_factor");
6926 game.server.incite_unit_factor
6927 = secfile_lookup_int_default_min_max(file,
6928 RS_DEFAULT_INCITE_UNIT_FCT,
6929 RS_MIN_INCITE_UNIT_FCT,
6930 RS_MAX_INCITE_UNIT_FCT,
6931 "incite_cost.unit_factor");
6932 game.server.incite_total_factor
6933 = secfile_lookup_int_default_min_max(file,
6934 RS_DEFAULT_INCITE_TOTAL_FCT,
6935 RS_MIN_INCITE_TOTAL_FCT,
6936 RS_MAX_INCITE_TOTAL_FCT,
6937 "incite_cost.total_factor");
6938 }
6939
6940 if (ok) {
6941 const char *tus_text;
6942
6943 /* section: combat_rules */
6944 game.info.tired_attack
6945 = secfile_lookup_bool_default(file, RS_DEFAULT_TIRED_ATTACK,
6946 "combat_rules.tired_attack");
6947
6948 game.info.only_killing_makes_veteran
6949 = secfile_lookup_bool_default(file, RS_DEFAULT_ONLY_KILLING_VETERAN,
6950 "combat_rules.only_killing_makes_veteran");
6951
6952 game.info.only_real_fight_makes_veteran
6953 = secfile_lookup_bool_default(file, RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN,
6954 "combat_rules.only_real_fight_makes_veteran");
6955
6956 game.info.combat_odds_scaled_veterancy
6957 = secfile_lookup_bool_default(file, RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY,
6958 "combat_rules.combat_odds_scaled_veterancy");
6959
6960 game.info.damage_reduces_bombard_rate
6961 = secfile_lookup_bool_default(file, RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE,
6962 "combat_rules.damage_reduces_bombard_rate");
6963
6964 game.info.low_firepower_badwallattacker
6965 = secfile_lookup_int_default(file, 1,
6966 "combat_rules.low_firepower_badwallattacker");
6967 game.info.low_firepower_pearl_harbour
6968 = secfile_lookup_int_default(file, 1,
6969 "combat_rules.low_firepower_pearl_harbour");
6970 game.info.low_firepower_combat_bonus
6971 = secfile_lookup_int_default(file, 1,
6972 "combat_rules.low_firepower_combat_bonus");
6973 game.info.low_firepower_nonnat_bombard
6974 = secfile_lookup_int_default(file, 1,
6975 "combat_rules.low_firepower_nonnat_bombard");
6976
6977 game.info.nuke_pop_loss_pct = secfile_lookup_int_default_min_max(file,
6978 RS_DEFAULT_NUKE_POP_LOSS_PCT,
6979 RS_MIN_NUKE_POP_LOSS_PCT,
6980 RS_MAX_NUKE_POP_LOSS_PCT,
6981 "combat_rules.nuke_pop_loss_pct");
6982
6983 game.info.nuke_defender_survival_chance_pct = secfile_lookup_int_default_min_max(file,
6984 RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT,
6985 RS_MIN_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT,
6986 RS_MAX_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT,
6987 "combat_rules.nuke_defender_survival_chance_pct");
6988
6989 /* section: borders */
6990 game.info.border_city_radius_sq
6991 = secfile_lookup_int_default_min_max(file,
6992 RS_DEFAULT_BORDER_RADIUS_SQ_CITY,
6993 RS_MIN_BORDER_RADIUS_SQ_CITY,
6994 RS_MAX_BORDER_RADIUS_SQ_CITY,
6995 "borders.radius_sq_city");
6996 game.info.border_size_effect
6997 = secfile_lookup_int_default_min_max(file,
6998 RS_DEFAULT_BORDER_SIZE_EFFECT,
6999 RS_MIN_BORDER_SIZE_EFFECT,
7000 RS_MAX_BORDER_SIZE_EFFECT,
7001 "borders.size_effect");
7002
7003 game.info.border_city_permanent_radius_sq
7004 = secfile_lookup_int_default_min_max(file,
7005 RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT,
7006 RS_MIN_BORDER_RADIUS_SQ_CITY_PERMANENT,
7007 RS_MAX_BORDER_RADIUS_SQ_CITY_PERMANENT,
7008 "borders.radius_sq_city_permanent");
7009
7010 /* section: research */
7011 tus_text = secfile_lookup_str_default(file, RS_DEFAULT_TECH_COST_STYLE,
7012 "research.tech_cost_style");
7013 game.info.tech_cost_style = tech_cost_style_by_name(tus_text,
7014 fc_strcasecmp);
7015 if (!tech_cost_style_is_valid(game.info.tech_cost_style)) {
7016 ruleset_error(NULL, LOG_ERROR,
7017 "Unknown tech cost style \"%s\"",
7018 tus_text);
7019 ok = FALSE;
7020 }
7021
7022 tus_text = secfile_lookup_str_default(file, RS_DEFAULT_TECH_LEAKAGE,
7023 "research.tech_leakage");
7024 game.info.tech_leakage = tech_leakage_style_by_name(tus_text,
7025 fc_strcasecmp);
7026 if (!tech_leakage_style_is_valid(game.info.tech_leakage)) {
7027 ruleset_error(NULL, LOG_ERROR,
7028 "Unknown tech leakage \"%s\"",
7029 tus_text);
7030 ok = FALSE;
7031 }
7032 if (game.info.tech_cost_style == TECH_COST_CIV1CIV2
7033 && game.info.tech_leakage != TECH_LEAKAGE_NONE) {
7034 log_error("Only tech_leakage \"%s\" supported with "
7035 "tech_cost_style \"%s\". ",
7036 tech_leakage_style_name(TECH_LEAKAGE_NONE),
7037 tech_cost_style_name(TECH_COST_CIV1CIV2));
7038 log_error("Switching to tech_leakage \"%s\".",
7039 tech_leakage_style_name(TECH_LEAKAGE_NONE));
7040 game.info.tech_leakage = TECH_LEAKAGE_NONE;
7041 }
7042 game.info.base_tech_cost
7043 = secfile_lookup_int_default_min_max(file,
7044 RS_DEFAULT_BASE_TECH_COST,
7045 RS_MIN_BASE_TECH_COST,
7046 RS_MAX_BASE_TECH_COST,
7047 "research.base_tech_cost");
7048
7049 tus_text = secfile_lookup_str_default(file, RS_DEFAULT_TECH_UPKEEP_STYLE,
7050 "research.tech_upkeep_style");
7051
7052 game.info.tech_upkeep_style = tech_upkeep_style_by_name(tus_text, fc_strcasecmp);
7053
7054 if (!tech_upkeep_style_is_valid(game.info.tech_upkeep_style)) {
7055 ruleset_error(NULL, LOG_ERROR,
7056 "Unknown tech upkeep style \"%s\"",
7057 tus_text);
7058 ok = FALSE;
7059 }
7060 }
7061
7062 if (ok) {
7063 game.info.tech_upkeep_divider
7064 = secfile_lookup_int_default_min_max(file,
7065 RS_DEFAULT_TECH_UPKEEP_DIVIDER,
7066 RS_MIN_TECH_UPKEEP_DIVIDER,
7067 RS_MAX_TECH_UPKEEP_DIVIDER,
7068 "research.tech_upkeep_divider");
7069
7070 sval = secfile_lookup_str_default(file, NULL, "research.free_tech_method");
7071 if (sval == NULL) {
7072 ruleset_error(NULL, LOG_ERROR,
7073 "No free_tech_method given");
7074 ok = FALSE;
7075 } else {
7076 game.info.free_tech_method = free_tech_method_by_name(sval, fc_strcasecmp);
7077 if (!free_tech_method_is_valid(game.info.free_tech_method)) {
7078 ruleset_error(NULL, LOG_ERROR,
7079 "Bad value %s for free_tech_method.", sval);
7080 ok = FALSE;
7081 }
7082 }
7083 }
7084
7085 if (ok) {
7086 int cf;
7087
7088 /* section: culture */
7089 game.info.culture_vic_points
7090 = secfile_lookup_int_default(file, RS_DEFAULT_CULTURE_VIC_POINTS,
7091 "culture.victory_min_points");
7092 game.info.culture_vic_lead
7093 = secfile_lookup_int_default(file, RS_DEFAULT_CULTURE_VIC_LEAD,
7094 "culture.victory_lead_pct");
7095 game.info.culture_migration_pml
7096 = secfile_lookup_int_default(file, RS_DEFAULT_CULTURE_MIGRATION_PML,
7097 "culture.migration_pml");
7098 game.info.history_interest_pml
7099 = secfile_lookup_int_default(file, RS_DEFAULT_HISTORY_INTEREST_PML,
7100 "culture.history_interest_pml");
7101
7102 /* section: world_peace */
7103 game.info.world_peace_turns
7104 = secfile_lookup_int_default(file, RS_DEFAULT_WORLD_PEACE_TURNS,
7105 "world_peace.victory_turns");
7106
7107 /* section: calendar */
7108 game.calendar.calendar_skip_0
7109 = secfile_lookup_bool_default(file, RS_DEFAULT_CALENDAR_SKIP_0,
7110 "calendar.skip_year_0");
7111 game.server.start_year
7112 = secfile_lookup_int_default(file, GAME_DEFAULT_START_YEAR,
7113 "calendar.start_year");
7114 game.calendar.calendar_fragments
7115 = secfile_lookup_int_default(file, 0, "calendar.fragments");
7116
7117 if (game.calendar.calendar_fragments > MAX_CALENDAR_FRAGMENTS) {
7118 ruleset_error(NULL, LOG_ERROR,
7119 "Too many calendar fragments. Max is %d",
7120 MAX_CALENDAR_FRAGMENTS);
7121 ok = FALSE;
7122 game.calendar.calendar_fragments = 0;
7123 }
7124 sz_strlcpy(game.calendar.positive_year_label,
7125 secfile_lookup_str_default(file,
7126 RS_DEFAULT_POS_YEAR_LABEL,
7127 "calendar.positive_label"));
7128 sz_strlcpy(game.calendar.negative_year_label,
7129 secfile_lookup_str_default(file,
7130 RS_DEFAULT_NEG_YEAR_LABEL,
7131 "calendar.negative_label"));
7132
7133 for (cf = 0; cf < game.calendar.calendar_fragments; cf++) {
7134 const char *fname;
7135
7136 fname = secfile_lookup_str_default(file, NULL, "calendar.fragment_name%d", cf);
7137 if (fname != NULL) {
7138 strncpy(game.calendar.calendar_fragment_name[cf], fname,
7139 sizeof(game.calendar.calendar_fragment_name[cf]));
7140 }
7141 }
7142 }
7143
7144 if (ok) {
7145 /* section playercolors */
7146 struct rgbcolor *prgbcolor = NULL;
7147 bool color_read = TRUE;
7148
7149 /* Check if the player list is defined and empty. */
7150 if (playercolor_count() != 0) {
7151 ok = FALSE;
7152 } else {
7153 i = 0;
7154
7155 while (color_read) {
7156 prgbcolor = NULL;
7157
7158 color_read = rgbcolor_load(file, &prgbcolor, "playercolors.colorlist%d", i);
7159 if (color_read) {
7160 playercolor_add(prgbcolor);
7161 }
7162
7163 i++;
7164 }
7165
7166 if (playercolor_count() == 0) {
7167 ruleset_error(NULL, LOG_ERROR, "No player colors defined!");
7168 ok = FALSE;
7169 }
7170
7171 if (ok) {
7172 fc_assert(game.plr_bg_color == NULL);
7173 if (!rgbcolor_load(file, &game.plr_bg_color, "playercolors.background")) {
7174 ruleset_error(NULL, LOG_ERROR,
7175 "No background player color defined! (%s)",
7176 secfile_error());
7177 ok = FALSE;
7178 }
7179 }
7180 }
7181 }
7182
7183 if (ok) {
7184 /* section: teams */
7185 svec = secfile_lookup_str_vec(file, &teams, "teams.names");
7186 if (team_slot_count() < teams) {
7187 teams = team_slot_count();
7188 }
7189 game.server.ruledit.named_teams = teams;
7190 for (i = 0; i < teams; i++) {
7191 team_slot_set_defined_name(team_slot_by_number(i), svec[i]);
7192 }
7193 free(svec);
7194
7195 sec = secfile_sections_by_name_prefix(file, DISASTER_SECTION_PREFIX);
7196 nval = (NULL != sec ? section_list_size(sec) : 0);
7197 if (nval > MAX_DISASTER_TYPES) {
7198 int num = nval; /* No "size_t" to printf */
7199
7200 ruleset_error(NULL, LOG_ERROR,
7201 "\"%s\": Too many disaster types (%d, max %d)",
7202 filename, num, MAX_DISASTER_TYPES);
7203 section_list_destroy(sec);
7204 ok = FALSE;
7205 } else {
7206 game.control.num_disaster_types = nval;
7207 }
7208 }
7209
7210 if (ok) {
7211 disaster_type_iterate(pdis) {
7212 int id = disaster_index(pdis);
7213 int j;
7214 size_t eff_count;
7215 struct requirement_vector *reqs;
7216 const char *sec_name = section_name(section_list_get(sec, id));
7217
7218 if (!ruleset_load_names(&pdis->name, NULL, file, sec_name)) {
7219 ruleset_error(NULL, LOG_ERROR,
7220 "\"%s\": Cannot load disaster names",
7221 filename);
7222 ok = FALSE;
7223 break;
7224 }
7225
7226 reqs = lookup_req_list(file, compat, sec_name, "reqs", disaster_rule_name(pdis));
7227 if (reqs == NULL) {
7228 ok = FALSE;
7229 break;
7230 }
7231 requirement_vector_copy(&pdis->reqs, reqs);
7232
7233 pdis->frequency = secfile_lookup_int_default(file, GAME_DEFAULT_DISASTER_FREQ,
7234 "%s.frequency", sec_name);
7235
7236 svec = secfile_lookup_str_vec(file, &eff_count, "%s.effects", sec_name);
7237
7238 BV_CLR_ALL(pdis->effects);
7239 for (j = 0; j < eff_count; j++) {
7240 const char *dsval = svec[j];
7241 enum disaster_effect_id effect;
7242
7243 effect = disaster_effect_id_by_name(dsval, fc_strcasecmp);
7244
7245 if (!disaster_effect_id_is_valid(effect)) {
7246 ruleset_error(NULL, LOG_ERROR,
7247 "\"%s\" disaster \"%s\": unknown effect \"%s\".",
7248 filename, disaster_rule_name(pdis), dsval);
7249 ok = FALSE;
7250 break;
7251 } else {
7252 BV_SET(pdis->effects, effect);
7253 }
7254 }
7255
7256 free(svec);
7257
7258 if (!ok) {
7259 break;
7260 }
7261 } disaster_type_iterate_end;
7262 section_list_destroy(sec);
7263 }
7264
7265 if (ok) {
7266 sec = secfile_sections_by_name_prefix(file, ACHIEVEMENT_SECTION_PREFIX);
7267
7268 achievements_iterate(pach) {
7269 int id = achievement_index(pach);
7270 const char *sec_name = section_name(section_list_get(sec, id));
7271 const char *typename;
7272 const char *msg;
7273
7274 typename = secfile_lookup_str_default(file, NULL, "%s.type", sec_name);
7275
7276 pach->type = achievement_type_by_name(typename, fc_strcasecmp);
7277 if (!achievement_type_is_valid(pach->type)) {
7278 ruleset_error(NULL, LOG_ERROR,
7279 "Achievement has unknown type \"%s\".",
7280 typename != NULL ? typename : "(NULL)");
7281 ok = FALSE;
7282 }
7283
7284 if (ok) {
7285 pach->unique = secfile_lookup_bool_default(file, GAME_DEFAULT_ACH_UNIQUE,
7286 "%s.unique", sec_name);
7287
7288 pach->value = secfile_lookup_int_default(file, GAME_DEFAULT_ACH_VALUE,
7289 "%s.value", sec_name);
7290 pach->culture = secfile_lookup_int_default(file, 0,
7291 "%s.culture", sec_name);
7292
7293 msg = secfile_lookup_str_default(file, NULL, "%s.first_msg", sec_name);
7294 if (msg == NULL) {
7295 ruleset_error(NULL, LOG_ERROR,
7296 "Achievement %s has no first msg!", sec_name);
7297 ok = FALSE;
7298 } else {
7299 pach->first_msg = fc_strdup(msg);
7300 }
7301 }
7302
7303 if (ok) {
7304 msg = secfile_lookup_str_default(file, NULL, "%s.cons_msg", sec_name);
7305 if (msg == NULL) {
7306 if (!pach->unique) {
7307 ruleset_error(NULL, LOG_ERROR,
7308 "Achievement %s has no msg for consecutive gainers!",
7309 sec_name);
7310 ok = FALSE;
7311 }
7312 } else {
7313 pach->cons_msg = fc_strdup(msg);
7314 }
7315 }
7316
7317 if (!ok) {
7318 break;
7319 }
7320 } achievements_iterate_end;
7321 section_list_destroy(sec);
7322 }
7323
7324 if (ok) {
7325 for (i = 0; (name = secfile_lookup_str_default(file, NULL,
7326 "trade.settings%d.type",
7327 i)); i++) {
7328 enum trade_route_type type = trade_route_type_by_name(name);
7329
7330 if (type == TRT_LAST) {
7331 ruleset_error(NULL, LOG_ERROR,
7332 "\"%s\" unknown trade route type \"%s\".",
7333 filename, name);
7334 ok = FALSE;
7335 } else {
7336 struct trade_route_settings *set = trade_route_settings_by_type(type);
7337 const char *cancelling;
7338 const char *bonus;
7339
7340 set->trade_pct = secfile_lookup_int_default(file, 100,
7341 "trade.settings%d.pct", i);
7342 cancelling = secfile_lookup_str_default(file, "Active",
7343 "trade.settings%d.cancelling", i);
7344 set->cancelling = trade_route_cancelling_type_by_name(cancelling);
7345 if (set->cancelling == TRI_LAST) {
7346 ruleset_error(NULL, LOG_ERROR,
7347 "\"%s\" unknown trade route cancelling type \"%s\".",
7348 filename, cancelling);
7349 ok = FALSE;
7350 }
7351
7352 bonus = secfile_lookup_str_default(file, "None", "trade.settings%d.bonus", i);
7353
7354 set->bonus_type = trade_route_bonus_type_by_name(bonus, fc_strcasecmp);
7355
7356 if (!trade_route_bonus_type_is_valid(set->bonus_type)) {
7357 ruleset_error(NULL, LOG_ERROR,
7358 "\"%s\" unknown trade route bonus type \"%s\".",
7359 filename, bonus);
7360 ok = FALSE;
7361 }
7362 }
7363 }
7364 }
7365
7366 if (ok) {
7367 const char *str;
7368
7369 game.info.min_trade_route_val
7370 = secfile_lookup_int_default(file, 0, "trade.min_trade_route_val");
7371
7372 game.info.reveal_trade_partner
7373 = secfile_lookup_bool_default(file, FALSE,
7374 "trade.reveal_trade_partner");
7375
7376 str = secfile_lookup_str_default(file,
7377 goods_selection_method_name(RS_DEFAULT_GOODS_SELECTION),
7378 "trade.goods_selection");
7379
7380 game.info.goods_selection = goods_selection_method_by_name(str, fc_strcasecmp);
7381
7382 if (!goods_selection_method_is_valid(game.info.goods_selection)) {
7383 ruleset_error(NULL, LOG_ERROR,
7384 "\"%s\" goods selection method \"%s\" unknown.",
7385 filename, str);
7386 ok = FALSE;
7387 }
7388 }
7389
7390 if (ok) {
7391 sec = secfile_sections_by_name_prefix(file, GOODS_SECTION_PREFIX);
7392
7393 goods_type_iterate(pgood) {
7394 int id = goods_index(pgood);
7395 const char *sec_name = section_name(section_list_get(sec, id));
7396 struct requirement_vector *reqs;
7397 const char **slist;
7398 int j;
7399
7400 reqs = lookup_req_list(file, compat, sec_name, "reqs", goods_rule_name(pgood));
7401 if (reqs == NULL) {
7402 ok = FALSE;
7403 break;
7404 }
7405 requirement_vector_copy(&pgood->reqs, reqs);
7406
7407 pgood->from_pct = secfile_lookup_int_default(file, 100,
7408 "%s.from_pct", sec_name);
7409 pgood->to_pct = secfile_lookup_int_default(file, 100,
7410 "%s.to_pct", sec_name);
7411 pgood->onetime_pct = secfile_lookup_int_default(file, 100,
7412 "%s.onetime_pct", sec_name);
7413 pgood->priority = secfile_lookup_int_default(file, 1,
7414 "%s.priority", sec_name);
7415
7416 slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec_name);
7417 BV_CLR_ALL(pgood->flags);
7418 for (j = 0; j < nval; j++) {
7419 enum goods_flag_id flag;
7420
7421 sval = slist[j];
7422 flag = goods_flag_id_by_name(sval, fc_strcasecmp);
7423 if (!goods_flag_id_is_valid(flag)) {
7424 ruleset_error(NULL, LOG_ERROR, "\"%s\" good \"%s\": unknown flag \"%s\".",
7425 filename, goods_rule_name(pgood), sval);
7426 ok = FALSE;
7427 break;
7428 } else {
7429 BV_SET(pgood->flags, flag);
7430 }
7431 }
7432 free(slist);
7433
7434 pgood->helptext = lookup_strvec(file, sec_name, "helptext");
7435 } goods_type_iterate_end;
7436 section_list_destroy(sec);
7437 }
7438
7439 if (ok) {
7440 sec = secfile_sections_by_name_prefix(file, CLAUSE_SECTION_PREFIX);
7441
7442 if (sec != NULL) {
7443 int num = section_list_size(sec);
7444
7445 for (i = 0; i < num; i++) {
7446 const char *sec_name = section_name(section_list_get(sec, i));
7447 const char *clause_name = secfile_lookup_str_default(file, NULL,
7448 "%s.type", sec_name);
7449 enum clause_type type = clause_type_by_name(clause_name, fc_strcasecmp);
7450 struct clause_info *info;
7451 struct requirement_vector *reqs;
7452
7453 if (!clause_type_is_valid(type)) {
7454 ruleset_error(NULL, LOG_ERROR,
7455 "\"%s\" unknown clause type \"%s\".",
7456 filename, clause_name);
7457 ok = FALSE;
7458 break;
7459 }
7460
7461 info = clause_info_get(type);
7462
7463 if (info->enabled) {
7464 ruleset_error(NULL, LOG_ERROR,
7465 "\"%s\" dublicate clause type \"%s\" definition.",
7466 filename, clause_name);
7467 ok = FALSE;
7468 break;
7469 }
7470
7471 reqs = lookup_req_list(file, compat, sec_name, "giver_reqs", clause_name);
7472 if (reqs == NULL) {
7473 ok = FALSE;
7474 break;
7475 }
7476 requirement_vector_copy(&info->giver_reqs, reqs);
7477
7478 reqs = lookup_req_list(file, compat, sec_name, "receiver_reqs", clause_name);
7479 if (reqs == NULL) {
7480 ok = FALSE;
7481 break;
7482 }
7483 requirement_vector_copy(&info->receiver_reqs, reqs);
7484
7485 reqs = lookup_req_list(file, compat, sec_name, "either_reqs", clause_name);
7486 if (reqs == NULL) {
7487 ok = FALSE;
7488 break;
7489 }
7490 requirement_vector_copy(&info->either_reqs, reqs);
7491
7492 info->enabled = TRUE;
7493 }
7494 }
7495 section_list_destroy(sec);
7496 }
7497
7498 if (ok) {
7499 sec = secfile_sections_by_name_prefix(file, COUNTER_SECTION_PREFIX);
7500
7501 if (sec != NULL) {
7502 int num = section_list_size(sec);
7503 int curr;
7504
7505 for (curr = 0; curr < num; curr++) {
7506
7507 struct counter *pcount = counter_by_id(curr);
7508 const char *sec_name = section_name(section_list_get(sec, curr));
7509 const char *counter_type = secfile_lookup_str_default(file, NULL,
7510 "%s.type",
7511 sec_name);
7512
7513 enum counter_behaviour cb = counter_behaviour_by_name(counter_type,
7514 fc_strcasecmp);
7515 if (!counter_behaviour_is_valid(cb)) {
7516 ruleset_error(NULL, LOG_ERROR,
7517 "\"%s\" unknown counter type \"%s\".",
7518 filename, counter_type);
7519 ok = FALSE;
7520 break;
7521 }
7522
7523 if (!ruleset_load_names(&pcount->name, NULL, file, sec_name)) {
7524 ruleset_error(NULL, LOG_ERROR,
7525 "\"%s\": Cannot load counter names",
7526 filename);
7527 ok = FALSE;
7528 break;
7529 }
7530
7531 pcount->helptext = lookup_strvec(file, sec_name, "helptext");
7532 pcount->type = cb;
7533 if (!secfile_lookup_int(file, &pcount->checkpoint,
7534 "%s.checkpoint", sec_name)) {
7535
7536 ruleset_error(NULL, LOG_ERROR,
7537 "\"%s\": No checkpoint value",
7538 filename);
7539 ok = FALSE;
7540 break;
7541 }
7542
7543 pcount->target = CTGT_CITY;
7544 pcount->index = curr;
7545 pcount->def = secfile_lookup_int_default(file, 0,
7546 "%s.def",
7547 sec_name);
7548 attach_city_counter(pcount);
7549 }
7550 }
7551 }
7552
7553 /* secfile_check_unused() is not here, but only after also settings section
7554 * has been loaded. */
7555
7556 return ok;
7557}
7558
7559/**********************************************************************/
7562 static bool load_ruleset_actions(struct section_file *file,
7563 struct section_file *gamefile,
7564 struct rscompat_info *compat)
7565{
7566 bool ok = TRUE;
7567 const char *filename = secfile_name(file);
7568 struct section_list *sec;
7569 struct action_auto_perf *auto_perf;
7570 struct requirement_vector *reqs;
7571
7572 /* Auto attack. */
7573
7574 /* Action auto performers aren't ready to be exposed in the ruleset
7575 * yet. The behavior when two action auto performers for the same
7576 * cause can fire isn't set in stone yet. How is one of them chosen?
7577 * What if all the actions of the chosen action auto performer turned
7578 * out to be illegal but one of the other action auto performers that
7579 * fired has legal actions? These issues can decide what other action
7580 * rules action auto performers can represent in the future. Deciding
7581 * should therefore wait until a rule needs action auto performers to
7582 * work a certain way. */
7583 /* Only one action auto performer, ACTION_AUTO_MOVED_ADJ, is caused
7584 * by AAPC_UNIT_MOVED_ADJ. It is therefore safe to expose the full
7585 * requirement vector to the ruleset. */
7586
7587 /* A unit moved next to this unit and the autoattack server setting
7588 * is enabled. */
7589 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_MOVED_ADJ);
7590 auto_perf->cause = AAPC_UNIT_MOVED_ADJ;
7591
7592 reqs = lookup_req_list(file, compat,
7593 "auto_attack", "if_attacker",
7594 "auto_attack");
7595 if (reqs == NULL) {
7596 ok = FALSE;
7597 } else {
7598 requirement_vector_copy(&auto_perf->reqs, reqs);
7599
7600 if (!load_action_auto_actions(file, auto_perf,
7601 "auto_attack.attack_actions",
7602 filename)) {
7603 /* Failed to load auto attack actions */
7604 ruleset_error(NULL, LOG_ERROR,
7605 "\"%s\": %s: failed load %s.",
7606 filename, "auto_attack", "attack_actions");
7607 ok = FALSE;
7608 }
7609 }
7610
7611 /* Section: actions */
7612 if (ok) {
7613 action_iterate(act_id) {
7614 struct action *paction = action_by_number(act_id);
7615
7616 if (!load_action_blocked_by_list(file, filename, paction)) {
7617 ok = FALSE;
7618 break;
7619 }
7620 } action_iterate_end;
7621
7622 if (ok) {
7623 if (!lookup_bv_actions(file, filename,
7624 &game.info.diplchance_initial_odds,
7625 "actions.diplchance_initial_odds")) {
7626 ok = FALSE;
7627 }
7628 }
7629
7630 if (ok) {
7631 /* If the "Poison City" action or the "Poison City Escape" action
7632 * should empty the granary. */
7633 /* TODO: empty granary and reduce population should become separate
7634 * action effect flags when actions are generalized. */
7635 game.info.poison_empties_food_stock
7636 = secfile_lookup_bool_default(file,
7637 RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK,
7638 "actions.poison_empties_food_stock");
7639
7640 /* If the "Steal Maps" action or the "Steal Maps Escape" action always
7641 * will reveal all cities when successful. */
7642 game.info.steal_maps_reveals_all_cities
7643 = secfile_lookup_bool_default(file,
7644 RS_DEFAULT_STEAL_MAP_REVEALS_CITIES,
7645 "actions.steal_maps_reveals_all_cities");
7646
7647 /* Allow setting certain properties for some actions before
7648 * generalized actions. */
7649 action_iterate(act_id) {
7650 if (!load_action_range(file, act_id)) {
7651 ok = FALSE;
7652 } else if (!load_action_kind(file, act_id)) {
7653 ok = FALSE;
7654 } else if (!load_action_actor_consuming_always(file, act_id)) {
7655 ok = FALSE;
7656 } else {
7657 const char *entry_name = NULL;
7658
7659 if (!action_id_is_internal(act_id)) {
7660 entry_name = action_ui_name_ruleset_var_name(act_id);
7661 }
7662
7663 load_action_ui_name(file, act_id, entry_name);
7664 }
7665
7666 if (!ok) {
7667 break;
7668 }
7669 } action_iterate_end;
7670 }
7671
7672 if (ok) {
7673 /* The quiet (don't auto generate help for) property of all actions
7674 * live in a single enum vector. This avoids generic action
7675 * expectations. */
7676 if (secfile_entry_by_path(file, "actions.quiet_actions")) {
7677 enum gen_action *quiet_actions;
7678 size_t asize;
7679 int j;
7680
7681 quiet_actions =
7682 secfile_lookup_enum_vec(file, &asize, gen_action,
7683 "actions.quiet_actions");
7684
7685 if (!quiet_actions) {
7686 /* Entity exists but couldn't read it. */
7687 ruleset_error(NULL, LOG_ERROR,
7688 "\"%s\": actions.quiet_actions: bad action list",
7689 filename);
7690
7691 ok = FALSE;
7692 } else {
7693 for (j = 0; j < asize; j++) {
7694 /* Don't auto generate help text for this action. */
7695 action_by_number(quiet_actions[j])->quiet = TRUE;
7696 }
7697
7698 free(quiet_actions);
7699 }
7700 }
7701 }
7702
7703 if (ok) {
7704 /* Hard code action sub results for now. */
7705
7706 /* Unit Enter Hut */
7707 action_by_result_iterate(paction, ACTRES_HUT_ENTER) {
7708 BV_SET(paction->sub_results, ACT_SUB_RES_HUT_ENTER);
7709 } action_by_result_iterate_end;
7710 BV_SET(action_by_number(ACTION_PARADROP_ENTER)->sub_results,
7711 ACT_SUB_RES_HUT_ENTER);
7712 BV_SET(action_by_number(ACTION_PARADROP_ENTER_CONQUER)->sub_results,
7713 ACT_SUB_RES_HUT_ENTER);
7714 BV_SET(action_by_number(ACTION_TELEPORT_ENTER)->sub_results,
7715 ACT_SUB_RES_HUT_ENTER);
7716 BV_SET(action_by_number(ACTION_TELEPORT_ENTER_CONQUER)->sub_results,
7717 ACT_SUB_RES_HUT_ENTER);
7718
7719 /* Unit Frighten Hut */
7720 action_by_result_iterate(paction, ACTRES_HUT_FRIGHTEN) {
7721 BV_SET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN);
7722 } action_by_result_iterate_end;
7723 BV_SET(action_by_number(ACTION_PARADROP_FRIGHTEN)->sub_results,
7724 ACT_SUB_RES_HUT_FRIGHTEN);
7725 BV_SET(action_by_number(ACTION_PARADROP_FRIGHTEN_CONQUER)->sub_results,
7726 ACT_SUB_RES_HUT_FRIGHTEN);
7727 BV_SET(action_by_number(ACTION_TELEPORT_FRIGHTEN)->sub_results,
7728 ACT_SUB_RES_HUT_FRIGHTEN);
7729 BV_SET(action_by_number(ACTION_TELEPORT_FRIGHTEN_CONQUER)->sub_results,
7730 ACT_SUB_RES_HUT_FRIGHTEN);
7731
7732 /* Unit May Embark */
7733 action_iterate(act_id) {
7734 struct action *paction = action_by_number(act_id);
7735
7736 if (secfile_lookup_bool_default(gamefile, FALSE,
7737 "civstyle.paradrop_to_transport")
7738 && (action_has_result(paction, ACTRES_PARADROP)
7739 || action_has_result(paction, ACTRES_PARADROP_CONQUER))) {
7740 BV_SET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK);
7741 }
7742
7743 /* Embark actions will always embark, not maybe embark. */
7744 } action_iterate_end;
7745
7746 /* Non Lethal bombard */
7747 BV_SET(action_by_number(ACTION_BOMBARD)->sub_results,
7748 ACT_SUB_RES_NON_LETHAL);
7749 BV_SET(action_by_number(ACTION_BOMBARD2)->sub_results,
7750 ACT_SUB_RES_NON_LETHAL);
7751 BV_SET(action_by_number(ACTION_BOMBARD3)->sub_results,
7752 ACT_SUB_RES_NON_LETHAL);
7753 }
7754 }
7755
7756 if (ok) {
7757 /* Forced actions after another action was successfully performed. */
7758
7759 if (!load_action_post_success_force(file, filename,
7760 ACTION_AUTO_POST_BRIBE,
7761 action_by_number(
7762 ACTION_SPY_BRIBE_UNIT))) {
7763 ok = FALSE;
7764 } else if (!load_action_post_success_force(file, filename,
7765 ACTION_AUTO_POST_ATTACK,
7766 action_by_number(
7767 ACTION_ATTACK))) {
7768 ok = FALSE;
7769 } else if (!load_action_post_success_force(file, filename,
7770 ACTION_AUTO_POST_ATTACK2,
7771 action_by_number(
7772 ACTION_ATTACK2))) {
7773 ok = FALSE;
7774 } else if (!load_action_post_success_force(file, filename,
7775 ACTION_AUTO_POST_COLLECT_RANSOM,
7776 action_by_number(
7777 ACTION_COLLECT_RANSOM))) {
7778 ok = FALSE;
7779 } else if (!load_action_post_success_force(file, filename,
7780 ACTION_AUTO_POST_WIPE_UNITS,
7781 action_by_number(
7782 ACTION_WIPE_UNITS))) {
7783 ok = FALSE;
7784 }
7785
7786 /* No "Suicide Attack". Can't act when dead. */
7787 }
7788
7789 if (ok) {
7790 /* The city that made the unit's current tile native is gone.
7791 * Evaluated against an adjacent tile. */
7792 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_ESCAPE_CITY);
7793 auto_perf->cause = AAPC_CITY_GONE;
7794
7795 /* I have no objections to moving this out of game's actions to
7796 * cities.ruleset, units.ruleset or an other location in game.ruleset
7797 * you find more suitable. -- Sveinung */
7798 if (!load_action_auto_actions(file, auto_perf,
7799 "actions.escape_city", filename)) {
7800 ok = FALSE;
7801 }
7802 }
7803
7804 if (ok) {
7805 /* The unit's stack has been defeated and is scheduled for execution
7806 * but the unit has the CanEscape unit type flag.
7807 * Evaluated against an adjacent tile. */
7808 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_ESCAPE_STACK);
7809 auto_perf->cause = AAPC_UNIT_STACK_DEATH;
7810
7811 /* I have no objections to moving this out of game's actions to
7812 * cities.ruleset, units.ruleset or an other location in game.ruleset
7813 * you find more suitable. -- Sveinung */
7814 if (!load_action_auto_actions(file, auto_perf,
7815 "actions.unit_stack_death", filename)) {
7816 ok = FALSE;
7817 }
7818 }
7819
7820 if (ok) {
7821 sec = secfile_sections_by_name_prefix(file,
7822 ACTION_ENABLER_SECTION_PREFIX);
7823
7824 if (sec) {
7825 section_list_iterate(sec, psection) {
7826 struct action_enabler *enabler;
7827 const char *sec_name = section_name(psection);
7828 struct action *paction;
7829 struct requirement_vector *actor_reqs;
7830 struct requirement_vector *target_reqs;
7831 const char *action_text;
7832
7833 enabler = action_enabler_new();
7834
7835 action_text = secfile_lookup_str(file, "%s.action", sec_name);
7836
7837 if (action_text == NULL) {
7838 ruleset_error(NULL, LOG_ERROR,
7839 "\"%s\" [%s] missing action to enable.",
7840 filename, sec_name);
7841 ok = FALSE;
7842 break;
7843 }
7844
7845 paction = action_by_rule_name(action_text);
7846 if (!paction) {
7847 ruleset_error(NULL, LOG_ERROR,
7848 "\"%s\" [%s] lists unknown action type \"%s\".",
7849 filename, sec_name, action_text);
7850 ok = FALSE;
7851 break;
7852 }
7853
7854 enabler->action = action_id(paction);
7855
7856 actor_reqs = lookup_req_list(file, compat, sec_name, "actor_reqs", action_text);
7857 if (actor_reqs == NULL) {
7858 ok = FALSE;
7859 break;
7860 }
7861
7862 requirement_vector_copy(&enabler->actor_reqs, actor_reqs);
7863
7864 target_reqs = lookup_req_list(file, compat, sec_name, "target_reqs", action_text);
7865 if (target_reqs == NULL) {
7866 ok = FALSE;
7867 break;
7868 }
7869
7870 requirement_vector_copy(&enabler->target_reqs, target_reqs);
7871
7872 action_enabler_add(enabler);
7873 } section_list_iterate_end;
7874
7875 section_list_destroy(sec);
7876 }
7877 }
7878
7879 return ok;
7880}
7881
7882/**********************************************************************/
7886 static void send_ruleset_unit_classes(struct conn_list *dest)
7887{
7888 struct packet_ruleset_unit_class packet;
7889 struct packet_ruleset_unit_class_flag fpacket;
7890 int i;
7891
7892 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
7893 const char *flagname;
7894 const char *helptxt;
7895
7896 fpacket.id = i + UCF_USER_FLAG_1;
7897
7898 flagname = unit_class_flag_id_name(i + UCF_USER_FLAG_1);
7899 if (flagname == NULL) {
7900 fpacket.name[0] = '\0';
7901 } else {
7902 sz_strlcpy(fpacket.name, flagname);
7903 }
7904
7905 helptxt = unit_class_flag_helptxt(i + UCF_USER_FLAG_1);
7906 if (helptxt == NULL) {
7907 fpacket.helptxt[0] = '\0';
7908 } else {
7909 sz_strlcpy(fpacket.helptxt, helptxt);
7910 }
7911
7912 lsend_packet_ruleset_unit_class_flag(dest, &fpacket);
7913 }
7914
7915 unit_class_iterate(c) {
7916 packet.id = uclass_number(c);
7917 sz_strlcpy(packet.name, untranslated_name(&c->name));
7918 sz_strlcpy(packet.rule_name, rule_name_get(&c->name));
7919 packet.min_speed = c->min_speed;
7920 packet.hp_loss_pct = c->hp_loss_pct;
7921 packet.non_native_def_pct = c->non_native_def_pct;
7922 packet.flags = c->flags;
7923
7924 PACKET_STRVEC_INSERT(packet.helptext, c->helptext);
7925
7926 lsend_packet_ruleset_unit_class(dest, &packet);
7927 } unit_class_iterate_end;
7928}
7929
7930/**********************************************************************/
7934 static void send_ruleset_units(struct conn_list *dest)
7935{
7936 struct packet_ruleset_unit packet;
7937#ifdef FREECIV_WEB
7938 struct packet_web_ruleset_unit_addition web_packet;
7939#endif /* FREECIV_WEB */
7940 struct packet_ruleset_unit_flag fpacket;
7941 int i;
7942
7943 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
7944 const char *flagname;
7945 const char *helptxt;
7946
7947 fpacket.id = i + UTYF_USER_FLAG_1;
7948
7949 flagname = unit_type_flag_id_name(i + UTYF_USER_FLAG_1);
7950 if (flagname == NULL) {
7951 fpacket.name[0] = '\0';
7952 } else {
7953 sz_strlcpy(fpacket.name, flagname);
7954 }
7955
7956 helptxt = unit_type_flag_helptxt(i + UTYF_USER_FLAG_1);
7957 if (helptxt == NULL) {
7958 fpacket.helptxt[0] = '\0';
7959 } else {
7960 sz_strlcpy(fpacket.helptxt, helptxt);
7961 }
7962
7963 lsend_packet_ruleset_unit_flag(dest, &fpacket);
7964 }
7965
7966 unit_type_iterate(u) {
7967 packet.id = utype_number(u);
7968 sz_strlcpy(packet.name, untranslated_name(&u->name));
7969 sz_strlcpy(packet.rule_name, rule_name_get(&u->name));
7970 sz_strlcpy(packet.sound_move, u->sound_move);
7971 sz_strlcpy(packet.sound_move_alt, u->sound_move_alt);
7972 sz_strlcpy(packet.sound_fight, u->sound_fight);
7973 sz_strlcpy(packet.sound_fight_alt, u->sound_fight_alt);
7974 sz_strlcpy(packet.graphic_str, u->graphic_str);
7975 sz_strlcpy(packet.graphic_alt, u->graphic_alt);
7976 sz_strlcpy(packet.graphic_alt2, u->graphic_alt2);
7977 packet.unit_class_id = uclass_number(utype_class(u));
7978 packet.build_cost = u->build_cost;
7979 packet.pop_cost = u->pop_cost;
7980 packet.attack_strength = u->attack_strength;
7981 packet.defense_strength = u->defense_strength;
7982 packet.move_rate = u->move_rate;
7983
7984 i = 0;
7985 requirement_vector_iterate(&u->build_reqs, req) {
7986 packet.build_reqs[i++] = *req;
7987 } requirement_vector_iterate_end;
7988 packet.build_reqs_count = i;
7989
7990 packet.vision_radius_sq = u->vision_radius_sq;
7991 packet.transport_capacity = u->transport_capacity;
7992 packet.hp = u->hp;
7993 packet.firepower = u->firepower;
7994 packet.obsoleted_by = u->obsoleted_by
7995 ? utype_number(u->obsoleted_by)
7996 : utype_count();
7997 packet.converted_to = u->converted_to
7998 ? utype_number(u->converted_to)
7999 : utype_count();
8000 packet.convert_time = u->convert_time;
8001 packet.fuel = u->fuel;
8002 packet.flags = u->flags;
8003 packet.roles = u->roles;
8004 packet.happy_cost = u->happy_cost;
8005 output_type_iterate(o) {
8006 packet.upkeep[o] = u->upkeep[o];
8007 } output_type_iterate_end;
8008 packet.paratroopers_range = u->paratroopers_range;
8009 packet.bombard_rate = u->bombard_rate;
8010 packet.city_size = u->city_size;
8011 packet.city_slots = u->city_slots;
8012 packet.tp_defense = u->tp_defense;
8013 packet.cargo = u->cargo;
8014 packet.targets = u->targets;
8015 packet.embarks = u->embarks;
8016 packet.disembarks = u->disembarks;
8017 packet.vlayer = u->vlayer;
8018
8019 if (u->veteran == NULL) {
8020 /* Use the default veteran system. */
8021 packet.veteran_levels = 0;
8022 } else {
8023 /* Per unit veteran system definition. */
8024 packet.veteran_levels = utype_veteran_levels(u);
8025
8026 for (i = 0; i < packet.veteran_levels; i++) {
8027 const struct veteran_level *vlevel = utype_veteran_level(u, i);
8028
8029 sz_strlcpy(packet.veteran_name[i], untranslated_name(&vlevel->name));
8030 packet.power_fact[i] = vlevel->power_fact;
8031 packet.move_bonus[i] = vlevel->move_bonus;
8032 packet.base_raise_chance[i] = vlevel->base_raise_chance;
8033 packet.work_raise_chance[i] = vlevel->work_raise_chance;
8034 }
8035 }
8036 PACKET_STRVEC_INSERT(packet.helptext, u->helptext);
8037
8038 packet.worker = u->adv.worker;
8039
8040#ifdef FREECIV_WEB
8041 web_packet.id = utype_number(u);
8042
8043 BV_CLR_ALL(web_packet.utype_actions);
8044
8045 action_iterate(act) {
8046 if (utype_can_do_action(u, act)) {
8047 BV_SET(web_packet.utype_actions, act);
8048 }
8049 } action_iterate_end;
8050#endif /* FREECIV_WEB */
8051
8052 lsend_packet_ruleset_unit(dest, &packet);
8053 web_lsend_packet(ruleset_unit_addition, dest, &web_packet);
8054
8055 combat_bonus_list_iterate(u->bonuses, pbonus) {
8056 struct packet_ruleset_unit_bonus bonuspacket;
8057
8058 bonuspacket.unit = packet.id;
8059 bonuspacket.flag = pbonus->flag;
8060 bonuspacket.type = pbonus->type;
8061 bonuspacket.value = pbonus->value;
8062 bonuspacket.quiet = pbonus->quiet;
8063
8064 lsend_packet_ruleset_unit_bonus(dest, &bonuspacket);
8065 } combat_bonus_list_iterate_end;
8066 } unit_type_iterate_end;
8067}
8068
8069/**********************************************************************/
8073 static void send_ruleset_specialists(struct conn_list *dest)
8074{
8075 struct packet_ruleset_specialist packet;
8076
8077 specialist_type_iterate(spec_id) {
8078 struct specialist *s = specialist_by_number(spec_id);
8079 int j;
8080
8081 packet.id = spec_id;
8082 sz_strlcpy(packet.plural_name, untranslated_name(&s->name));
8083 sz_strlcpy(packet.rule_name, rule_name_get(&s->name));
8084 sz_strlcpy(packet.short_name, untranslated_name(&s->abbreviation));
8085 sz_strlcpy(packet.graphic_str, s->graphic_str);
8086 sz_strlcpy(packet.graphic_alt, s->graphic_alt);
8087 j = 0;
8088 requirement_vector_iterate(&s->reqs, preq) {
8089 packet.reqs[j++] = *preq;
8090 } requirement_vector_iterate_end;
8091 packet.reqs_count = j;
8092
8093 PACKET_STRVEC_INSERT(packet.helptext, s->helptext);
8094
8095 lsend_packet_ruleset_specialist(dest, &packet);
8096 } specialist_type_iterate_end;
8097}
8098/**********************************************************************/
8101 static void send_ruleset_tech_classes(struct conn_list *dest)
8102{
8103 struct packet_ruleset_tech_class packet;
8104
8105 tech_class_iterate(ptclass) {
8106 packet.id = ptclass->idx;
8107 sz_strlcpy(packet.name, untranslated_name(&ptclass->name));
8108 sz_strlcpy(packet.rule_name, rule_name_get(&ptclass->name));
8109 packet.cost_pct = ptclass->cost_pct;
8110
8111 lsend_packet_ruleset_tech_class(dest, &packet);
8112 } tech_class_iterate_end;
8113}
8114
8115/**********************************************************************/
8119 static void send_ruleset_techs(struct conn_list *dest)
8120{
8121 struct packet_ruleset_tech packet;
8122 struct packet_ruleset_tech_flag fpacket;
8123 int i;
8124
8125 for (i = 0; i < MAX_NUM_USER_TECH_FLAGS; i++) {
8126 const char *flagname;
8127 const char *helptxt;
8128
8129 fpacket.id = i + TECH_USER_1;
8130
8131 flagname = tech_flag_id_name_cb(i + TECH_USER_1);
8132 if (flagname == NULL) {
8133 fpacket.name[0] = '\0';
8134 } else {
8135 sz_strlcpy(fpacket.name, flagname);
8136 }
8137
8138 helptxt = tech_flag_helptxt(i + TECH_USER_1);
8139 if (helptxt == NULL) {
8140 fpacket.helptxt[0] = '\0';
8141 } else {
8142 sz_strlcpy(fpacket.helptxt, helptxt);
8143 }
8144
8145 lsend_packet_ruleset_tech_flag(dest, &fpacket);
8146 }
8147
8148 advance_iterate(a) {
8149 packet.id = advance_number(a);
8150 packet.removed = !valid_advance(a);
8151 if (a->tclass == NULL) {
8152 packet.tclass = 0;
8153 } else {
8154 packet.tclass = a->tclass->idx;
8155 }
8156 sz_strlcpy(packet.name, untranslated_name(&a->name));
8157 sz_strlcpy(packet.rule_name, rule_name_get(&a->name));
8158 sz_strlcpy(packet.graphic_str, a->graphic_str);
8159 sz_strlcpy(packet.graphic_alt, a->graphic_alt);
8160
8161 /* Current size of the packet's research_reqs requirement vector. */
8162 i = 0;
8163
8164 /* The requirements req1 and req2 are needed to research a tech. Send
8165 * them in the research_reqs requirement vector. Range is set to player
8166 * since pooled research is configurable. */
8167
8168 if ((a->require[AR_ONE] != A_NEVER)
8169 && advance_number(a->require[AR_ONE]) > A_NONE) {
8170 packet.research_reqs[i++]
8171 = req_from_values(VUT_ADVANCE, REQ_RANGE_PLAYER,
8172 FALSE, TRUE, FALSE,
8173 advance_number(a->require[AR_ONE]));
8174 }
8175
8176 if ((a->require[AR_TWO] != A_NEVER)
8177 && advance_number(a->require[AR_TWO]) > A_NONE) {
8178 packet.research_reqs[i++]
8179 = req_from_values(VUT_ADVANCE, REQ_RANGE_PLAYER,
8180 FALSE, TRUE, FALSE,
8181 advance_number(a->require[AR_TWO]));
8182 }
8183
8184 /* The requirements of the tech's research_reqs also goes in the
8185 * packet's research_reqs requirement vector. */
8186 requirement_vector_iterate(&a->research_reqs, req) {
8187 packet.research_reqs[i++] = *req;
8188 } requirement_vector_iterate_end;
8189
8190 /* The packet's research_reqs should contain req1, req2 and the
8191 * requirements of the tech's research_reqs. */
8192 packet.research_reqs_count = i;
8193
8194 packet.root_req = a->require[AR_ROOT]
8195 ? advance_number(a->require[AR_ROOT])
8196 : advance_count();
8197
8198 packet.flags = a->flags;
8199 packet.cost = a->cost;
8200 packet.num_reqs = a->num_reqs;
8201 PACKET_STRVEC_INSERT(packet.helptext, a->helptext);
8202
8203 lsend_packet_ruleset_tech(dest, &packet);
8204 } advance_iterate_end;
8205}
8206
8207/**********************************************************************/
8210 static void send_ruleset_counters(struct conn_list *dest)
8211{
8212 city_counters_iterate(pcount) {
8213 struct packet_ruleset_counter packet;
8214
8215 sz_strlcpy(packet.name, untranslated_name(&pcount->name));
8216 sz_strlcpy(packet.rule_name, rule_name_get(&pcount->name));
8217 packet.checkpoint = pcount->checkpoint;
8218 packet.behaviour = pcount->type;
8219 packet.type = pcount->target;
8220 packet.def = pcount->def;
8221
8222 PACKET_STRVEC_INSERT(packet.helptext, pcount->helptext);
8223 lsend_packet_ruleset_counter(dest, &packet);
8224 } city_counters_iterate_end;
8225}
8226
8227/**********************************************************************/
8231 static void send_ruleset_buildings(struct conn_list *dest)
8232{
8233 int i;
8234
8235 for (i = 0; i < MAX_NUM_USER_BUILDING_FLAGS; i++) {
8236 struct packet_ruleset_impr_flag fpacket;
8237 const char *flagname;
8238 const char *helptxt;
8239
8240 fpacket.id = i + IF_USER_FLAG_1;
8241
8242 flagname = impr_flag_id_name(i + IF_USER_FLAG_1);
8243 if (flagname == NULL) {
8244 fpacket.name[0] = '\0';
8245 } else {
8246 sz_strlcpy(fpacket.name, flagname);
8247 }
8248
8249 helptxt = impr_flag_helptxt(i + IF_USER_FLAG_1);
8250 if (helptxt == NULL) {
8251 fpacket.helptxt[0] = '\0';
8252 } else {
8253 sz_strlcpy(fpacket.helptxt, helptxt);
8254 }
8255
8256 lsend_packet_ruleset_impr_flag(dest, &fpacket);
8257 }
8258
8259 improvement_iterate(b) {
8260 struct packet_ruleset_building packet;
8261 int j;
8262
8263 packet.id = improvement_number(b);
8264 packet.genus = b->genus;
8265 sz_strlcpy(packet.name, untranslated_name(&b->name));
8266 sz_strlcpy(packet.rule_name, rule_name_get(&b->name));
8267 sz_strlcpy(packet.graphic_str, b->graphic_str);
8268 sz_strlcpy(packet.graphic_alt, b->graphic_alt);
8269 sz_strlcpy(packet.graphic_alt2, b->graphic_alt2);
8270 j = 0;
8271 requirement_vector_iterate(&b->reqs, preq) {
8272 packet.reqs[j++] = *preq;
8273 } requirement_vector_iterate_end;
8274 packet.reqs_count = j;
8275 j = 0;
8276 requirement_vector_iterate(&b->obsolete_by, pobs) {
8277 packet.obs_reqs[j++] = *pobs;
8278 } requirement_vector_iterate_end;
8279 packet.obs_count = j;
8280 packet.build_cost = b->build_cost;
8281 packet.upkeep = b->upkeep;
8282 packet.sabotage = b->sabotage;
8283 packet.flags = b->flags;
8284 sz_strlcpy(packet.soundtag, b->soundtag);
8285 sz_strlcpy(packet.soundtag_alt, b->soundtag_alt);
8286 sz_strlcpy(packet.soundtag_alt2, b->soundtag_alt2);
8287 PACKET_STRVEC_INSERT(packet.helptext, b->helptext);
8288
8289 lsend_packet_ruleset_building(dest, &packet);
8290 } improvement_iterate_end;
8291}
8292
8293/**********************************************************************/
8297 static void send_ruleset_terrain(struct conn_list *dest)
8298{
8299 struct packet_ruleset_terrain packet;
8300 struct packet_ruleset_terrain_flag fpacket;
8301 int i;
8302
8303 lsend_packet_ruleset_terrain_control(dest, &terrain_control);
8304
8305 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
8306 const char *flagname;
8307 const char *helptxt;
8308
8309 fpacket.id = i + TER_USER_1;
8310
8311 flagname = terrain_flag_id_name_cb(i + TER_USER_1);
8312 if (flagname == NULL) {
8313 fpacket.name[0] = '\0';
8314 } else {
8315 sz_strlcpy(fpacket.name, flagname);
8316 }
8317
8318 helptxt = terrain_flag_helptxt(i + TER_USER_1);
8319 if (helptxt == NULL) {
8320 fpacket.helptxt[0] = '\0';
8321 } else {
8322 sz_strlcpy(fpacket.helptxt, helptxt);
8323 }
8324
8325 lsend_packet_ruleset_terrain_flag(dest, &fpacket);
8326 }
8327
8328 terrain_type_iterate(pterrain) {
8329 packet.id = terrain_number(pterrain);
8330 packet.tclass = pterrain->tclass;
8331 packet.native_to = pterrain->native_to;
8332
8333 sz_strlcpy(packet.name, untranslated_name(&pterrain->name));
8334 sz_strlcpy(packet.rule_name, rule_name_get(&pterrain->name));
8335 sz_strlcpy(packet.graphic_str, pterrain->graphic_str);
8336 sz_strlcpy(packet.graphic_alt, pterrain->graphic_alt);
8337 sz_strlcpy(packet.graphic_alt2, pterrain->graphic_alt2);
8338
8339 packet.movement_cost = pterrain->movement_cost;
8340 packet.defense_bonus = pterrain->defense_bonus;
8341
8342 output_type_iterate(o) {
8343 packet.output[o] = pterrain->output[o];
8344 } output_type_iterate_end;
8345
8346 packet.num_resources = 0;
8347 terrain_resources_iterate(pterrain, res, freq) {
8348 packet.resources[packet.num_resources] = extra_number(res);
8349 packet.resource_freq[packet.num_resources] = freq;
8350 packet.num_resources++;
8351 } terrain_resources_iterate_end;
8352
8353 output_type_iterate(o) {
8354 packet.road_output_incr_pct[o] = pterrain->road_output_incr_pct[o];
8355 } output_type_iterate_end;
8356
8357 packet.base_time = pterrain->base_time;
8358 packet.road_time = pterrain->road_time;
8359
8360 packet.cultivate_result = (pterrain->cultivate_result
8361 ? terrain_number(pterrain->cultivate_result)
8362 : terrain_count());
8363 packet.cultivate_time = pterrain->cultivate_time;
8364
8365 packet.plant_result = (pterrain->plant_result
8366 ? terrain_number(pterrain->plant_result)
8367 : terrain_count());
8368 packet.plant_time = pterrain->plant_time;
8369
8370 packet.irrigation_food_incr = pterrain->irrigation_food_incr;
8371 packet.irrigation_time = pterrain->irrigation_time;
8372
8373 packet.mining_shield_incr = pterrain->mining_shield_incr;
8374 packet.mining_time = pterrain->mining_time;
8375
8376 packet.animal = (pterrain->animal == NULL ? -1 : utype_number(pterrain->animal));
8377 packet.transform_result = (pterrain->transform_result
8378 ? terrain_number(pterrain->transform_result)
8379 : terrain_count());
8380 packet.placing_time = pterrain->placing_time;
8381 packet.pillage_time = pterrain->pillage_time;
8382 packet.transform_time = pterrain->transform_time;
8383
8384 packet.extra_count = game.control.num_extra_types;
8385 for (i = 0; i < game.control.num_extra_types; i++) {
8386 packet.extra_removal_times[i] = pterrain->extra_removal_times[i];
8387 }
8388
8389 packet.flags = pterrain->flags;
8390
8391 packet.color_red = pterrain->rgb->r;
8392 packet.color_green = pterrain->rgb->g;
8393 packet.color_blue = pterrain->rgb->b;
8394
8395 PACKET_STRVEC_INSERT(packet.helptext, pterrain->helptext);
8396
8397 lsend_packet_ruleset_terrain(dest, &packet);
8398 } terrain_type_iterate_end;
8399}
8400
8401/**********************************************************************/
8404 static void send_ruleset_resources(struct conn_list *dest)
8405{
8406 struct packet_ruleset_resource packet;
8407
8408 extra_type_by_cause_iterate(EC_RESOURCE, presource) {
8409 packet.id = extra_index(presource);
8410
8411 output_type_iterate(o) {
8412 packet.output[o] = presource->data.resource->output[o];
8413 } output_type_iterate_end;
8414
8415 lsend_packet_ruleset_resource(dest, &packet);
8416 } extra_type_by_cause_iterate_end;
8417}
8418
8419/**********************************************************************/
8423 static void send_ruleset_extras(struct conn_list *dest)
8424{
8425 int i;
8426
8427 for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
8428 struct packet_ruleset_extra_flag fpacket;
8429 const char *flagname;
8430 const char *helptxt;
8431
8432 fpacket.id = i + EF_USER_FLAG_1;
8433
8434 flagname = extra_flag_id_name(i + EF_USER_FLAG_1);
8435 if (flagname == NULL) {
8436 fpacket.name[0] = '\0';
8437 } else {
8438 sz_strlcpy(fpacket.name, flagname);
8439 }
8440
8441 helptxt = extra_flag_helptxt(i + EF_USER_FLAG_1);
8442 if (helptxt == NULL) {
8443 fpacket.helptxt[0] = '\0';
8444 } else {
8445 sz_strlcpy(fpacket.helptxt, helptxt);
8446 }
8447
8448 lsend_packet_ruleset_extra_flag(dest, &fpacket);
8449 }
8450
8451 extra_type_iterate(e) {
8452 struct packet_ruleset_extra packet;
8453 int j;
8454
8455 packet.id = extra_number(e);
8456 sz_strlcpy(packet.name, untranslated_name(&e->name));
8457 sz_strlcpy(packet.rule_name, rule_name_get(&e->name));
8458
8459 packet.category = e->category;
8460
8461 BV_CLR_ALL(packet.causes);
8462 for (j = 0; j < EC_COUNT; j++) {
8463 if (is_extra_caused_by(e, j)) {
8464 BV_SET(packet.causes, j);
8465 }
8466 }
8467
8468 BV_CLR_ALL(packet.rmcauses);
8469 for (j = 0; j < ERM_COUNT; j++) {
8470 if (is_extra_removed_by(e, j)) {
8471 BV_SET(packet.rmcauses, j);
8472 }
8473 }
8474
8475 sz_strlcpy(packet.activity_gfx, e->activity_gfx);
8476 sz_strlcpy(packet.act_gfx_alt, e->act_gfx_alt);
8477 sz_strlcpy(packet.act_gfx_alt2, e->act_gfx_alt2);
8478 sz_strlcpy(packet.rmact_gfx, e->rmact_gfx);
8479 sz_strlcpy(packet.rmact_gfx_alt, e->rmact_gfx_alt);
8480 sz_strlcpy(packet.rmact_gfx_alt2, e->rmact_gfx_alt2);
8481 sz_strlcpy(packet.graphic_str, e->graphic_str);
8482 sz_strlcpy(packet.graphic_alt, e->graphic_alt);
8483
8484 j = 0;
8485 requirement_vector_iterate(&e->reqs, preq) {
8486 packet.reqs[j++] = *preq;
8487 } requirement_vector_iterate_end;
8488 packet.reqs_count = j;
8489
8490 j = 0;
8491 requirement_vector_iterate(&e->rmreqs, preq) {
8492 packet.rmreqs[j++] = *preq;
8493 } requirement_vector_iterate_end;
8494 packet.rmreqs_count = j;
8495
8496 packet.appearance_chance = e->appearance_chance;
8497 j = 0;
8498 requirement_vector_iterate(&e->appearance_reqs, preq) {
8499 packet.appearance_reqs[j++] = *preq;
8500 } requirement_vector_iterate_end;
8501 packet.appearance_reqs_count = j;
8502
8503 packet.disappearance_chance = e->disappearance_chance;
8504 j = 0;
8505 requirement_vector_iterate(&e->disappearance_reqs, preq) {
8506 packet.disappearance_reqs[j++] = *preq;
8507 } requirement_vector_iterate_end;
8508 packet.disappearance_reqs_count = j;
8509
8510 packet.visibility_req = e->visibility_req;
8511 packet.buildable = e->buildable;
8512 packet.generated = e->generated;
8513 packet.build_time = e->build_time;
8514 packet.build_time_factor = e->build_time_factor;
8515 packet.removal_time = e->removal_time;
8516 packet.removal_time_factor = e->removal_time_factor;
8517 packet.infracost = e->infracost;
8518 packet.defense_bonus = e->defense_bonus;
8519 packet.eus = e->eus;
8520 packet.no_aggr_near_city = e->no_aggr_near_city;
8521
8522 packet.native_to = e->native_to;
8523
8524 packet.flags = e->flags;
8525 packet.hidden_by = e->hidden_by;
8526 packet.bridged_over = e->bridged_over;
8527 packet.conflicts = e->conflicts;
8528
8529 PACKET_STRVEC_INSERT(packet.helptext, e->helptext);
8530
8531 lsend_packet_ruleset_extra(dest, &packet);
8532 } extra_type_iterate_end;
8533}
8534
8535/**********************************************************************/
8539 static void send_ruleset_bases(struct conn_list *dest)
8540{
8541 extra_type_by_cause_iterate(EC_BASE, pextra) {
8542 struct base_type *b = extra_base_get(pextra);
8543 struct packet_ruleset_base packet;
8544
8545 packet.id = base_number(b);
8546
8547 packet.gui_type = b->gui_type;
8548 packet.border_sq = b->border_sq;
8549 packet.vision_main_sq = b->vision_main_sq;
8550 packet.vision_invis_sq = b->vision_invis_sq;
8551 packet.vision_subs_sq = b->vision_subs_sq;
8552
8553 lsend_packet_ruleset_base(dest, &packet);
8554 } extra_type_by_cause_iterate_end;
8555}
8556
8557/**********************************************************************/
8561 static void send_ruleset_roads(struct conn_list *dest)
8562{
8563 struct packet_ruleset_road packet;
8564
8565 extra_type_by_cause_iterate(EC_ROAD, pextra) {
8566 struct road_type *r = extra_road_get(pextra);
8567 int j;
8568
8569 packet.id = road_number(r);
8570
8571 packet.gui_type = r->gui_type;
8572
8573 j = 0;
8574 requirement_vector_iterate(&r->first_reqs, preq) {
8575 packet.first_reqs[j++] = *preq;
8576 } requirement_vector_iterate_end;
8577 packet.first_reqs_count = j;
8578
8579 packet.move_cost = r->move_cost;
8580 packet.move_mode = r->move_mode;
8581
8582 output_type_iterate(o) {
8583 packet.tile_incr_const[o] = r->tile_incr_const[o];
8584 packet.tile_incr[o] = r->tile_incr[o];
8585 packet.tile_bonus[o] = r->tile_bonus[o];
8586 } output_type_iterate_end;
8587
8588 packet.compat = r->compat;
8589
8590 packet.integrates = r->integrates;
8591 packet.flags = r->flags;
8592
8593 lsend_packet_ruleset_road(dest, &packet);
8594 } extra_type_by_cause_iterate_end;
8595}
8596
8597/**********************************************************************/
8601 static void send_ruleset_goods(struct conn_list *dest)
8602{
8603 struct packet_ruleset_goods packet;
8604
8605 goods_type_iterate(g) {
8606 int j;
8607
8608 packet.id = goods_number(g);
8609 sz_strlcpy(packet.name, untranslated_name(&g->name));
8610 sz_strlcpy(packet.rule_name, rule_name_get(&g->name));
8611
8612 j = 0;
8613 requirement_vector_iterate(&g->reqs, preq) {
8614 packet.reqs[j++] = *preq;
8615 } requirement_vector_iterate_end;
8616 packet.reqs_count = j;
8617
8618 packet.from_pct = g->from_pct;
8619 packet.to_pct = g->to_pct;
8620 packet.onetime_pct = g->onetime_pct;
8621 packet.flags = g->flags;
8622
8623 PACKET_STRVEC_INSERT(packet.helptext, g->helptext);
8624
8625 lsend_packet_ruleset_goods(dest, &packet);
8626 } goods_type_iterate_end;
8627}
8628
8629/**********************************************************************/
8633 static void send_ruleset_disasters(struct conn_list *dest)
8634{
8635 struct packet_ruleset_disaster packet;
8636
8637 disaster_type_iterate(d) {
8638 int j;
8639
8640 packet.id = disaster_number(d);
8641
8642 sz_strlcpy(packet.name, untranslated_name(&d->name));
8643 sz_strlcpy(packet.rule_name, rule_name_get(&d->name));
8644
8645 j = 0;
8646 requirement_vector_iterate(&d->reqs, preq) {
8647 packet.reqs[j++] = *preq;
8648 } requirement_vector_iterate_end;
8649 packet.reqs_count = j;
8650
8651 packet.frequency = d->frequency;
8652
8653 packet.effects = d->effects;
8654
8655 lsend_packet_ruleset_disaster(dest, &packet);
8656 } disaster_type_iterate_end;
8657}
8658
8659/**********************************************************************/
8663 static void send_ruleset_achievements(struct conn_list *dest)
8664{
8665 struct packet_ruleset_achievement packet;
8666
8667 achievements_iterate(a) {
8668 packet.id = achievement_number(a);
8669
8670 sz_strlcpy(packet.name, untranslated_name(&a->name));
8671 sz_strlcpy(packet.rule_name, rule_name_get(&a->name));
8672
8673 packet.type = a->type;
8674 packet.unique = a->unique;
8675 packet.value = a->value;
8676
8677 lsend_packet_ruleset_achievement(dest, &packet);
8678 } achievements_iterate_end;
8679}
8680
8681/**********************************************************************/
8684 static void send_ruleset_actions(struct conn_list *dest)
8685{
8686 struct packet_ruleset_action packet;
8687
8688 action_iterate(act) {
8689 struct action *paction = action_by_number(act);
8690
8691 packet.id = act;
8692 sz_strlcpy(packet.ui_name, action_by_number(act)->ui_name);
8693 packet.quiet = action_by_number(act)->quiet;
8694
8695 packet.result = paction->result;
8696 packet.sub_results = paction->sub_results;
8697 packet.actor_consuming_always = paction->actor_consuming_always;
8698
8699 packet.act_kind = action_by_number(act)->actor_kind;
8700 packet.tgt_kind = action_by_number(act)->target_kind;
8701 packet.sub_tgt_kind = action_id_get_sub_target_kind(act);
8702
8703 packet.min_distance = action_by_number(act)->min_distance;
8704 packet.max_distance = action_by_number(act)->max_distance;
8705 packet.blocked_by = action_by_number(act)->blocked_by;
8706
8707 lsend_packet_ruleset_action(dest, &packet);
8708 } action_iterate_end;
8709}
8710
8711/**********************************************************************/
8714 static void send_ruleset_action_enablers(struct conn_list *dest)
8715{
8716 int counter;
8717 struct packet_ruleset_action_enabler packet;
8718
8719 action_enablers_iterate(enabler) {
8720 packet.enabled_action = enabler_get_action_id(enabler);
8721
8722 counter = 0;
8723 requirement_vector_iterate(&enabler->actor_reqs, req) {
8724 packet.actor_reqs[counter++] = *req;
8725 } requirement_vector_iterate_end;
8726 packet.actor_reqs_count = counter;
8727
8728 counter = 0;
8729 requirement_vector_iterate(&enabler->target_reqs, req) {
8730 packet.target_reqs[counter++] = *req;
8731 } requirement_vector_iterate_end;
8732 packet.target_reqs_count = counter;
8733
8734 lsend_packet_ruleset_action_enabler(dest, &packet);
8735 } action_enablers_iterate_end;
8736}
8737
8738/**********************************************************************/
8742 static void send_ruleset_action_auto_performers(struct conn_list *dest)
8743{
8744 int counter;
8745 int id;
8746 struct packet_ruleset_action_auto packet;
8747
8748 id = 0;
8749 action_auto_perf_iterate(aperf) {
8750 packet.id = id++;
8751
8752 packet.cause = aperf->cause;
8753
8754 counter = 0;
8755 requirement_vector_iterate(&aperf->reqs, req) {
8756 packet.reqs[counter++] = *req;
8757 } requirement_vector_iterate_end;
8758 packet.reqs_count = counter;
8759
8760 for (counter = 0;
8761 /* Can't list more actions than all actions. */
8762 counter < NUM_ACTIONS
8763 /* ACTION_NONE terminates the list. */
8764 && aperf->alternatives[counter] != ACTION_NONE;
8765 counter++) {
8766 packet.alternatives[counter] = aperf->alternatives[counter];
8767 }
8768 packet.alternatives_count = counter;
8769
8770 lsend_packet_ruleset_action_auto(dest, &packet);
8771 } action_auto_perf_iterate_end;
8772}
8773
8774/**********************************************************************/
8778 static void send_ruleset_trade_routes(struct conn_list *dest)
8779{
8780 struct packet_ruleset_trade packet;
8781 enum trade_route_type type;
8782
8783 for (type = TRT_NATIONAL; type < TRT_LAST; type++) {
8784 struct trade_route_settings *set = trade_route_settings_by_type(type);
8785
8786 packet.id = type;
8787 packet.trade_pct = set->trade_pct;
8788 packet.cancelling = set->cancelling;
8789 packet.bonus_type = set->bonus_type;
8790
8791 lsend_packet_ruleset_trade(dest, &packet);
8792 }
8793}
8794
8795/**********************************************************************/
8799 static void send_ruleset_governments(struct conn_list *dest)
8800{
8801 struct packet_ruleset_government gov;
8802 struct packet_ruleset_government_ruler_title title;
8803 int j;
8804
8805 governments_iterate(g) {
8806 /* send one packet_government */
8807 gov.id = government_number(g);
8808
8809 j = 0;
8810 requirement_vector_iterate(&g->reqs, preq) {
8811 gov.reqs[j++] = *preq;
8812 } requirement_vector_iterate_end;
8813 gov.reqs_count = j;
8814
8815 sz_strlcpy(gov.name, untranslated_name(&g->name));
8816 sz_strlcpy(gov.rule_name, rule_name_get(&g->name));
8817 sz_strlcpy(gov.graphic_str, g->graphic_str);
8818 sz_strlcpy(gov.graphic_alt, g->graphic_alt);
8819 PACKET_STRVEC_INSERT(gov.helptext, g->helptext);
8820
8821 lsend_packet_ruleset_government(dest, &gov);
8822
8823 /* Send one packet_government_ruler_title per ruler title. */
8824 ruler_titles_iterate(government_ruler_titles(g), pruler_title) {
8825 const struct nation_type *pnation = ruler_title_nation(pruler_title);
8826
8827 title.gov = government_number(g);
8828 title.nation = pnation ? nation_number(pnation) : nation_count();
8829 sz_strlcpy(title.male_title,
8830 ruler_title_male_untranslated_name(pruler_title));
8831 sz_strlcpy(title.female_title,
8832 ruler_title_female_untranslated_name(pruler_title));
8833 lsend_packet_ruleset_government_ruler_title(dest, &title);
8834 } ruler_titles_iterate_end;
8835 } governments_iterate_end;
8836}
8837
8838/**********************************************************************/
8842 static void send_ruleset_nations(struct conn_list *dest)
8843{
8844 struct packet_ruleset_nation_sets sets_packet;
8845 struct packet_ruleset_nation_groups groups_packet;
8846 struct packet_ruleset_nation packet;
8847 int i;
8848
8849 sets_packet.nsets = nation_set_count();
8850 i = 0;
8851 nation_sets_iterate(pset) {
8852 sz_strlcpy(sets_packet.names[i], nation_set_untranslated_name(pset));
8853 sz_strlcpy(sets_packet.rule_names[i], nation_set_rule_name(pset));
8854 sz_strlcpy(sets_packet.descriptions[i], nation_set_description(pset));
8855 i++;
8856 } nation_sets_iterate_end;
8857 lsend_packet_ruleset_nation_sets(dest, &sets_packet);
8858
8859 groups_packet.ngroups = nation_group_count();
8860 i = 0;
8861 nation_groups_iterate(pgroup) {
8862 sz_strlcpy(groups_packet.groups[i],
8863 nation_group_untranslated_name(pgroup));
8864 groups_packet.hidden[i] = pgroup->hidden;
8865 i++;
8866 } nation_groups_iterate_end;
8867 lsend_packet_ruleset_nation_groups(dest, &groups_packet);
8868
8869 nations_iterate(n) {
8870 packet.id = nation_number(n);
8871 if (n->translation_domain == NULL) {
8872 packet.translation_domain[0] = '\0';
8873 } else {
8874 sz_strlcpy(packet.translation_domain, n->translation_domain);
8875 }
8876 sz_strlcpy(packet.adjective, untranslated_name(&n->adjective));
8877 sz_strlcpy(packet.rule_name, rule_name_get(&n->adjective));
8878 sz_strlcpy(packet.noun_plural, untranslated_name(&n->noun_plural));
8879 sz_strlcpy(packet.graphic_str, n->flag_graphic_str);
8880 sz_strlcpy(packet.graphic_alt, n->flag_graphic_alt);
8881
8882 i = 0;
8883 nation_leader_list_iterate(nation_leaders(n), pleader) {
8884 sz_strlcpy(packet.leader_name[i], nation_leader_name(pleader));
8885 packet.leader_is_male[i] = nation_leader_is_male(pleader);
8886 i++;
8887 } nation_leader_list_iterate_end;
8888 packet.leader_count = i;
8889
8890 packet.style = style_number(n->style);
8891 packet.is_playable = n->is_playable;
8892 packet.barbarian_type = n->barb_type;
8893
8894 sz_strlcpy(packet.legend, n->legend);
8895
8896 i = 0;
8897 nation_set_list_iterate(n->sets, pset) {
8898 packet.sets[i++] = nation_set_number(pset);
8899 } nation_set_list_iterate_end;
8900 packet.nsets = i;
8901
8902 i = 0;
8903 nation_group_list_iterate(n->groups, pgroup) {
8904 packet.groups[i++] = nation_group_number(pgroup);
8905 } nation_group_list_iterate_end;
8906 packet.ngroups = i;
8907
8908 packet.init_government_id = n->init_government
8909 ? government_number(n->init_government) : government_count();
8910 fc_assert(ARRAY_SIZE(packet.init_techs) == ARRAY_SIZE(n->init_techs));
8911 for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
8912 if (n->init_techs[i] != A_LAST) {
8913 packet.init_techs[i] = n->init_techs[i];
8914 } else {
8915 break;
8916 }
8917 }
8918 packet.init_techs_count = i;
8919 fc_assert(ARRAY_SIZE(packet.init_units) == ARRAY_SIZE(n->init_units));
8920 for (i = 0; i < MAX_NUM_UNIT_LIST; i++) {
8921 const struct unit_type *t = n->init_units[i];
8922 if (t) {
8923 packet.init_units[i] = utype_number(t);
8924 } else {
8925 break;
8926 }
8927 }
8928 packet.init_units_count = i;
8929 fc_assert(ARRAY_SIZE(packet.init_buildings)
8930 == ARRAY_SIZE(n->init_buildings));
8931 for (i = 0; i < MAX_NUM_BUILDING_LIST; i++) {
8932 if (n->init_buildings[i] != B_LAST) {
8933 /* Impr_type_id to int */
8934 packet.init_buildings[i] = n->init_buildings[i];
8935 } else {
8936 break;
8937 }
8938 }
8939 packet.init_buildings_count = i;
8940
8941 lsend_packet_ruleset_nation(dest, &packet);
8942 } nations_iterate_end;
8943
8944 /* Send initial values of is_pickable */
8945 send_nation_availability(dest, FALSE);
8946}
8947
8948/**********************************************************************/
8952 static void send_ruleset_styles(struct conn_list *dest)
8953{
8954 struct packet_ruleset_style packet;
8955
8956 styles_iterate(s) {
8957 packet.id = style_index(s);
8958 sz_strlcpy(packet.name, untranslated_name(&s->name));
8959 sz_strlcpy(packet.rule_name, rule_name_get(&s->name));
8960
8961 lsend_packet_ruleset_style(dest, &packet);
8962 } styles_iterate_end;
8963}
8964
8965/**********************************************************************/
8968 static void send_ruleset_clauses(struct conn_list *dest)
8969{
8970 struct packet_ruleset_clause packet;
8971 int i;
8972
8973 for (i = 0; i < CLAUSE_COUNT; i++) {
8974 struct clause_info *info = clause_info_get(i);
8975 int j;
8976
8977 packet.type = i;
8978 packet.enabled = info->enabled;
8979
8980 j = 0;
8981 requirement_vector_iterate(&info->giver_reqs, preq) {
8982 packet.giver_reqs[j++] = *preq;
8983 } requirement_vector_iterate_end;
8984 packet.giver_reqs_count = j;
8985
8986 j = 0;
8987 requirement_vector_iterate(&info->receiver_reqs, preq) {
8988 packet.receiver_reqs[j++] = *preq;
8989 } requirement_vector_iterate_end;
8990 packet.receiver_reqs_count = j;
8991
8992 j = 0;
8993 requirement_vector_iterate(&info->either_reqs, preq) {
8994 packet.either_reqs[j++] = *preq;
8995 } requirement_vector_iterate_end;
8996 packet.either_reqs_count = j;
8997
8998 lsend_packet_ruleset_clause(dest, &packet);
8999 }
9000}
9001
9002/**********************************************************************/
9006 static void send_ruleset_multipliers(struct conn_list *dest)
9007{
9008 multipliers_iterate(pmul) {
9009 int j;
9010 struct packet_ruleset_multiplier packet;
9011
9012 packet.id = multiplier_number(pmul);
9013 packet.start = pmul->start;
9014 packet.stop = pmul->stop;
9015 packet.step = pmul->step;
9016 packet.def = pmul->def;
9017 packet.offset = pmul->offset;
9018 packet.factor = pmul->factor;
9019 packet.minimum_turns = pmul->minimum_turns;
9020
9021 sz_strlcpy(packet.name, untranslated_name(&pmul->name));
9022 sz_strlcpy(packet.rule_name, rule_name_get(&pmul->name));
9023
9024 j = 0;
9025 requirement_vector_iterate(&pmul->reqs, preq) {
9026 packet.reqs[j++] = *preq;
9027 } requirement_vector_iterate_end;
9028 packet.reqs_count = j;
9029
9030 PACKET_STRVEC_INSERT(packet.helptext, pmul->helptext);
9031
9032 lsend_packet_ruleset_multiplier(dest, &packet);
9033 } multipliers_iterate_end;
9034}
9035
9036/**********************************************************************/
9040 static void send_ruleset_cities(struct conn_list *dest)
9041{
9042 struct packet_ruleset_city city_p;
9043 int k, j;
9044
9045 for (k = 0; k < game.control.num_city_styles; k++) {
9046 city_p.style_id = k;
9047
9048 j = 0;
9049 requirement_vector_iterate(&city_styles[k].reqs, preq) {
9050 city_p.reqs[j++] = *preq;
9051 } requirement_vector_iterate_end;
9052 city_p.reqs_count = j;
9053
9054 sz_strlcpy(city_p.name, untranslated_name(&city_styles[k].name));
9055 sz_strlcpy(city_p.rule_name, rule_name_get(&city_styles[k].name));
9056 sz_strlcpy(city_p.graphic, city_styles[k].graphic);
9057 sz_strlcpy(city_p.graphic_alt, city_styles[k].graphic_alt);
9058 sz_strlcpy(city_p.citizens_graphic, city_styles[k].citizens_graphic);
9059
9060 lsend_packet_ruleset_city(dest, &city_p);
9061 }
9062}
9063
9064/**********************************************************************/
9068 static void send_ruleset_musics(struct conn_list *dest)
9069{
9070 struct packet_ruleset_music packet;
9071
9072 music_styles_iterate(pmus) {
9073 int j;
9074
9075 packet.id = pmus->id;
9076
9077 sz_strlcpy(packet.music_peaceful, pmus->music_peaceful);
9078 sz_strlcpy(packet.music_combat, pmus->music_combat);
9079
9080 j = 0;
9081 requirement_vector_iterate(&(pmus->reqs), preq) {
9082 packet.reqs[j++] = *preq;
9083 } requirement_vector_iterate_end;
9084 packet.reqs_count = j;
9085
9086 lsend_packet_ruleset_music(dest, &packet);
9087 } music_styles_iterate_end;
9088}
9089
9090/**********************************************************************/
9094 static void send_ruleset_game(struct conn_list *dest)
9095{
9096 struct packet_ruleset_game misc_p;
9097 int i;
9098
9099 fc_assert_ret(game.veteran != NULL);
9100
9101 /* Per unit veteran system definition. */
9102 misc_p.veteran_levels = game.veteran->levels;
9103
9104 for (i = 0; i < misc_p.veteran_levels; i++) {
9105 const struct veteran_level *vlevel = game.veteran->definitions + i;
9106
9107 sz_strlcpy(misc_p.veteran_name[i], untranslated_name(&vlevel->name));
9108 misc_p.power_fact[i] = vlevel->power_fact;
9109 misc_p.move_bonus[i] = vlevel->move_bonus;
9110 misc_p.base_raise_chance[i] = vlevel->base_raise_chance;
9111 misc_p.work_raise_chance[i] = vlevel->work_raise_chance;
9112 }
9113
9114 fc_assert(sizeof(misc_p.global_init_techs)
9115 == sizeof(game.rgame.global_init_techs));
9116 fc_assert(ARRAY_SIZE(misc_p.global_init_techs)
9117 == ARRAY_SIZE(game.rgame.global_init_techs));
9118 for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
9119 if (game.rgame.global_init_techs[i] != A_LAST) {
9120 misc_p.global_init_techs[i] = game.rgame.global_init_techs[i];
9121 } else {
9122 break;
9123 }
9124 }
9125 misc_p.global_init_techs_count = i;
9126
9127 fc_assert(ARRAY_SIZE(misc_p.global_init_buildings)
9128 == ARRAY_SIZE(game.rgame.global_init_buildings));
9129 for (i = 0; i < MAX_NUM_BUILDING_LIST; i++) {
9130 if (game.rgame.global_init_buildings[i] != B_LAST) {
9131 /* Impr_type_id to int */
9132 misc_p.global_init_buildings[i] =
9133 game.rgame.global_init_buildings[i];
9134 } else {
9135 break;
9136 }
9137 }
9138 misc_p.global_init_buildings_count = i;
9139
9140 misc_p.default_specialist = DEFAULT_SPECIALIST;
9141
9142 fc_assert_ret(game.plr_bg_color != NULL);
9143
9144 misc_p.background_red = game.plr_bg_color->r;
9145 misc_p.background_green = game.plr_bg_color->g;
9146 misc_p.background_blue = game.plr_bg_color->b;
9147
9148 lsend_packet_ruleset_game(dest, &misc_p);
9149}
9150
9151/**********************************************************************/
9155 static void send_ruleset_team_names(struct conn_list *dest)
9156{
9157 struct packet_team_name_info team_name_info_p;
9158
9159 team_slots_iterate(tslot) {
9160 const char *name = team_slot_defined_name(tslot);
9161
9162 if (NULL == name) {
9163 /* End of defined names. */
9164 break;
9165 }
9166
9167 team_name_info_p.team_id = team_slot_index(tslot);
9168 sz_strlcpy(team_name_info_p.team_name, name);
9169
9170 lsend_packet_team_name_info(dest, &team_name_info_p);
9171 } team_slots_iterate_end;
9172}
9173
9174/**********************************************************************/
9177 static void notify_ruleset_fallback(const char *msg)
9178{
9179 notify_conn(NULL, NULL, E_LOG_FATAL, ftc_warning, "%s", msg);
9180}
9181
9182/**********************************************************************/
9185 bool load_rulesets(const char *restore, const char *alt, bool compat_mode,
9186 rs_conversion_logger logger,
9187 bool act, bool buffer_script, bool load_luadata)
9188{
9189 set_ruleset_compat_mode(compat_mode);
9190
9191 if (load_rulesetdir(game.server.rulesetdir, compat_mode, logger,
9192 act, buffer_script, load_luadata)) {
9193 set_ruleset_compat_mode(FALSE);
9194 return TRUE;
9195 }
9196
9197 if (alt != NULL) {
9198 if (load_rulesetdir(alt, compat_mode, logger, act, buffer_script,
9199 load_luadata)) {
9200 sz_strlcpy(game.server.rulesetdir, alt);
9201
9202 set_ruleset_compat_mode(FALSE);
9203 return TRUE;
9204 }
9205 }
9206
9207 /* Fallback to previous one. */
9208 if (restore != NULL) {
9209 if (load_rulesetdir(restore, compat_mode, logger, act, buffer_script, TRUE)) {
9210 sz_strlcpy(game.server.rulesetdir, restore);
9211
9212 notify_ruleset_fallback(_("Ruleset couldn't be loaded. Keeping previous one."));
9213
9214 set_ruleset_compat_mode(FALSE);
9215
9216 /* We're in sane state as restoring previous ruleset succeeded,
9217 * but return failure to indicate that this is not what caller
9218 * wanted. */
9219 return FALSE;
9220 }
9221 }
9222
9223 set_ruleset_compat_mode(FALSE);
9224
9225 /* Fallback to default one, but not if that's what we tried already */
9226 if (strcmp(GAME_DEFAULT_RULESETDIR, game.server.rulesetdir)
9227 && (restore == NULL || strcmp(GAME_DEFAULT_RULESETDIR, restore))) {
9228 if (load_rulesetdir(GAME_DEFAULT_RULESETDIR, FALSE, NULL, act, buffer_script, TRUE)) {
9229 /* We're in sane state as fallback ruleset loading succeeded,
9230 * but return failure to indicate that this is not what caller
9231 * wanted. */
9232 sz_strlcpy(game.server.rulesetdir, GAME_DEFAULT_RULESETDIR);
9233
9234 notify_ruleset_fallback(_("Ruleset couldn't be loaded. Switching to default one."));
9235
9236 return FALSE;
9237 }
9238 }
9239
9240#ifdef FREECIV_WEB
9241 log_normal(_("Cannot load any ruleset. Freeciv-web ruleset is available from "
9242 "https://github.com/freeciv/freeciv-web"));
9243#endif /* FREECIV_WEB */
9244
9245 /* Cannot load even default ruleset, we're in completely unusable state */
9246 exit(EXIT_FAILURE);
9247
9248 RETURN_VALUE_AFTER_EXIT(FALSE);
9249}
9250
9251/**********************************************************************/
9254 static void nullcheck_secfile_destroy(struct section_file *file)
9255{
9256 if (file != NULL) {
9257 secfile_destroy(file);
9258 }
9259}
9260
9261/**********************************************************************/
9265 void rulesets_deinit(void)
9266{
9267 script_server_free();
9268 requirement_vector_free(&reqs_list);
9269}
9270
9271/**********************************************************************/
9275 static bool load_rulesetdir(const char *rsdir, bool compat_mode,
9276 rs_conversion_logger logger,
9277 bool act, bool buffer_script, bool load_luadata)
9278{
9279 struct section_file *techfile, *unitfile, *buildfile, *govfile, *terrfile;
9280 struct section_file *stylefile, *cityfile, *nationfile, *effectfile, *gamefile;
9281 struct section_file *actionfile;
9282 bool ok = TRUE;
9283 struct rscompat_info compat_info;
9284
9285 log_normal(_("Loading rulesets."));
9286
9287 rscompat_init_info(&compat_info);
9288 compat_info.compat_mode = compat_mode;
9289 compat_info.log_cb = logger;
9290
9291 game_ruleset_free();
9292 /* Reset the list of available player colors. */
9293 playercolor_free();
9294 playercolor_init();
9295 game_ruleset_init();
9296
9297 if (script_buffer != NULL) {
9298 FC_FREE(script_buffer);
9299 script_buffer = NULL;
9300 }
9301 if (parser_buffer != NULL) {
9302 FC_FREE(parser_buffer);
9303 parser_buffer = NULL;
9304 }
9305
9306 server.playable_nations = 0;
9307
9308 gamefile = openload_ruleset_file("game", rsdir);
9309 techfile = openload_ruleset_file("techs", rsdir);
9310 actionfile = openload_ruleset_file("actions", rsdir);
9311 buildfile = openload_ruleset_file("buildings", rsdir);
9312 govfile = openload_ruleset_file("governments", rsdir);
9313 unitfile = openload_ruleset_file("units", rsdir);
9314 terrfile = openload_ruleset_file("terrain", rsdir);
9315 stylefile = openload_ruleset_file("styles", rsdir);
9316 cityfile = openload_ruleset_file("cities", rsdir);
9317 nationfile = openload_ruleset_file("nations", rsdir);
9318 effectfile = openload_ruleset_file("effects", rsdir);
9319
9320 if (load_luadata) {
9321 game.server.luadata = openload_luadata_file(rsdir);
9322 } else {
9323 game.server.luadata = NULL;
9324 }
9325
9326 if (techfile == NULL
9327 || buildfile == NULL
9328 || govfile == NULL
9329 || unitfile == NULL
9330 || terrfile == NULL
9331 || stylefile == NULL
9332 || cityfile == NULL
9333 || nationfile == NULL
9334 || effectfile == NULL
9335 || actionfile == NULL
9336 || gamefile == NULL) {
9337 ok = FALSE;
9338 }
9339
9340 if (ok) {
9341 /* Note: Keep load_game_names() first so that compat_info.version is
9342 * correctly initialized. */
9343 ok = load_game_names(gamefile, &compat_info)
9344 && load_action_names(actionfile, &compat_info)
9345 && load_tech_names(techfile, &compat_info)
9346 && load_building_names(buildfile, &compat_info)
9347 && load_government_names(govfile, &compat_info)
9348 && load_unit_names(unitfile, &compat_info)
9349 && load_terrain_names(terrfile, &compat_info)
9350 && load_style_names(stylefile, &compat_info)
9351 && load_nation_names(nationfile, &compat_info);
9352 }
9353
9354 if (ok) {
9355 ok = rscompat_names(&compat_info);
9356 }
9357
9358 if (ok) {
9359 ok = load_ruleset_techs(techfile, &compat_info);
9360 }
9361 if (ok) {
9362 ok = load_ruleset_styles(stylefile, &compat_info);
9363 }
9364 if (ok) {
9365 ok = load_ruleset_cities(cityfile, &compat_info);
9366 }
9367 if (ok) {
9368 ok = load_ruleset_governments(govfile, &compat_info);
9369 }
9370 if (ok) {
9371 /* Terrain must precede nations and units */
9372 ok = load_ruleset_terrain(terrfile, &compat_info);
9373 }
9374 if (ok) {
9375 ok = load_ruleset_units(unitfile, &compat_info);
9376 }
9377 if (ok) {
9378 ok = load_ruleset_buildings(buildfile, &compat_info);
9379 }
9380 if (ok) {
9381 ok = load_ruleset_nations(nationfile, &compat_info);
9382 }
9383 if (ok) {
9384 ok = load_ruleset_effects(effectfile, &compat_info);
9385 }
9386 if (ok) {
9387 ok = load_ruleset_actions(actionfile, gamefile, &compat_info);
9388 }
9389 if (ok) {
9390 ok = load_ruleset_game(gamefile, act, &compat_info);
9391 }
9392
9393 if (ok) {
9394 /* Init nations we just loaded. */
9395 update_nations_with_startpos();
9396
9397 /* Needed by role_unit_precalcs(). */
9398 unit_type_action_cache_init();
9399
9400 /* Prepare caches we want to sanity check. */
9401 role_unit_precalcs();
9402 road_integrators_cache_init();
9403 actions_rs_pre_san_gen();
9404
9405 ok = autoadjust_ruleset_data()
9406 && sanity_check_ruleset_data(&compat_info);
9407 }
9408
9409 if (ok) {
9410 /* Only load settings for a sane ruleset */
9411 ok = settings_ruleset(gamefile, "settings", act,
9412 compat_info.compat_mode
9413 && compat_info.version < RSFORMAT_CURRENT);
9414
9415 if (ok) {
9416 secfile_check_unused(gamefile);
9417 }
9418 }
9419
9420 nullcheck_secfile_destroy(techfile);
9421 nullcheck_secfile_destroy(stylefile);
9422 nullcheck_secfile_destroy(cityfile);
9423 nullcheck_secfile_destroy(govfile);
9424 nullcheck_secfile_destroy(terrfile);
9425 nullcheck_secfile_destroy(unitfile);
9426 nullcheck_secfile_destroy(buildfile);
9427 nullcheck_secfile_destroy(nationfile);
9428 nullcheck_secfile_destroy(effectfile);
9429 nullcheck_secfile_destroy(actionfile);
9430 nullcheck_secfile_destroy(gamefile);
9431
9432 if (extra_sections) {
9433 free(extra_sections);
9434 extra_sections = NULL;
9435 }
9436 if (base_sections) {
9437 free(base_sections);
9438 base_sections = NULL;
9439 }
9440 if (road_sections) {
9441 free(road_sections);
9442 road_sections = NULL;
9443 }
9444 if (resource_sections) {
9445 free(resource_sections);
9446 resource_sections = NULL;
9447 }
9448 if (terrain_sections) {
9449 free(terrain_sections);
9450 terrain_sections = NULL;
9451 }
9452
9453 if (ok) {
9454 rscompat_postprocess(&compat_info);
9455 }
9456
9457 if (ok) {
9458 char **buffer = buffer_script ? &script_buffer : NULL;
9459
9460 script_server_free();
9461
9462 script_server_init();
9463
9464 ok = (openload_script_file("script", rsdir, buffer, FALSE) == TRI_YES);
9465 }
9466
9467 if (ok) {
9468 enum fc_tristate pret;
9469 char **buffer = buffer_script ? &parser_buffer : NULL;
9470
9471 pret = openload_script_file("parser", rsdir, buffer, compat_info.compat_mode);
9472
9473 if (pret == TRI_MAYBE && buffer_script) {
9474 parser_buffer = fc_strdup(
9475 "-- This file is for lua-functionality for parsing luadata.txt\n-- of this ruleset.");
9476 }
9477
9478 ok = (pret != TRI_NO);
9479 }
9480
9481 if (ok && !buffer_script) {
9482 ok = (openload_script_file("default", rsdir, NULL, FALSE) == TRI_YES);
9483 }
9484
9485 if (ok && act) {
9486 /* Populate remaining caches. */
9487 techs_precalc_data();
9488 improvement_feature_cache_init();
9489 unit_class_iterate(pclass) {
9490 set_unit_class_caches(pclass);
9491 } unit_class_iterate_end;
9492 unit_type_iterate(ptype) {
9493 ptype->unknown_move_cost = utype_unknown_move_cost(ptype);
9494 set_unit_type_caches(ptype);
9495 } unit_type_iterate_end;
9496 city_production_caravan_shields_init();
9497
9498 /* Build advisors unit class cache corresponding to loaded rulesets */
9499 adv_units_ruleset_init();
9500 CALL_FUNC_EACH_AI(units_ruleset_init);
9501
9502 /* We may need to adjust the number of AI players
9503 * if the number of available nations changed. */
9504 (void) aifill(game.info.aifill);
9505 }
9506
9507 return ok;
9508}
9509
9510/**********************************************************************/
9513 bool reload_rulesets_settings(void)
9514{
9515 struct section_file *file;
9516 bool ok = TRUE;
9517
9518 file = openload_ruleset_file("game", game.server.rulesetdir);
9519 if (file == NULL) {
9520 ruleset_error(NULL, LOG_ERROR,
9521 "Could not load game.ruleset:\n%s",
9522 secfile_error());
9523 ok = FALSE;
9524 }
9525 if (ok) {
9526 settings_ruleset(file, "settings", TRUE, FALSE);
9527 secfile_destroy(file);
9528 }
9529
9530 return ok;
9531}
9532
9533/**********************************************************************/
9536 void send_rulesets(struct conn_list *dest)
9537{
9538 conn_list_compression_freeze(dest);
9539
9540 /* ruleset_control also indicates to client that ruleset sending starts. */
9541 send_ruleset_control(dest);
9542
9543 /* Currently containing control-kind of data of nation sets and groups,
9544 * this too must be sent before any requirement vector may depend on
9545 * that data. */
9546 send_ruleset_nations(dest);
9547
9548 send_ruleset_game(dest);
9549 send_ruleset_disasters(dest);
9550 send_ruleset_achievements(dest);
9551 send_ruleset_counters(dest);
9552 send_ruleset_trade_routes(dest);
9553 send_ruleset_team_names(dest);
9554 send_ruleset_actions(dest);
9555 send_ruleset_action_enablers(dest);
9556 send_ruleset_action_auto_performers(dest);
9557 send_ruleset_tech_classes(dest);
9558 send_ruleset_techs(dest);
9559 send_ruleset_governments(dest);
9560 send_ruleset_unit_classes(dest);
9561 send_ruleset_units(dest);
9562 send_ruleset_specialists(dest);
9563 send_ruleset_extras(dest);
9564 send_ruleset_bases(dest);
9565 send_ruleset_roads(dest);
9566 send_ruleset_resources(dest);
9567 send_ruleset_terrain(dest);
9568 send_ruleset_goods(dest);
9569 send_ruleset_buildings(dest);
9570 send_ruleset_styles(dest);
9571 send_ruleset_clauses(dest);
9572 send_ruleset_cities(dest);
9573 send_ruleset_multipliers(dest);
9574 send_ruleset_musics(dest);
9575 send_ruleset_cache(dest);
9576
9577 /* Indicate client that all rulesets have now been sent. */
9578 lsend_packet_rulesets_ready(dest);
9579
9580 /* changed game settings will be send in
9581 * connecthand.c:establish_new_connection() */
9582
9583 conn_list_compression_thaw(dest);
9584}
achievement_index
int achievement_index(const struct achievement *pach)
Definition achievements.c:86
achievement_number
int achievement_number(const struct achievement *pach)
Definition achievements.c:76
achievements.h
achievements_iterate_end
#define achievements_iterate_end
Definition achievements.h:70
achievements_iterate
#define achievements_iterate(_ach_)
Definition achievements.h:64
action_auto_perf_slot_number
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:5658
actions_rs_pre_san_gen
void actions_rs_pre_san_gen(void)
Definition actions.c:869
action_min_range_ruleset_var_name
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:6392
action_blocked_by_ruleset_var_name
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7089
action_is_in_use
bool action_is_in_use(struct action *paction)
Definition actions.c:5612
action_post_success_forced_ruleset_var_name
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7279
action_by_rule_name
struct action * action_by_rule_name(const char *name)
Definition actions.c:1044
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1181
action_actor_consuming_always_ruleset_var_name
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:6919
action_max_range_ruleset_var_name
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:6567
action_target_kind_ruleset_var_name
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:6750
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:1486
action_ui_name_default
const char * action_ui_name_default(int act)
Definition actions.c:6036
action_enabler_new
struct action_enabler * action_enabler_new(void)
Definition actions.c:1440
action_enabler_possible_actor
bool action_enabler_possible_actor(const struct action_enabler *ae)
Definition actions.c:5555
action_id_is_internal
bool action_id_is_internal(action_id act)
Definition actions.c:5650
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1519
action_ui_name_ruleset_var_name
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:5743
actions.h
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:236
action_auto_perf_iterate_end
#define action_auto_perf_iterate_end
Definition actions.h:341
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:274
ACTION_AUTO_MOVED_ADJ
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:366
action_id_get_sub_target_kind
#define action_id_get_sub_target_kind(act_id)
Definition actions.h:411
ACTION_AUTO_UPKEEP_GOLD
#define ACTION_AUTO_UPKEEP_GOLD
Definition actions.h:364
enabler_get_action_id
#define enabler_get_action_id(_enabler_)
Definition actions.h:178
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:390
NUM_ACTIONS
#define NUM_ACTIONS
Definition actions.h:59
ACTION_AUTO_ESCAPE_STACK
#define ACTION_AUTO_ESCAPE_STACK
Definition actions.h:372
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:175
ACTION_AUTO_ESCAPE_CITY
#define ACTION_AUTO_ESCAPE_CITY
Definition actions.h:371
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:185
ACTION_DISTANCE_UNLIMITED
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:101
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:240
ACTION_AUTO_POST_WIPE_UNITS
#define ACTION_AUTO_POST_WIPE_UNITS
Definition actions.h:373
ACTION_AUTO_UPKEEP_SHIELD
#define ACTION_AUTO_UPKEEP_SHIELD
Definition actions.h:365
ACTION_AUTO_POST_BRIBE
#define ACTION_AUTO_POST_BRIBE
Definition actions.h:367
action_iterate_end
#define action_iterate_end
Definition actions.h:209
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:268
ACTION_AUTO_POST_ATTACK2
#define ACTION_AUTO_POST_ATTACK2
Definition actions.h:369
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:183
action_id
#define action_id(_act_)
Definition actions.h:416
action_iterate
#define action_iterate(_act_)
Definition actions.h:205
action_auto_perf_iterate
#define action_auto_perf_iterate(_act_perf_)
Definition actions.h:329
ACTION_AUTO_UPKEEP_FOOD
#define ACTION_AUTO_UPKEEP_FOOD
Definition actions.h:363
ACTION_AUTO_POST_ATTACK
#define ACTION_AUTO_POST_ATTACK
Definition actions.h:368
ACTION_AUTO_POST_COLLECT_RANSOM
#define ACTION_AUTO_POST_COLLECT_RANSOM
Definition actions.h:370
ACTION_NONE
#define ACTION_NONE
Definition actions.h:55
actres_min_range_default
int actres_min_range_default(enum action_result result)
Definition actres.c:376
actres_max_range_default
int actres_max_range_default(enum action_result result)
Definition actres.c:465
actres_target_kind_default
enum action_target_kind actres_target_kind_default(enum action_result result)
Definition actres.c:766
adv_units_ruleset_init
void adv_units_ruleset_init(void)
Definition advruleset.c:33
advruleset.h
ai.h
CALL_FUNC_EACH_AI
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:387
str
#define str
Definition astring.c:76
n
#define n
Definition astring.c:77
base_number
Base_type_id base_number(const struct base_type *pbase)
Definition base.c:92
base_type_init
void base_type_init(struct extra_type *pextra, int idx)
Definition base.c:117
territory_claiming_base
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
base.h
bitvector.h
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
capability.h
city_styles_alloc
void city_styles_alloc(int num)
Definition city.c:3384
city_production_caravan_shields_init
void city_production_caravan_shields_init(void)
Definition city.c:1770
city_style_rule_name
const char * city_style_rule_name(const int style)
Definition city.c:1757
get_output_identifier
const char * get_output_identifier(Output_type_id output)
Definition city.c:618
city_styles
static const struct city struct citystyle * city_styles
Definition city.c:83
city.h
output_type_iterate
#define output_type_iterate(output)
Definition city.h:833
output_type_iterate_end
#define output_type_iterate_end
Definition city.h:839
citytools.h
list
static struct fc_sockaddr_list * list
Definition clinet.c:102
incite_cost
char * incite_cost
Definition comments.c:74
MAX_LEN_CONTENT
#define MAX_LEN_CONTENT
Definition conn_types.h:32
MAX_LEN_MSG
#define MAX_LEN_MSG
Definition conn_types.h:37
conn_list_compression_thaw
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Definition connection.c:732
conn_list_compression_freeze
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Definition connection.c:720
counter_by_id
struct counter * counter_by_id(int id)
Definition counters.c:82
attach_city_counter
void attach_city_counter(struct counter *counter)
Definition counters.c:94
counters.h
city_counters_iterate_end
#define city_counters_iterate_end
Definition counters.h:64
city_counters_iterate
#define city_counters_iterate(pcount)
Definition counters.h:57
deprecations.h
clause_info_get
struct clause_info * clause_info_get(enum clause_type type)
Definition diptreaty.c:288
disaster_rule_name
const char * disaster_rule_name(struct disaster_type *pdis)
Definition disaster.c:105
disaster_number
Disaster_type_id disaster_number(const struct disaster_type *pdis)
Definition disaster.c:56
disaster_index
Disaster_type_id disaster_index(const struct disaster_type *pdis)
Definition disaster.c:69
disaster_type_iterate
#define disaster_type_iterate(_p)
Definition disaster.h:82
disaster_type_iterate_end
#define disaster_type_iterate_end
Definition disaster.h:88
id
int int id
Definition editgui_g.h:28
reqs
struct @21::@22 reqs
send_ruleset_cache
void send_ruleset_cache(struct conn_list *dest)
Definition effects.c:610
effect_new
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:186
user_effect_ai_valued_set
void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
Definition effects.c:1348
get_effects
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:143
user_effect_ai_valued_as
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1359
effect_req_append
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:266
is_user_effect
bool is_user_effect(enum effect_type eff)
Definition effects.c:1339
effects.h
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:81
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
extra_type_by_rule_name
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:212
extra_flag_helptxt
const char * extra_flag_helptxt(enum extra_flag_id id)
Definition extras.c:974
set_user_extra_flag_name
void set_user_extra_flag_name(enum extra_flag_id id, const char *name, const char *helptxt)
Definition extras.c:933
is_extra_caused_by_worker_action
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1032
extra_type_list_of_zoccers
struct extra_type_list * extra_type_list_of_zoccers(void)
Definition extras.c:267
extra_number
int extra_number(const struct extra_type *pextra)
Definition extras.c:161
extra_has_flag
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:861
extra_type_list_by_cause
struct extra_type_list * extra_type_list_by_cause(enum extra_cause cause)
Definition extras.c:249
extra_to_caused_by_list
void extra_to_caused_by_list(struct extra_type *pextra, enum extra_cause cause)
Definition extras.c:312
extra_by_number
struct extra_type * extra_by_number(int id)
Definition extras.c:183
extra_type_list_of_terr_claimers
struct extra_type_list * extra_type_list_of_terr_claimers(void)
Definition extras.c:275
extra_rule_name
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
is_extra_removed_by
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:353
extra_type_list_of_unit_hiders
struct extra_type_list * extra_type_list_of_unit_hiders(void)
Definition extras.c:259
extras.h
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_to_removed_by_list
static void extra_to_removed_by_list(struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.h:214
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:203
extra_index
#define extra_index(_e_)
Definition extras.h:183
extra_base_get
#define extra_base_get(_e_)
Definition extras.h:190
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:191
extra_type_by_cause_iterate_end
#define extra_type_by_cause_iterate_end
Definition extras.h:339
MAX_NUM_USER_EXTRA_FLAGS
#define MAX_NUM_USER_EXTRA_FLAGS
Definition extras.h:83
extra_type_by_cause_iterate
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
fc_types.h
MAX_NUM_USER_BUILDING_FLAGS
#define MAX_NUM_USER_BUILDING_FLAGS
Definition fc_types.h:685
MAX_DISASTER_TYPES
#define MAX_DISASTER_TYPES
Definition fc_types.h:52
MAX_VET_LEVELS
#define MAX_VET_LEVELS
Definition fc_types.h:49
ROCO_RAILROAD
@ ROCO_RAILROAD
Definition fc_types.h:1263
ROCO_NONE
@ ROCO_NONE
Definition fc_types.h:1263
ROCO_RIVER
@ ROCO_RIVER
Definition fc_types.h:1263
ROCO_ROAD
@ ROCO_ROAD
Definition fc_types.h:1263
MAX_GRANARY_INIS
#define MAX_GRANARY_INIS
Definition fc_types.h:72
MAX_NUM_NATIONS
#define MAX_NUM_NATIONS
Definition fc_types.h:60
MAX_NUM_BUILDING_LIST
#define MAX_NUM_BUILDING_LIST
Definition fc_types.h:46
MAX_NUM_REQS
#define MAX_NUM_REQS
Definition fc_types.h:414
MAX_GOODS_TYPES
#define MAX_GOODS_TYPES
Definition fc_types.h:51
EC_NATURAL_DEFENSIVE
#define EC_NATURAL_DEFENSIVE
Definition fc_types.h:1126
EC_SPECIAL
#define EC_SPECIAL
Definition fc_types.h:1124
action_id
int action_id
Definition fc_types.h:393
SP_MAX
#define SP_MAX
Definition fc_types.h:413
EC_NONE
#define EC_NONE
Definition fc_types.h:1123
EC_NOT_AGGRESSIVE
#define EC_NOT_AGGRESSIVE
Definition fc_types.h:1127
EC_DEFENSIVE
#define EC_DEFENSIVE
Definition fc_types.h:1125
MAX_CALENDAR_FRAGMENTS
#define MAX_CALENDAR_FRAGMENTS
Definition fc_types.h:62
MAX_NUM_TECH_CLASSES
#define MAX_NUM_TECH_CLASSES
Definition fc_types.h:63
MAX_NUM_LEADERS
#define MAX_NUM_LEADERS
Definition fc_types.h:56
MAX_NUM_MULTIPLIERS
#define MAX_NUM_MULTIPLIERS
Definition fc_types.h:55
MAX_NUM_UNIT_LIST
#define MAX_NUM_UNIT_LIST
Definition fc_types.h:45
MAX_EXTRA_TYPES
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
CTGT_CITY
@ CTGT_CITY
Definition fc_types.h:126
MAX_ACHIEVEMENT_TYPES
#define MAX_ACHIEVEMENT_TYPES
Definition fc_types.h:53
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
MAX_NUM_TECH_LIST
#define MAX_NUM_TECH_LIST
Definition fc_types.h:44
MAX_LEN_CITYNAME
#define MAX_LEN_CITYNAME
Definition fc_types.h:67
MAX_COUNTERS
#define MAX_COUNTERS
Definition fc_types.h:106
UCL_LAST
#define UCL_LAST
Definition fc_types.h:421
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
_
#define _(String)
Definition fcintl.h:67
Qn_
#define Qn_(String)
Definition fcintl.h:89
N_
#define N_(String)
Definition fcintl.h:69
ftc_warning
const struct ft_color ftc_warning
Definition featured_text.c:75
featured_text.h
game
struct civ_game game
Definition game.c:62
game_ruleset_init
void game_ruleset_init(void)
Definition game.c:518
game_ruleset_free
void game_ruleset_free(void)
Definition game.c:567
wld
struct world wld
Definition game.c:63
game.h
RS_DEFAULT_RANSOM_GOLD
#define RS_DEFAULT_RANSOM_GOLD
Definition game.h:865
RS_DEFAULT_GRANARY_FOOD_INI
#define RS_DEFAULT_GRANARY_FOOD_INI
Definition game.h:814
RS_DEFAULT_CIVIL_WAR_UNHAPPY
#define RS_DEFAULT_CIVIL_WAR_UNHAPPY
Definition game.h:851
RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:857
RS_MIN_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_MIN_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:795
RS_MAX_TECH_UPKEEP_DIVIDER
#define RS_MAX_TECH_UPKEEP_DIVIDER
Definition game.h:877
RS_MIN_ILLNESS_POLLUTION_PCT
#define RS_MIN_ILLNESS_POLLUTION_PCT
Definition game.h:781
RS_DEFAULT_NUKE_POP_LOSS_PCT
#define RS_DEFAULT_NUKE_POP_LOSS_PCT
Definition game.h:854
RS_MAX_BORDER_RADIUS_SQ_CITY
#define RS_MAX_BORDER_RADIUS_SQ_CITY
Definition game.h:788
RS_DEFAULT_BASE_POLLUTION
#define RS_DEFAULT_BASE_POLLUTION
Definition game.h:837
RS_MIN_ILLNESS_TRADE_INFECTION_PCT
#define RS_MIN_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:777
RS_MAX_ILLNESS_BASE_FACTOR
#define RS_MAX_ILLNESS_BASE_FACTOR
Definition game.h:770
RS_DEFAULT_INCITE_TOTAL_FCT
#define RS_DEFAULT_INCITE_TOTAL_FCT
Definition game.h:810
RS_DEFAULT_ILLNESS_BASE_FACTOR
#define RS_DEFAULT_ILLNESS_BASE_FACTOR
Definition game.h:768
RS_DEFAULT_NEG_YEAR_LABEL
#define RS_DEFAULT_NEG_YEAR_LABEL
Definition game.h:764
RS_MIN_NUKE_POP_LOSS_PCT
#define RS_MIN_NUKE_POP_LOSS_PCT
Definition game.h:855
RS_MIN_INCITE_IMPROVEMENT_FCT
#define RS_MIN_INCITE_IMPROVEMENT_FCT
Definition game.h:803
RS_MIN_FOOD_COST
#define RS_MIN_FOOD_COST
Definition game.h:847
RS_MIN_BASE_BRIBE_COST
#define RS_MIN_BASE_BRIBE_COST
Definition game.h:862
RS_MAX_NUKE_POP_LOSS_PCT
#define RS_MAX_NUKE_POP_LOSS_PCT
Definition game.h:856
RS_DEFAULT_INCITE_IMPROVEMENT_FCT
#define RS_DEFAULT_INCITE_IMPROVEMENT_FCT
Definition game.h:802
RS_MAX_INCITE_IMPROVEMENT_FCT
#define RS_MAX_INCITE_IMPROVEMENT_FCT
Definition game.h:804
RS_MIN_RANSOM_GOLD
#define RS_MIN_RANSOM_GOLD
Definition game.h:866
RS_ACTION_NO_MAX_DISTANCE
#define RS_ACTION_NO_MAX_DISTANCE
Definition game.h:889
RS_DEFAULT_BASE_BRIBE_COST
#define RS_DEFAULT_BASE_BRIBE_COST
Definition game.h:861
RS_MAX_INCITE_BASE_COST
#define RS_MAX_INCITE_BASE_COST
Definition game.h:800
RS_DEFAULT_TECH_UPKEEP_DIVIDER
#define RS_DEFAULT_TECH_UPKEEP_DIVIDER
Definition game.h:875
RS_DEFAULT_HAPPY_COST
#define RS_DEFAULT_HAPPY_COST
Definition game.h:842
RS_MIN_UPGRADE_VETERAN_LOSS
#define RS_MIN_UPGRADE_VETERAN_LOSS
Definition game.h:872
RS_MIN_ILLNESS_MIN_SIZE
#define RS_MIN_ILLNESS_MIN_SIZE
Definition game.h:773
RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
#define RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
Definition game.h:879
RS_DEFAULT_GRANARY_FOOD_INC
#define RS_DEFAULT_GRANARY_FOOD_INC
Definition game.h:816
RS_DEFAULT_ILLNESS_ON
#define RS_DEFAULT_ILLNESS_ON
Definition game.h:766
RS_MAX_FOOD_COST
#define RS_MAX_FOOD_COST
Definition game.h:848
RS_MAX_HAPPY_COST
#define RS_MAX_HAPPY_COST
Definition game.h:844
GAME_DEFAULT_CELEBRATESIZE
#define GAME_DEFAULT_CELEBRATESIZE
Definition game.h:499
RS_MIN_ILLNESS_BASE_FACTOR
#define RS_MIN_ILLNESS_BASE_FACTOR
Definition game.h:769
RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
#define RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
Definition game.h:880
RS_MIN_TECH_UPKEEP_DIVIDER
#define RS_MIN_TECH_UPKEEP_DIVIDER
Definition game.h:876
RS_MAX_RANSOM_GOLD
#define RS_MAX_RANSOM_GOLD
Definition game.h:867
RS_MIN_HAPPY_COST
#define RS_MIN_HAPPY_COST
Definition game.h:843
RS_MIN_BORDER_RADIUS_SQ_CITY
#define RS_MIN_BORDER_RADIUS_SQ_CITY
Definition game.h:787
GAME_DEFAULT_RULESETDIR
#define GAME_DEFAULT_RULESETDIR
Definition game.h:673
RS_DEFAULT_CIVIL_WAR_CELEB
#define RS_DEFAULT_CIVIL_WAR_CELEB
Definition game.h:850
RS_MIN_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_MIN_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:858
RS_MAX_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_MAX_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:796
RS_DEFAULT_UPGRADE_VETERAN_LOSS
#define RS_DEFAULT_UPGRADE_VETERAN_LOSS
Definition game.h:871
RS_MAX_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_MAX_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:859
RS_MAX_INCITE_UNIT_FCT
#define RS_MAX_INCITE_UNIT_FCT
Definition game.h:808
RS_MIN_VIS_RADIUS_SQ
#define RS_MIN_VIS_RADIUS_SQ
Definition game.h:834
RS_DEFAULT_CALENDAR_SKIP_0
#define RS_DEFAULT_CALENDAR_SKIP_0
Definition game.h:784
RS_MAX_ILLNESS_MIN_SIZE
#define RS_MAX_ILLNESS_MIN_SIZE
Definition game.h:774
RS_DEFAULT_CITY_RADIUS_SQ
#define RS_DEFAULT_CITY_RADIUS_SQ
Definition game.h:829
GAME_DEFAULT_START_YEAR
#define GAME_DEFAULT_START_YEAR
Definition game.h:740
RS_MAX_BORDER_SIZE_EFFECT
#define RS_MAX_BORDER_SIZE_EFFECT
Definition game.h:792
RS_DEFAULT_BORDER_SIZE_EFFECT
#define RS_DEFAULT_BORDER_SIZE_EFFECT
Definition game.h:790
RS_MAX_BASE_BRIBE_COST
#define RS_MAX_BASE_BRIBE_COST
Definition game.h:863
RS_MIN_INCITE_BASE_COST
#define RS_MIN_INCITE_BASE_COST
Definition game.h:799
RS_DEFAULT_PILLAGE_SELECT
#define RS_DEFAULT_PILLAGE_SELECT
Definition game.h:869
RS_MIN_CITY_RADIUS_SQ
#define RS_MIN_CITY_RADIUS_SQ
Definition game.h:830
RS_MIN_CITY_CENTER_OUTPUT
#define RS_MIN_CITY_CENTER_OUTPUT
Definition game.h:821
RS_MAX_GRANARY_FOOD_INC
#define RS_MAX_GRANARY_FOOD_INC
Definition game.h:818
RS_MAX_CITY_CENTER_OUTPUT
#define RS_MAX_CITY_CENTER_OUTPUT
Definition game.h:822
RS_MAX_CITY_RADIUS_SQ
#define RS_MAX_CITY_RADIUS_SQ
Definition game.h:831
RS_DEFAULT_POS_YEAR_LABEL
#define RS_DEFAULT_POS_YEAR_LABEL
Definition game.h:762
RS_MIN_INCITE_UNIT_FCT
#define RS_MIN_INCITE_UNIT_FCT
Definition game.h:807
RS_MIN_BORDER_SIZE_EFFECT
#define RS_MIN_BORDER_SIZE_EFFECT
Definition game.h:791
RS_DEFAULT_VIS_RADIUS_SQ
#define RS_DEFAULT_VIS_RADIUS_SQ
Definition game.h:833
RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:794
RS_DEFAULT_TIRED_ATTACK
#define RS_DEFAULT_TIRED_ATTACK
Definition game.h:853
RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
#define RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
Definition game.h:881
RS_MAX_ILLNESS_POLLUTION_PCT
#define RS_MAX_ILLNESS_POLLUTION_PCT
Definition game.h:782
RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
#define RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:776
RS_DEFAULT_FOOD_COST
#define RS_DEFAULT_FOOD_COST
Definition game.h:846
RS_DEFAULT_INCITE_UNIT_FCT
#define RS_DEFAULT_INCITE_UNIT_FCT
Definition game.h:806
RS_MAX_INCITE_TOTAL_FCT
#define RS_MAX_INCITE_TOTAL_FCT
Definition game.h:812
RS_DEFAULT_INCITE_BASE_COST
#define RS_DEFAULT_INCITE_BASE_COST
Definition game.h:798
GAME_DEFAULT_ANGRYCITIZEN
#define GAME_DEFAULT_ANGRYCITIZEN
Definition game.h:390
RS_DEFAULT_CITY_CENTER_OUTPUT
#define RS_DEFAULT_CITY_CENTER_OUTPUT
Definition game.h:820
RS_MIN_INCITE_TOTAL_FCT
#define RS_MIN_INCITE_TOTAL_FCT
Definition game.h:811
RS_DEFAULT_ILLNESS_POLLUTION_PCT
#define RS_DEFAULT_ILLNESS_POLLUTION_PCT
Definition game.h:780
RS_MAX_UPGRADE_VETERAN_LOSS
#define RS_MAX_UPGRADE_VETERAN_LOSS
Definition game.h:873
set_ruleset_compat_mode
static void set_ruleset_compat_mode(bool active)
Definition game.h:354
RS_MAX_VIS_RADIUS_SQ
#define RS_MAX_VIS_RADIUS_SQ
Definition game.h:835
RS_MIN_GRANARY_FOOD_INC
#define RS_MIN_GRANARY_FOOD_INC
Definition game.h:817
RS_MAX_ILLNESS_TRADE_INFECTION_PCT
#define RS_MAX_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:778
RS_DEFAULT_ILLNESS_MIN_SIZE
#define RS_DEFAULT_ILLNESS_MIN_SIZE
Definition game.h:772
RS_DEFAULT_BORDER_RADIUS_SQ_CITY
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY
Definition game.h:786
ruler_title_nation
const struct nation_type * ruler_title_nation(const struct ruler_title *pruler_title)
Definition government.c:365
government_ruler_title_new
struct ruler_title * government_ruler_title_new(struct government *pgovern, const struct nation_type *pnation, const char *ruler_male_title, const char *ruler_female_title)
Definition government.c:325
ruler_title_female_untranslated_name
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:383
government_count
Government_type_id government_count(void)
Definition government.c:71
ruler_title_male_untranslated_name
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:374
governments_alloc
void governments_alloc(int num)
Definition government.c:528
government_number
Government_type_id government_number(const struct government *pgovern)
Definition government.c:91
government_ruler_titles
const struct ruler_title_hash * government_ruler_titles(const struct government *pgovern)
Definition government.c:314
government_index
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
government_rule_name
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
government_by_rule_name
struct government * government_by_rule_name(const char *name)
Definition government.c:55
government.h
governments_iterate
#define governments_iterate(NAME_pgov)
Definition government.h:120
G_LAST
#define G_LAST
Definition government.h:48
ruler_titles_iterate
#define ruler_titles_iterate(ARG_hash, NAME_rule_title)
Definition government.h:38
ruler_titles_iterate_end
#define ruler_titles_iterate_end
Definition government.h:41
governments_iterate_end
#define governments_iterate_end
Definition government.h:123
title
const char * title
Definition repodlgs.c:1314
type
GType type
Definition repodlgs.c:1313
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:184
improvement_rule_name
const char * improvement_rule_name(const struct impr_type *pimprove)
Definition improvement.c:252
improvement_feature_cache_init
void improvement_feature_cache_init(void)
Definition improvement.c:92
improvement_by_rule_name
struct impr_type * improvement_by_rule_name(const char *name)
Definition improvement.c:367
set_user_impr_flag_name
void set_user_impr_flag_name(enum impr_flag_id id, const char *name, const char *helptxt)
Definition improvement.c:1184
impr_flag_helptxt
const char * impr_flag_helptxt(enum impr_flag_id id)
Definition improvement.c:1225
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:205
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:199
B_LAST
#define B_LAST
Definition improvement.h:42
name
const char * name
Definition inputfile.c:127
vdo_log
void vdo_log(const char *file, const char *function, int line, bool print_from_where, enum log_level level, char *buf, int buflen, const char *message, va_list args)
Definition log.c:403
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
MAX_LEN_LOG_LINE
#define MAX_LEN_LOG_LINE
Definition log.h:26
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_do_output_for_level
#define log_do_output_for_level(level)
Definition log.h:89
log_debug
#define log_debug(message,...)
Definition log.h:115
log_normal
#define log_normal(message,...)
Definition log.h:107
log_level
log_level
Definition log.h:28
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
LOG_FATAL
@ LOG_FATAL
Definition log.h:29
log_error
#define log_error(message,...)
Definition log.h:103
terrain_control
struct terrain_misc terrain_control
Definition map.c:68
map.h
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
utype_unknown_move_cost
int utype_unknown_move_cost(const struct unit_type *utype)
Definition movement.c:104
init_move_fragments
void init_move_fragments(void)
Definition movement.c:928
movement.h
SINGLE_MOVE
#define SINGLE_MOVE
Definition movement.h:26
multiplier_rule_name
const char * multiplier_rule_name(const struct multiplier *pmul)
Definition multipliers.c:106
multiplier_number
Multiplier_type_id multiplier_number(const struct multiplier *pmul)
Definition multipliers.c:67
multiplier_by_rule_name
struct multiplier * multiplier_by_rule_name(const char *name)
Definition multipliers.c:115
multiplier_index
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Definition multipliers.c:80
multipliers.h
multipliers_iterate
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
multipliers_iterate_end
#define multipliers_iterate_end
Definition multipliers.h:67
name_translation.h
name_set
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
Definition name_translation.h:88
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
untranslated_name
static const char * untranslated_name(const struct name_translation *ptrans)
Definition name_translation.h:104
names_set
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
Definition name_translation.h:60
nation_group_set_match
void nation_group_set_match(struct nation_group *pgroup, int match)
Definition nation.c:1047
nation_group_untranslated_name
const char * nation_group_untranslated_name(const struct nation_group *pgroup)
Definition nation.c:1069
nation_group_by_rule_name
struct nation_group * nation_group_by_rule_name(const char *name)
Definition nation.c:1021
nation_rule_name
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
nation_count
Nation_type_id nation_count(void)
Definition nation.c:507
nation_number
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
nation_group_new
struct nation_group * nation_group_new(const char *name)
Definition nation.c:960
nation_leader_is_male
bool nation_leader_is_male(const struct nation_leader *pleader)
Definition nation.c:290
nation_set_new
struct nation_set * nation_set_new(const char *set_name, const char *set_rule_name, const char *set_description)
Definition nation.c:716
nation_by_number
struct nation_type * nation_by_number(const Nation_type_id nation)
Definition nation.c:475
nation_city_new
struct nation_city * nation_city_new(struct nation_type *pnation, const char *name)
Definition nation.c:342
nation_leaders
const struct nation_leader_list * nation_leaders(const struct nation_type *pnation)
Definition nation.c:230
nation_set_untranslated_name
const char * nation_set_untranslated_name(const struct nation_set *pset)
Definition nation.c:797
is_nation_playable
bool is_nation_playable(const struct nation_type *nation)
Definition nation.c:200
nation_set_number
int nation_set_number(const struct nation_set *pset)
Definition nation.c:708
nation_city_set_terrain_preference
void nation_city_set_terrain_preference(struct nation_city *pncity, const struct terrain *pterrain, enum nation_city_preference prefer)
Definition nation.c:390
nation_city_set_river_preference
void nation_city_set_river_preference(struct nation_city *pncity, enum nation_city_preference prefer)
Definition nation.c:402
nation_is_in_set
bool nation_is_in_set(const struct nation_type *pnation, const struct nation_set *pset)
Definition nation.c:837
nation_set_description
const char * nation_set_description(const struct nation_set *pset)
Definition nation.c:828
nation_set_count
int nation_set_count(void)
Definition nation.c:691
nation_set_by_number
struct nation_set * nation_set_by_number(int id)
Definition nation.c:762
nation_by_rule_name
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:121
nation_set_by_rule_name
struct nation_set * nation_set_by_rule_name(const char *name)
Definition nation.c:779
nation_index
Nation_type_id nation_index(const struct nation_type *pnation)
Definition nation.c:498
nation_leader_name
const char * nation_leader_name(const struct nation_leader *pleader)
Definition nation.c:281
nation_group_count
int nation_group_count(void)
Definition nation.c:935
nation_set_rule_name
const char * nation_set_rule_name(const struct nation_set *pset)
Definition nation.c:807
nation_leader_new
struct nation_leader * nation_leader_new(struct nation_type *pnation, const char *name, bool is_male)
Definition nation.c:239
nation_group_set_hidden
void nation_group_set_hidden(struct nation_group *pgroup, bool hidden)
Definition nation.c:1037
nations_alloc
void nations_alloc(int num)
Definition nation.c:622
nation_barbarian_type
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:211
nation_group_number
int nation_group_number(const struct nation_group *pgroup)
Definition nation.c:952
nation.h
nation_leader_list_iterate
#define nation_leader_list_iterate(leaderlist, pleader)
Definition nation.h:57
nation_sets_iterate_end
#define nation_sets_iterate_end
Definition nation.h:305
nation_set_list_iterate_end
#define nation_set_list_iterate_end
Definition nation.h:68
nation_group_list_iterate
#define nation_group_list_iterate(grouplist, pgroup)
Definition nation.h:75
nation_sets_iterate
#define nation_sets_iterate(NAME_pset)
Definition nation.h:301
nations_iterate_end
#define nations_iterate_end
Definition nation.h:336
nation_city_preference
nation_city_preference
Definition nation.h:39
NCP_DISLIKE
@ NCP_DISLIKE
Definition nation.h:40
NCP_LIKE
@ NCP_LIKE
Definition nation.h:42
nations_iterate
#define nations_iterate(NAME_pnation)
Definition nation.h:333
nation_leader_list_iterate_end
#define nation_leader_list_iterate_end
Definition nation.h:59
nation_group_list_iterate_end
#define nation_group_list_iterate_end
Definition nation.h:77
nation_set_list_iterate
#define nation_set_list_iterate(setlist, pset)
Definition nation.h:66
nation_groups_iterate
#define nation_groups_iterate(NAME_pgroup)
Definition nation.h:311
nation_groups_iterate_end
#define nation_groups_iterate_end
Definition nation.h:315
notify_conn
void notify_conn(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:239
notify.h
packets.h
web_lsend_packet
#define web_lsend_packet(packetname,...)
Definition packets.h:57
PACKET_STRVEC_INSERT
#define PACKET_STRVEC_INSERT(dest, src)
Definition packets.h:185
lsend_packet_ruleset_summary
void lsend_packet_ruleset_summary(struct conn_list *dest, const struct packet_ruleset_summary *packet)
Definition packets_gen.c:72877
lsend_packet_ruleset_building
void lsend_packet_ruleset_building(struct conn_list *dest, const struct packet_ruleset_building *packet)
Definition packets_gen.c:56548
lsend_packet_ruleset_unit_class_flag
void lsend_packet_ruleset_unit_class_flag(struct conn_list *dest, const struct packet_ruleset_unit_class_flag *packet)
Definition packets_gen.c:45491
lsend_packet_ruleset_achievement
void lsend_packet_ruleset_achievement(struct conn_list *dest, const struct packet_ruleset_achievement *packet)
Definition packets_gen.c:66377
lsend_packet_ruleset_nation_sets
void lsend_packet_ruleset_nation_sets(struct conn_list *dest, const struct packet_ruleset_nation_sets *packet)
Definition packets_gen.c:51646
lsend_packet_ruleset_multiplier
void lsend_packet_ruleset_multiplier(struct conn_list *dest, const struct packet_ruleset_multiplier *packet)
Definition packets_gen.c:70553
lsend_packet_ruleset_city
void lsend_packet_ruleset_city(struct conn_list *dest, const struct packet_ruleset_city *packet)
Definition packets_gen.c:55134
lsend_packet_ruleset_unit
void lsend_packet_ruleset_unit(struct conn_list *dest, const struct packet_ruleset_unit *packet)
Definition packets_gen.c:44613
lsend_packet_ruleset_clause
void lsend_packet_ruleset_clause(struct conn_list *dest, const struct packet_ruleset_clause *packet)
Definition packets_gen.c:71356
lsend_packet_ruleset_unit_flag
void lsend_packet_ruleset_unit_flag(struct conn_list *dest, const struct packet_ruleset_unit_flag *packet)
Definition packets_gen.c:45228
lsend_packet_ruleset_action
void lsend_packet_ruleset_action(struct conn_list *dest, const struct packet_ruleset_action *packet)
Definition packets_gen.c:67325
lsend_packet_ruleset_extra
void lsend_packet_ruleset_extra(struct conn_list *dest, const struct packet_ruleset_extra *packet)
Definition packets_gen.c:62943
lsend_packet_ruleset_nation_groups
void lsend_packet_ruleset_nation_groups(struct conn_list *dest, const struct packet_ruleset_nation_groups *packet)
Definition packets_gen.c:52109
lsend_packet_ruleset_terrain_control
void lsend_packet_ruleset_terrain_control(struct conn_list *dest, const struct packet_ruleset_terrain_control *packet)
Definition packets_gen.c:50997
lsend_packet_ruleset_government_ruler_title
void lsend_packet_ruleset_government_ruler_title(struct conn_list *dest, const struct packet_ruleset_government_ruler_title *packet)
Definition packets_gen.c:48045
lsend_packet_ruleset_music
void lsend_packet_ruleset_music(struct conn_list *dest, const struct packet_ruleset_music *packet)
Definition packets_gen.c:69543
lsend_packet_ruleset_control
void lsend_packet_ruleset_control(struct conn_list *dest, const struct packet_ruleset_control *packet)
Definition packets_gen.c:72692
lsend_packet_team_name_info
void lsend_packet_team_name_info(struct conn_list *dest, const struct packet_team_name_info *packet)
Definition packets_gen.c:11266
lsend_packet_ruleset_terrain_flag
void lsend_packet_ruleset_terrain_flag(struct conn_list *dest, const struct packet_ruleset_terrain_flag *packet)
Definition packets_gen.c:59688
lsend_packet_ruleset_unit_class
void lsend_packet_ruleset_unit_class(struct conn_list *dest, const struct packet_ruleset_unit_class *packet)
Definition packets_gen.c:60339
lsend_packet_ruleset_disaster
void lsend_packet_ruleset_disaster(struct conn_list *dest, const struct packet_ruleset_disaster *packet)
Definition packets_gen.c:66006
lsend_packet_ruleset_description_part
void lsend_packet_ruleset_description_part(struct conn_list *dest, const struct packet_ruleset_description_part *packet)
Definition packets_gen.c:73062
lsend_packet_ruleset_government
void lsend_packet_ruleset_government(struct conn_list *dest, const struct packet_ruleset_government *packet)
Definition packets_gen.c:50421
lsend_packet_ruleset_unit_bonus
void lsend_packet_ruleset_unit_bonus(struct conn_list *dest, const struct packet_ruleset_unit_bonus *packet)
Definition packets_gen.c:44965
lsend_packet_ruleset_base
void lsend_packet_ruleset_base(struct conn_list *dest, const struct packet_ruleset_base *packet)
Definition packets_gen.c:63596
lsend_packet_ruleset_resource
void lsend_packet_ruleset_resource(struct conn_list *dest, const struct packet_ruleset_resource *packet)
Definition packets_gen.c:78518
lsend_packet_ruleset_specialist
void lsend_packet_ruleset_specialist(struct conn_list *dest, const struct packet_ruleset_specialist *packet)
Definition packets_gen.c:47723
lsend_packet_ruleset_tech
void lsend_packet_ruleset_tech(struct conn_list *dest, const struct packet_ruleset_tech *packet)
Definition packets_gen.c:49071
lsend_packet_ruleset_trade
void lsend_packet_ruleset_trade(struct conn_list *dest, const struct packet_ruleset_trade *packet)
Definition packets_gen.c:66699
lsend_packet_ruleset_action_enabler
void lsend_packet_ruleset_action_enabler(struct conn_list *dest, const struct packet_ruleset_action_enabler *packet)
Definition packets_gen.c:67876
lsend_packet_ruleset_style
void lsend_packet_ruleset_style(struct conn_list *dest, const struct packet_ruleset_style *packet)
Definition packets_gen.c:54576
lsend_packet_ruleset_tech_flag
void lsend_packet_ruleset_tech_flag(struct conn_list *dest, const struct packet_ruleset_tech_flag *packet)
Definition packets_gen.c:49636
lsend_packet_ruleset_tech_class
void lsend_packet_ruleset_tech_class(struct conn_list *dest, const struct packet_ruleset_tech_class *packet)
Definition packets_gen.c:49373
lsend_packet_ruleset_goods
void lsend_packet_ruleset_goods(struct conn_list *dest, const struct packet_ruleset_goods *packet)
Definition packets_gen.c:65487
lsend_packet_ruleset_game
void lsend_packet_ruleset_game(struct conn_list *dest, const struct packet_ruleset_game *packet)
Definition packets_gen.c:46893
lsend_packet_ruleset_nation
void lsend_packet_ruleset_nation(struct conn_list *dest, const struct packet_ruleset_nation *packet)
Definition packets_gen.c:53969
lsend_packet_ruleset_counter
void lsend_packet_ruleset_counter(struct conn_list *dest, const struct packet_ruleset_counter *packet)
Definition packets_gen.c:69102
lsend_packet_rulesets_ready
void lsend_packet_rulesets_ready(struct conn_list *dest)
Definition packets_gen.c:51044
lsend_packet_ruleset_impr_flag
void lsend_packet_ruleset_impr_flag(struct conn_list *dest, const struct packet_ruleset_impr_flag *packet)
Definition packets_gen.c:56811
lsend_packet_ruleset_extra_flag
void lsend_packet_ruleset_extra_flag(struct conn_list *dest, const struct packet_ruleset_extra_flag *packet)
Definition packets_gen.c:63206
lsend_packet_ruleset_road
void lsend_packet_ruleset_road(struct conn_list *dest, const struct packet_ruleset_road *packet)
Definition packets_gen.c:64622
lsend_packet_ruleset_terrain
void lsend_packet_ruleset_terrain(struct conn_list *dest, const struct packet_ruleset_terrain *packet)
Definition packets_gen.c:59425
lsend_packet_ruleset_action_auto
void lsend_packet_ruleset_action_auto(struct conn_list *dest, const struct packet_ruleset_action_auto *packet)
Definition packets_gen.c:68476
cities
struct city_list * cities
Definition packhand.c:119
len
int len
Definition packhand.c:127
player.h
send_nation_availability
void send_nation_availability(struct conn_list *dest, bool nationset_change)
Definition plrhand.c:2642
playercolor_free
void playercolor_free(void)
Definition plrhand.c:3347
playercolor_init
void playercolor_init(void)
Definition plrhand.c:3337
playercolor_count
int playercolor_count(void)
Definition plrhand.c:3386
playercolor_add
void playercolor_add(struct rgbcolor *prgbcolor)
Definition plrhand.c:3366
count_playable_nations
void count_playable_nations(void)
Definition plrhand.c:2599
plrhand.h
secfile_load
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
Definition registry.c:50
registry.h
secfile_error
const char * secfile_error(void)
Definition section_file.c:36
section_name
const char * section_name(const struct section *psection)
Definition section_file.c:65
secfile_destroy
void secfile_destroy(struct section_file *secfile)
Definition section_file.c:95
entry_bool_get
bool entry_bool_get(const struct entry *pentry, bool *value)
Definition registry_ini.c:3454
secfile_check_unused
void secfile_check_unused(const struct section_file *secfile)
Definition registry_ini.c:907
secfile_lookup_int
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Definition registry_ini.c:1975
secfile_sections_by_name_prefix
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
Definition registry_ini.c:2871
secfile_lookup_str_vec
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Definition registry_ini.c:2239
entry_name
const char * entry_name(const struct entry *pentry)
Definition registry_ini.c:3357
secfile_entry_lookup
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:1857
entry_str_get
bool entry_str_get(const struct entry *pentry, const char **value)
Definition registry_ini.c:3553
secfile_lookup_str
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:2175
secfile_lookup_int_vec
int * secfile_lookup_int_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Definition registry_ini.c:2077
secfile_lookup_bool_default
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Definition registry_ini.c:1900
secfile_lookup_int_default
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Definition registry_ini.c:2000
entry_int_get
bool entry_int_get(const struct entry *pentry, int *value)
Definition registry_ini.c:3525
secfile_name
const char * secfile_name(const struct section_file *secfile)
Definition registry_ini.c:943
secfile_entry_by_path
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
Definition registry_ini.c:1784
secfile_lookup_str_default
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Definition registry_ini.c:2205
secfile_lookup_int_def_min_max
int secfile_lookup_int_def_min_max(const struct section_file *secfile, int defval, int minval, int maxval, const char *path,...)
Definition registry_ini.c:2030
entry_type_get
enum entry_type entry_type_get(const struct entry *pentry)
Definition registry_ini.c:3339
ENTRY_FILEREFERENCE
@ ENTRY_FILEREFERENCE
Definition registry_ini.h:636
ENTRY_LONG_COMMENT
@ ENTRY_LONG_COMMENT
Definition registry_ini.h:637
ENTRY_INT
@ ENTRY_INT
Definition registry_ini.h:633
ENTRY_FLOAT
@ ENTRY_FLOAT
Definition registry_ini.h:634
ENTRY_STR
@ ENTRY_STR
Definition registry_ini.h:635
ENTRY_ILLEGAL
@ ENTRY_ILLEGAL
Definition registry_ini.h:638
ENTRY_BOOL
@ ENTRY_BOOL
Definition registry_ini.h:632
secfile_lookup_enum_vec
#define secfile_lookup_enum_vec(secfile, dim, specenum_type, path,...)
Definition registry_ini.h:549
secfile_lookup_enum_default
#define secfile_lookup_enum_default(secfile, defval, specenum_type, path,...)
Definition registry_ini.h:516
section_list_iterate
#define section_list_iterate(seclist, psection)
Definition registry_ini.h:45
section_list_iterate_end
#define section_list_iterate_end
Definition registry_ini.h:47
req_vec_vector_number
req_vec_num_in_item req_vec_vector_number(const void *parent_item, const struct requirement_vector *vec)
Definition requirements.c:6178
req_vec_by_number
struct requirement_vector * req_vec_by_number(const void *parent_item, req_vec_num_in_item number)
Definition requirements.c:6197
req_vec_change_apply
bool req_vec_change_apply(const struct req_vec_change *modification, requirement_vector_by_number getter, const void *parent_item)
Definition requirements.c:6286
are_requirements_equal
bool are_requirements_equal(const struct requirement *req1, const struct requirement *req2)
Definition requirements.c:1469
req_from_str
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
Definition requirements.c:1048
req_from_values
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Definition requirements.c:1422
req_vec_problem_free
void req_vec_problem_free(struct req_vec_problem *issue)
Definition requirements.c:6383
req_vec_get_first_missing_univ
struct req_vec_problem * req_vec_get_first_missing_univ(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:6489
req_vec_get_first_redundant_req
struct req_vec_problem * req_vec_get_first_redundant_req(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:6574
req_vec_is_impossible_to_fulfill
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
Definition requirements.c:6158
requirements.h
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
rgbcolor_load
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, char *path,...)
Definition rgbcolor.c:90
rgbcolor.h
road_number
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
road_integrators_cache_init
void road_integrators_cache_init(void)
Definition road.c:111
road_type_init
void road_type_init(struct extra_type *pextra, int idx)
Definition road.c:93
road.h
rscompat_names
bool rscompat_names(struct rscompat_info *info)
Definition rscompat.c:341
rscompat_postprocess
void rscompat_postprocess(struct rscompat_info *info)
Definition rscompat.c:405
rscompat_utype_flag_name_3_3
const char * rscompat_utype_flag_name_3_3(const char *old_name)
Definition rscompat.c:472
rscompat_check_capabilities
int rscompat_check_capabilities(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:66
rscompat_enablers_add_obligatory_hard_reqs
void rscompat_enablers_add_obligatory_hard_reqs(void)
Definition rscompat.c:286
rscompat_init_info
void rscompat_init_info(struct rscompat_info *info)
Definition rscompat.c:57
rscompat_check_cap_and_version
bool rscompat_check_cap_and_version(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:131
rscompat.h
sanity_check_ruleset_data
bool sanity_check_ruleset_data(struct rscompat_info *compat)
Definition rssanity.c:853
autoadjust_ruleset_data
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1551
rssanity.h
check_cityname
#define check_cityname(name)
Definition ruleload.c:116
ruleset_purge_redundant_reqs_enablers
static int ruleset_purge_redundant_reqs_enablers(void)
Definition ruleload.c:423
ruleset_load_traits
static void ruleset_load_traits(struct trait_limits *out, struct section_file *file, const char *secname, const char *field_prefix)
Definition ruleload.c:1272
load_rulesetdir
static bool load_rulesetdir(const char *rsdir, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Definition ruleload.c:9275
STYLE_SECTION_PREFIX
#define STYLE_SECTION_PREFIX
Definition ruleload.c:98
lookup_terrain
static bool lookup_terrain(struct section_file *file, const char *entry, const char *filename, struct terrain *pthis, struct terrain **result, bool null_acceptable)
Definition ruleload.c:1173
load_ruleset_veteran
static bool load_ruleset_veteran(struct section_file *file, const char *path, struct veteran_system **vsystem, char *err, size_t err_len)
Definition ruleload.c:1948
load_terrain_names
static bool load_terrain_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:2760
load_style_names
static bool load_style_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:5610
ruleset_purge_unused_entities
int ruleset_purge_unused_entities(void)
Definition ruleload.c:313
MUSICSTYLE_SECTION_PREFIX
#define MUSICSTYLE_SECTION_PREFIX
Definition ruleload.c:91
road_sections
static char * road_sections
Definition ruleload.c:127
load_ruleset_governments
static bool load_ruleset_governments(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:4321
MULTIPLIER_SECTION_PREFIX
#define MULTIPLIER_SECTION_PREFIX
Definition ruleload.c:112
reqs_list
static struct requirement_vector reqs_list
Definition ruleload.c:129
send_ruleset_techs
static void send_ruleset_techs(struct conn_list *dest)
Definition ruleload.c:8119
section_strlcpy
#define section_strlcpy(dst, src)
Definition ruleload.c:121
load_action_range
static bool load_action_range(struct section_file *file, action_id act)
Definition ruleload.c:6332
check_name
#define check_name(name)
Definition ruleload.c:115
send_ruleset_units
static void send_ruleset_units(struct conn_list *dest)
Definition ruleload.c:7934
send_ruleset_governments
static void send_ruleset_governments(struct conn_list *dest)
Definition ruleload.c:8799
load_action_names
static bool load_action_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:1441
lookup_resource
static struct extra_type * lookup_resource(const char *filename, const char *name, const char *jsection)
Definition ruleload.c:1152
openload_luadata_file
static struct section_file * openload_luadata_file(const char *rsdir)
Definition ruleload.c:626
load_ruleset_techs
static bool load_ruleset_techs(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:1579
purge_unused_req_vec
static bool purge_unused_req_vec(const struct requirement_vector *reqs, const char *msg)
Definition ruleload.c:327
rulesets_deinit
void rulesets_deinit(void)
Definition ruleload.c:9265
send_ruleset_resources
static void send_ruleset_resources(struct conn_list *dest)
Definition ruleload.c:8404
load_ruleset_buildings
static bool load_ruleset_buildings(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:2636
terrain_sections
static char * terrain_sections
Definition ruleload.c:124
lookup_building_list
static bool lookup_building_list(struct section_file *file, const char *prefix, const char *entry, int *output, const char *filename)
Definition ruleload.c:1004
nullcheck_secfile_destroy
static void nullcheck_secfile_destroy(struct section_file *file)
Definition ruleload.c:9254
send_ruleset_clauses
static void send_ruleset_clauses(struct conn_list *dest)
Definition ruleload.c:8968
send_ruleset_game
static void send_ruleset_game(struct conn_list *dest)
Definition ruleload.c:9094
parser_buffer
char * parser_buffer
Definition ruleload.c:209
NATION_SECTION_PREFIX
#define NATION_SECTION_PREFIX
Definition ruleload.c:97
load_ruleset_effects
static bool load_ruleset_effects(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:6058
lookup_cbonus_list
static bool lookup_cbonus_list(struct combat_bonus_list *list, struct section_file *file, const char *sec, const char *sub)
Definition ruleload.c:789
send_ruleset_nations
static void send_ruleset_nations(struct conn_list *dest)
Definition ruleload.c:8842
send_ruleset_roads
static void send_ruleset_roads(struct conn_list *dest)
Definition ruleload.c:8561
ruleset_purge_unused_enablers
static int ruleset_purge_unused_enablers(void)
Definition ruleload.c:244
UEFF_SECTION_PREFIX
#define UEFF_SECTION_PREFIX
Definition ruleload.c:92
is_on_allowed_list
static bool is_on_allowed_list(const char *name, const char **list, size_t len)
Definition ruleload.c:4707
send_ruleset_tech_classes
static void send_ruleset_tech_classes(struct conn_list *dest)
Definition ruleload.c:8101
send_ruleset_action_enablers
static void send_ruleset_action_enablers(struct conn_list *dest)
Definition ruleload.c:8714
send_ruleset_control
static void send_ruleset_control(struct conn_list *dest)
Definition ruleload.c:4513
load_rulesets
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Definition ruleload.c:9185
GOODS_SECTION_PREFIX
#define GOODS_SECTION_PREFIX
Definition ruleload.c:104
ruleset_error_real
void ruleset_error_real(rs_conversion_logger logger, const char *file, const char *function, int line, enum log_level level, const char *format,...)
Definition ruleload.c:215
TERRAIN_SECTION_PREFIX
#define TERRAIN_SECTION_PREFIX
Definition ruleload.c:106
openload_ruleset_file
static struct section_file * openload_ruleset_file(const char *whichset, const char *rsdir)
Definition ruleload.c:571
send_ruleset_musics
static void send_ruleset_musics(struct conn_list *dest)
Definition ruleload.c:9068
ruleset_purge_redundant_reqs
int ruleset_purge_redundant_reqs(void)
Definition ruleload.c:490
secfile_lookup_int_default_min_max
static int secfile_lookup_int_default_min_max(struct section_file *file, int def, int min, int max, const char *path,...) fc__attribute((__format__(__printf__
Definition ruleload.c:6232
base_sections
static char * base_sections
Definition ruleload.c:126
DISASTER_SECTION_PREFIX
#define DISASTER_SECTION_PREFIX
Definition ruleload.c:109
send_ruleset_goods
static void send_ruleset_goods(struct conn_list *dest)
Definition ruleload.c:8601
name_too_long
static const char name_too_long[]
Definition ruleload.c:119
reload_rulesets_settings
bool reload_rulesets_settings(void)
Definition ruleload.c:9513
lookup_strvec
static struct strvec * lookup_strvec(struct section_file *file, const char *prefix, const char *suffix)
Definition ruleload.c:1132
CITYSTYLE_SECTION_PREFIX
#define CITYSTYLE_SECTION_PREFIX
Definition ruleload.c:90
lookup_tech
static bool lookup_tech(struct section_file *file, struct advance **result, const char *prefix, const char *entry, const char *filename, const char *description)
Definition ruleload.c:848
load_game_names
static bool load_game_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:1311
send_ruleset_counters
static void send_ruleset_counters(struct conn_list *dest)
Definition ruleload.c:8210
send_ruleset_specialists
static void send_ruleset_specialists(struct conn_list *dest)
Definition ruleload.c:8073
ADVANCE_SECTION_PREFIX
#define ADVANCE_SECTION_PREFIX
Definition ruleload.c:87
EFFECT_SECTION_PREFIX
#define EFFECT_SECTION_PREFIX
Definition ruleload.c:93
send_ruleset_action_auto_performers
static void send_ruleset_action_auto_performers(struct conn_list *dest)
Definition ruleload.c:8742
load_government_names
static bool load_government_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:4239
send_ruleset_team_names
static void send_ruleset_team_names(struct conn_list *dest)
Definition ruleload.c:9155
send_ruleset_cities
static void send_ruleset_cities(struct conn_list *dest)
Definition ruleload.c:9040
purge_redundant_req_vec
static bool purge_redundant_req_vec(const struct requirement_vector *reqs, const char *msg)
Definition ruleload.c:412
lookup_string
static char * lookup_string(struct section_file *file, const char *prefix, const char *suffix)
Definition ruleload.c:1112
check_leader_names
static const char * check_leader_names(struct nation_type *pnation)
Definition ruleload.c:4551
ACTION_ENABLER_SECTION_PREFIX
#define ACTION_ENABLER_SECTION_PREFIX
Definition ruleload.c:111
BASE_SECTION_PREFIX
#define BASE_SECTION_PREFIX
Definition ruleload.c:101
ruleset_purge_redundant_reqs_effects
static int ruleset_purge_redundant_reqs_effects(void)
Definition ruleload.c:461
openload_script_file
static enum fc_tristate openload_script_file(const char *whichset, const char *rsdir, char **buffer, bool optional)
Definition ruleload.c:599
get_parser_buffer
char * get_parser_buffer(void)
Definition ruleload.c:562
load_building_names
static bool load_building_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:2555
EXTRA_SECTION_PREFIX
#define EXTRA_SECTION_PREFIX
Definition ruleload.c:100
send_rulesets
void send_rulesets(struct conn_list *dest)
Definition ruleload.c:9536
CLAUSE_SECTION_PREFIX
#define CLAUSE_SECTION_PREFIX
Definition ruleload.c:99
lookup_unit_list
static bool lookup_unit_list(struct section_file *file, const char *prefix, const char *entry, struct unit_type **output, const char *filename)
Definition ruleload.c:880
resource_sections
static char * resource_sections
Definition ruleload.c:123
UNIT_SECTION_PREFIX
#define UNIT_SECTION_PREFIX
Definition ruleload.c:108
ACHIEVEMENT_SECTION_PREFIX
#define ACHIEVEMENT_SECTION_PREFIX
Definition ruleload.c:110
load_ruleset_cities
static bool load_ruleset_cities(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:5850
load_ruleset_styles
static bool load_ruleset_styles(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:5671
lookup_government
static struct government * lookup_government(struct section_file *file, const char *entry, const char *filename, struct government *fallback)
Definition ruleload.c:1087
load_ruleset_units
static bool load_ruleset_units(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:2069
script_buffer
char * script_buffer
Definition ruleload.c:208
lookup_time
static bool lookup_time(const struct section_file *secfile, int *turns, const char *sec_name, const char *property_name, const char *filename, const char *item_name, bool *ok)
Definition ruleload.c:1223
load_action_blocked_by_list
static bool load_action_blocked_by_list(struct section_file *file, const char *filename, struct action *paction)
Definition ruleload.c:6396
send_ruleset_styles
static void send_ruleset_styles(struct conn_list *dest)
Definition ruleload.c:8952
NATION_GROUP_SECTION_PREFIX
#define NATION_GROUP_SECTION_PREFIX
Definition ruleload.c:96
extra_sections
static char * extra_sections
Definition ruleload.c:125
RULES_SUFFIX
#define RULES_SUFFIX
Definition ruleload.c:84
lookup_req_list
struct requirement_vector * lookup_req_list(struct section_file *file, struct rscompat_info *compat, const char *sec, const char *sub, const char *rfor)
Definition ruleload.c:654
send_ruleset_disasters
static void send_ruleset_disasters(struct conn_list *dest)
Definition ruleload.c:8633
purge_duplicate_req_vec
static bool purge_duplicate_req_vec(const struct requirement_vector *reqs, const char *msg)
Definition ruleload.c:367
lookup_tech_list
static bool lookup_tech_list(struct section_file *file, const char *prefix, const char *entry, int *output, const char *filename)
Definition ruleload.c:940
MAX_SECTION_LABEL
#define MAX_SECTION_LABEL
Definition ruleload.c:120
BUILDING_SECTION_PREFIX
#define BUILDING_SECTION_PREFIX
Definition ruleload.c:89
load_ruleset_game
static bool load_ruleset_game(struct section_file *file, bool act, struct rscompat_info *compat)
Definition ruleload.c:6511
load_nation_names
static bool load_nation_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:4571
send_ruleset_achievements
static void send_ruleset_achievements(struct conn_list *dest)
Definition ruleload.c:8663
SCRIPT_SUFFIX
#define SCRIPT_SUFFIX
Definition ruleload.c:85
send_ruleset_bases
static void send_ruleset_bases(struct conn_list *dest)
Definition ruleload.c:8539
load_ruleset_terrain
static bool load_ruleset_terrain(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:3092
ruleset_purge_unused_effects
static int ruleset_purge_unused_effects(void)
Definition ruleload.c:290
load_action_actor_consuming_always
static bool load_action_actor_consuming_always(struct section_file *file, action_id act)
Definition ruleload.c:6379
load_action_post_success_force
static bool load_action_post_success_force(struct section_file *file, const char *filename, int performer_slot, struct action *paction)
Definition ruleload.c:6440
load_tech_names
static bool load_tech_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:1461
SPECIALIST_SECTION_PREFIX
#define SPECIALIST_SECTION_PREFIX
Definition ruleload.c:105
COUNTER_SECTION_PREFIX
#define COUNTER_SECTION_PREFIX
Definition ruleload.c:113
load_action_kind
static bool load_action_kind(struct section_file *file, action_id act)
Definition ruleload.c:6357
send_ruleset_multipliers
static void send_ruleset_multipliers(struct conn_list *dest)
Definition ruleload.c:9006
get_script_buffer
char * get_script_buffer(void)
Definition ruleload.c:554
send_ruleset_actions
static void send_ruleset_actions(struct conn_list *dest)
Definition ruleload.c:8684
load_city_name_list
static bool load_city_name_list(struct section_file *file, struct nation_type *pnation, const char *secfile_str1, const char *secfile_str2, const char **allowed_terrains, size_t atcount)
Definition ruleload.c:4723
load_action_auto_uflag_block
static bool load_action_auto_uflag_block(struct section_file *file, struct action_auto_perf *auto_perf, const char *uflags_path, const char *filename)
Definition ruleload.c:5749
load_ruleset_nations
static bool load_ruleset_nations(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:4893
load_action_auto_actions
static bool load_action_auto_actions(struct section_file *file, struct action_auto_perf *auto_perf, const char *actions_path, const char *filename)
Definition ruleload.c:5792
send_ruleset_unit_classes
static void send_ruleset_unit_classes(struct conn_list *dest)
Definition ruleload.c:7886
TECH_CLASS_SECTION_PREFIX
#define TECH_CLASS_SECTION_PREFIX
Definition ruleload.c:88
RESOURCE_SECTION_PREFIX
#define RESOURCE_SECTION_PREFIX
Definition ruleload.c:103
lookup_unit_type
static bool lookup_unit_type(struct section_file *file, const char *prefix, const char *entry, const struct unit_type **result, const char *filename, const char *description)
Definition ruleload.c:1056
send_ruleset_extras
static void send_ruleset_extras(struct conn_list *dest)
Definition ruleload.c:8423
rs_sanity_veteran
#define rs_sanity_veteran(_path, _entry, _i, _condition, _action)
send_ruleset_terrain
static void send_ruleset_terrain(struct conn_list *dest)
Definition ruleload.c:8297
GOVERNMENT_SECTION_PREFIX
#define GOVERNMENT_SECTION_PREFIX
Definition ruleload.c:94
load_unit_names
static bool load_unit_names(struct section_file *file, struct rscompat_info *compat)
Definition ruleload.c:1790
send_ruleset_trade_routes
static void send_ruleset_trade_routes(struct conn_list *dest)
Definition ruleload.c:8778
load_ruleset_actions
static bool load_ruleset_actions(struct section_file *file, struct section_file *gamefile, struct rscompat_info *compat)
Definition ruleload.c:7562
notify_ruleset_fallback
static void notify_ruleset_fallback(const char *msg)
Definition ruleload.c:9177
lookup_bv_actions
static bool lookup_bv_actions(struct section_file *file, const char *filename, bv_actions *target, const char *path)
Definition ruleload.c:6477
send_ruleset_buildings
static void send_ruleset_buildings(struct conn_list *dest)
Definition ruleload.c:8231
UNIT_CLASS_SECTION_PREFIX
#define UNIT_CLASS_SECTION_PREFIX
Definition ruleload.c:107
ruleset_load_names
static bool ruleset_load_names(struct name_translation *pname, const char *domain, struct section_file *file, const char *sec_name)
Definition ruleload.c:1249
ROAD_SECTION_PREFIX
#define ROAD_SECTION_PREFIX
Definition ruleload.c:102
valid_ruleset_filename
static const char * valid_ruleset_filename(const char *subdir, const char *name, const char *extension, bool optional)
Definition ruleload.c:509
load_action_range_max
static bool load_action_range_max(struct section_file *file, action_id act)
Definition ruleload.c:6291
load_muuk_as_action_auto
static bool load_muuk_as_action_auto(struct section_file *file, struct action_auto_perf *auto_perf, const char *item, const char *filename)
Definition ruleload.c:5828
load_action_ui_name
static bool load_action_ui_name(struct section_file *file, int act, const char *entry_name)
Definition ruleload.c:6270
NATION_SET_SECTION_PREFIX
#define NATION_SET_SECTION_PREFIX
Definition ruleload.c:95
ruleload.h
RS_DEFAULT_CONVERT_SPEED
#define RS_DEFAULT_CONVERT_SPEED
Definition ruleload.h:123
RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
#define RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
Definition ruleload.h:109
RS_DEFAULT_WORLD_PEACE_TURNS
#define RS_DEFAULT_WORLD_PEACE_TURNS
Definition ruleload.h:99
RS_DEFAULT_TECH_TRADE_LOSS_HOLES
#define RS_DEFAULT_TECH_TRADE_LOSS_HOLES
Definition ruleload.h:84
RS_DEFAULT_TECH_COST_STYLE
#define RS_DEFAULT_TECH_COST_STYLE
Definition ruleload.h:90
RS_DEFAULT_EXTRA_APPEARANCE
#define RS_DEFAULT_EXTRA_APPEARANCE
Definition ruleload.h:103
RS_DEFAULT_TECH_PARASITE_HOLES
#define RS_DEFAULT_TECH_PARASITE_HOLES
Definition ruleload.h:85
GAME_DEFAULT_ACH_VALUE
#define GAME_DEFAULT_ACH_VALUE
Definition ruleload.h:78
RS_DEFAULT_TECH_TRADE_HOLES
#define RS_DEFAULT_TECH_TRADE_HOLES
Definition ruleload.h:83
RS_DEFAULT_CULTURE_VIC_POINTS
#define RS_DEFAULT_CULTURE_VIC_POINTS
Definition ruleload.h:94
RS_DEFAULT_CULTURE_MIGRATION_PML
#define RS_DEFAULT_CULTURE_MIGRATION_PML
Definition ruleload.h:96
rs_conversion_logger
void(* rs_conversion_logger)(const char *msg)
Definition ruleload.h:42
RS_DEFAULT_SMALL_WONDER_VISIBILITY
#define RS_DEFAULT_SMALL_WONDER_VISIBILITY
Definition ruleload.h:111
ruleset_error
#define ruleset_error(logger, level, format,...)
Definition ruleload.h:59
RS_DEFAULT_ONLY_KILLING_VETERAN
#define RS_DEFAULT_ONLY_KILLING_VETERAN
Definition ruleload.h:106
RS_DEFAULT_TECH_LOSS_HOLES
#define RS_DEFAULT_TECH_LOSS_HOLES
Definition ruleload.h:86
RS_DEFAULT_HISTORY_INTEREST_PML
#define RS_DEFAULT_HISTORY_INTEREST_PML
Definition ruleload.h:97
RS_DEFAULT_TECH_UPKEEP_STYLE
#define RS_DEFAULT_TECH_UPKEEP_STYLE
Definition ruleload.h:92
RS_DEFAULT_GOODS_SELECTION
#define RS_DEFAULT_GOODS_SELECTION
Definition ruleload.h:101
RS_DEFAULT_PYTHAGOREAN_DIAGONAL
#define RS_DEFAULT_PYTHAGOREAN_DIAGONAL
Definition ruleload.h:87
RS_DEFAULT_TECH_STEAL_HOLES
#define RS_DEFAULT_TECH_STEAL_HOLES
Definition ruleload.h:82
RS_MIN_MIN_TECH_COST
#define RS_MIN_MIN_TECH_COST
Definition ruleload.h:118
GAME_DEFAULT_ACH_UNIQUE
#define GAME_DEFAULT_ACH_UNIQUE
Definition ruleload.h:77
RS_MAX_BASE_TECH_COST
#define RS_MAX_BASE_TECH_COST
Definition ruleload.h:115
RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
#define RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
Definition ruleload.h:108
RS_DEFAULT_MUUK_FOOD_WIPE
#define RS_DEFAULT_MUUK_FOOD_WIPE
Definition ruleload.h:79
RS_DEFAULT_MUUK_GOLD_WIPE
#define RS_DEFAULT_MUUK_GOLD_WIPE
Definition ruleload.h:80
RS_DEFAULT_BASE_TECH_COST
#define RS_DEFAULT_BASE_TECH_COST
Definition ruleload.h:113
RS_DEFAULT_NATIONALITY
#define RS_DEFAULT_NATIONALITY
Definition ruleload.h:121
GAME_DEFAULT_CHANGABLE_TAX
#define GAME_DEFAULT_CHANGABLE_TAX
Definition ruleload.h:74
RS_DEFAULT_MUUK_SHIELD_WIPE
#define RS_DEFAULT_MUUK_SHIELD_WIPE
Definition ruleload.h:81
RSFORMAT_CURRENT
#define RSFORMAT_CURRENT
Definition ruleload.h:38
RS_DEFAULT_GOLD_UPKEEP_STYLE
#define RS_DEFAULT_GOLD_UPKEEP_STYLE
Definition ruleload.h:89
GAME_DEFAULT_ADDTOSIZE
#define GAME_DEFAULT_ADDTOSIZE
Definition ruleload.h:73
RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
#define RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
Definition ruleload.h:107
RS_DEFAULT_EXTRA_DISAPPEARANCE
#define RS_DEFAULT_EXTRA_DISAPPEARANCE
Definition ruleload.h:104
RS_MAX_MIN_TECH_COST
#define RS_MAX_MIN_TECH_COST
Definition ruleload.h:119
RS_DEFAULT_MIN_TECH_COST
#define RS_DEFAULT_MIN_TECH_COST
Definition ruleload.h:117
GAME_DEFAULT_VISION_REVEAL_TILES
#define GAME_DEFAULT_VISION_REVEAL_TILES
Definition ruleload.h:75
RS_DEFAULT_CULTURE_VIC_LEAD
#define RS_DEFAULT_CULTURE_VIC_LEAD
Definition ruleload.h:95
RS_DEFAULT_TECH_LEAKAGE
#define RS_DEFAULT_TECH_LEAKAGE
Definition ruleload.h:91
GAME_DEFAULT_DISASTER_FREQ
#define GAME_DEFAULT_DISASTER_FREQ
Definition ruleload.h:76
RSFORMAT_3_3
#define RSFORMAT_3_3
Definition ruleload.h:37
RS_MIN_BASE_TECH_COST
#define RS_MIN_BASE_TECH_COST
Definition ruleload.h:114
compat
static struct compatibility compat[]
Definition savecompat.c:112
script_server_init
bool script_server_init(void)
Definition script_server.c:292
script_server_load_file
bool script_server_load_file(const char *filename, char **buf)
Definition script_server.c:129
script_server_free
void script_server_free(void)
Definition script_server.c:366
script_server_do_file
bool script_server_do_file(struct connection *caller, const char *filename)
Definition script_server.c:188
script_server.h
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
settings_ruleset
bool settings_ruleset(struct section_file *file, const char *section, bool act, bool compat)
Definition settings.c:4372
settings.h
sex_by_name
sex_t sex_by_name(const char *name)
Definition sex.c:27
sex.h
sex_t
sex_t
Definition sex.h:20
SEX_UNKNOWN
@ SEX_UNKNOWN
Definition sex.h:21
SEX_FEMALE
@ SEX_FEMALE
Definition sex.h:22
SEX_MALE
@ SEX_MALE
Definition sex.h:23
check_strlen
bool check_strlen(const char *str, size_t len, const char *errmsg)
Definition shared.c:495
fileinfoname
const char * fileinfoname(const struct strvec *dirs, const char *filename)
Definition shared.c:1101
remove_leading_trailing_spaces
void remove_leading_trailing_spaces(char *s)
Definition shared.c:444
get_data_dirs
const struct strvec * get_data_dirs(void)
Definition shared.c:893
shared.h
fc_tristate
fc_tristate
Definition shared.h:46
TRI_YES
@ TRI_YES
Definition shared.h:46
TRI_NO
@ TRI_NO
Definition shared.h:46
TRI_MAYBE
@ TRI_MAYBE
Definition shared.h:46
DIR_SEPARATOR
#define DIR_SEPARATOR
Definition shared.h:127
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
specialist_by_number
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:100
specialist_rule_name
const char * specialist_rule_name(const struct specialist *sp)
Definition specialist.c:146
specialist.h
specialist_type_iterate_end
#define specialist_type_iterate_end
Definition specialist.h:79
specialist_type_iterate
#define specialist_type_iterate(sp)
Definition specialist.h:73
DEFAULT_SPECIALIST
#define DEFAULT_SPECIALIST
Definition specialist.h:43
aifill
const char * aifill(int amount)
Definition srv_main.c:2503
update_nations_with_startpos
void update_nations_with_startpos(void)
Definition srv_main.c:2308
srv_main.h
strvec_store
void strvec_store(struct strvec *psv, const char *const *vec, size_t size)
Definition string_vector.c:111
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:59
string_vector.h
action_auto_perf
Definition actions.h:316
action_enabler
Definition actions.h:165
action
Definition actions.h:106
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:139
action::max_distance
int max_distance
Definition actions.h:122
action::quiet
bool quiet
Definition actions.h:129
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:125
action::sub_results
bv_action_sub_results sub_results
Definition actions.h:110
action::actor_kind
enum action_actor_kind actor_kind
Definition actions.h:112
action::blocked_by
bv_actions blocked_by
Definition actions.h:133
action::target_kind
enum action_target_kind target_kind
Definition actions.h:113
action::min_distance
int min_distance
Definition actions.h:122
advance
Definition tech.h:124
advance::require
struct advance * require[AR_SIZE]
Definition tech.h:132
base_type
Definition base.h:41
base_type::border_sq
int border_sq
Definition base.h:44
base_type::vision_main_sq
int vision_main_sq
Definition base.h:45
base_type::gui_type
enum base_gui_type gui_type
Definition base.h:43
base_type::vision_invis_sq
int vision_invis_sq
Definition base.h:46
base_type::vision_subs_sq
int vision_subs_sq
Definition base.h:47
civ_game::nationlist
char * nationlist
Definition game.h:282
civ_game::named_teams
int named_teams
Definition game.h:294
civ_game::as_count
size_t as_count
Definition game.h:293
civ_game::allowed_govs
const char ** allowed_govs
Definition game.h:285
civ_game::upgrade_veteran_loss
int upgrade_veteran_loss
Definition game.h:199
civ_game::plr_bg_color
struct rgbcolor * plr_bg_color
Definition game.h:103
civ_game::incite_total_factor
int incite_total_factor
Definition game.h:150
civ_game::init_vis_radius_sq
int init_vis_radius_sq
Definition game.h:152
civ_game::vision_reveal_tiles
bool vision_reveal_tiles
Definition game.h:200
civ_game::description_file
char * description_file
Definition game.h:281
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
civ_game::ruleset_summary
char * ruleset_summary
Definition game.h:84
civ_game::nc_agovs
char ** nc_agovs
Definition game.h:286
civ_game::base_incite_cost
int base_incite_cost
Definition game.h:134
civ_game::global_init_techs
int global_init_techs[MAX_NUM_TECH_LIST]
Definition game.h:108
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::autoupgrade_veteran_loss
int autoupgrade_veteran_loss
Definition game.h:132
civ_game::rulesetdir
char rulesetdir[MAX_LEN_NAME]
Definition game.h:239
civ_game::start_year
int start_year
Definition game.h:191
civ_game::incite_improvement_factor
int incite_improvement_factor
Definition game.h:149
civ_game::luadata
struct section_file * luadata
Definition game.h:247
civ_game::embedded_nations
char ** embedded_nations
Definition game.h:283
civ_game::global_init_buildings
int global_init_buildings[MAX_NUM_BUILDING_LIST]
Definition game.h:109
civ_game::default_traits
struct trait_limits default_traits[TRAIT_COUNT]
Definition game.h:274
civ_game::nc_astyles
char ** nc_astyles
Definition game.h:292
civ_game::allowed_terrains
const char ** allowed_terrains
Definition game.h:288
civ_game::ruledit
struct civ_game::@31::@35::@40 ruledit
civ_game::ruleset_description
char * ruleset_description
Definition game.h:85
civ_game::ag_count
size_t ag_count
Definition game.h:287
civ_game::allowed_styles
const char ** allowed_styles
Definition game.h:291
civ_game::server
struct civ_game::@31::@35 server
civ_game::nc_aterrs
char ** nc_aterrs
Definition game.h:289
civ_game::embedded_nations_count
size_t embedded_nations_count
Definition game.h:284
civ_game::incite_unit_factor
int incite_unit_factor
Definition game.h:151
civ_game::ruleset_capabilities
char * ruleset_capabilities
Definition game.h:86
civ_game::rgame
struct civ_game::@30 rgame
civ_game::ransom_gold
int ransom_gold
Definition game.h:175
civ_game::at_count
size_t at_count
Definition game.h:290
civ_game::veteran
struct veteran_system * veteran
Definition game.h:101
civ_game::calendar
struct packet_calendar_info calendar
Definition game.h:90
civ_game::default_government
struct government * default_government
Definition game.h:93
civ_game::government_during_revolution
struct government * government_during_revolution
Definition game.h:94
civ_map::server
struct civ_map::@42::@44 server
civ_map::ocean_resources
bool ocean_resources
Definition map_types.h:107
clause_info
Definition diptreaty.h:55
clause_info::receiver_reqs
struct requirement_vector receiver_reqs
Definition diptreaty.h:59
clause_info::giver_reqs
struct requirement_vector giver_reqs
Definition diptreaty.h:58
clause_info::either_reqs
struct requirement_vector either_reqs
Definition diptreaty.h:60
clause_info::enabled
bool enabled
Definition diptreaty.h:57
combat_bonus
Definition unittype.h:473
combat_bonus::value
int value
Definition unittype.h:476
combat_bonus::flag
enum unit_type_flag_id flag
Definition unittype.h:474
combat_bonus::quiet
bool quiet
Definition unittype.h:479
combat_bonus::type
enum combat_bonus_type type
Definition unittype.h:475
compatibility::version
int version
Definition savecompat.c:95
counter
Definition counters.h:27
effect
Definition effects.h:40
entry
Definition registry_ini.c:193
extra_type
Definition extras.h:88
extra_type::name
struct name_translation name
Definition extras.h:90
government
Definition government.h:52
impr_type
Definition improvement.h:50
impr_type::build_cost
int build_cost
Definition improvement.h:60
impr_type::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition improvement.h:55
impr_type::upkeep
int upkeep
Definition improvement.h:61
impr_type::graphic_alt2
char graphic_alt2[MAX_LEN_NAME]
Definition improvement.h:57
impr_type::genus
enum impr_genus_id genus
Definition improvement.h:63
impr_type::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition improvement.h:56
impr_type::obsolete_by
struct requirement_vector obsolete_by
Definition improvement.h:59
impr_type::sabotage
int sabotage
Definition improvement.h:62
impr_type::soundtag_alt
char soundtag_alt[MAX_LEN_NAME]
Definition improvement.h:67
impr_type::soundtag_alt2
char soundtag_alt2[MAX_LEN_NAME]
Definition improvement.h:68
impr_type::reqs
struct requirement_vector reqs
Definition improvement.h:58
impr_type::helptext
struct strvec * helptext
Definition improvement.h:65
impr_type::name
struct name_translation name
Definition improvement.h:52
impr_type::flags
bv_impr_flags flags
Definition improvement.h:64
impr_type::soundtag
char soundtag[MAX_LEN_NAME]
Definition improvement.h:66
item
Definition climisc.h:80
multiplier
Definition multipliers.h:31
music_style
Definition style.h:29
name_translation
Definition name_translation.h:35
nation_city
Definition nation.c:321
nation_group
Definition nation.h:167
nation_group::hidden
bool hidden
Definition nation.h:169
nation_set
Definition nation.c:41
nation_type
Definition nation.h:98
nation_type::legend
char * legend
Definition nation.h:107
nation_type::barb_type
enum barbarian_type barb_type
Definition nation.h:110
packet_calendar_info::positive_year_label
char positive_year_label[MAX_LEN_NAME]
Definition packets_gen.h:261
packet_calendar_info::calendar_skip_0
bool calendar_skip_0
Definition packets_gen.h:265
packet_calendar_info::negative_year_label
char negative_year_label[MAX_LEN_NAME]
Definition packets_gen.h:262
packet_calendar_info::calendar_fragments
int calendar_fragments
Definition packets_gen.h:263
packet_calendar_info::calendar_fragment_name
char calendar_fragment_name[MAX_CALENDAR_FRAGMENTS][MAX_LEN_NAME]
Definition packets_gen.h:264
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:217
packet_game_info::min_trade_route_val
int min_trade_route_val
Definition packets_gen.h:164
packet_game_info::illness_trade_infection
int illness_trade_infection
Definition packets_gen.h:189
packet_game_info::gameloss_style
enum gameloss_style gameloss_style
Definition packets_gen.h:238
packet_game_info::history_interest_pml
int history_interest_pml
Definition packets_gen.h:141
packet_game_info::citizen_partisans_pct
int citizen_partisans_pct
Definition packets_gen.h:150
packet_game_info::celebratesize
int celebratesize
Definition packets_gen.h:143
packet_game_info::goods_selection
enum goods_selection_method goods_selection
Definition packets_gen.h:166
packet_game_info::illness_base_factor
int illness_base_factor
Definition packets_gen.h:185
packet_game_info::illness_min_size
int illness_min_size
Definition packets_gen.h:186
packet_game_info::aifill
int aifill
Definition packets_gen.h:122
packet_game_info::add_to_size_limit
int add_to_size_limit
Definition packets_gen.h:121
packet_game_info::forced_science
int forced_science
Definition packets_gen.h:161
packet_game_info::granary_num_inis
int granary_num_inis
Definition packets_gen.h:180
packet_game_info::government_during_revolution_id
Government_type_id government_during_revolution_id
Definition packets_gen.h:177
packet_game_info::gold_upkeep_style
enum gold_upkeep_style gold_upkeep_style
Definition packets_gen.h:172
packet_game_info::pop_report_zeroes
int pop_report_zeroes
Definition packets_gen.h:145
packet_game_info::damage_reduces_bombard_rate
bool damage_reduces_bombard_rate
Definition packets_gen.h:198
packet_game_info::citizen_nationality
bool citizen_nationality
Definition packets_gen.h:146
packet_game_info::nuke_pop_loss_pct
int nuke_pop_loss_pct
Definition packets_gen.h:203
packet_game_info::nuke_defender_survival_chance_pct
int nuke_defender_survival_chance_pct
Definition packets_gen.h:204
packet_game_info::angrycitizen
int angrycitizen
Definition packets_gen.h:127
packet_game_info::granary_food_inc
int granary_food_inc
Definition packets_gen.h:178
packet_game_info::tech_upkeep_style
enum tech_upkeep_style tech_upkeep_style
Definition packets_gen.h:235
packet_game_info::tech_trade_loss_allow_holes
bool tech_trade_loss_allow_holes
Definition packets_gen.h:219
packet_game_info::granary_food_ini
int granary_food_ini[MAX_GRANARY_INIS]
Definition packets_gen.h:179
packet_game_info::culture_vic_lead
int culture_vic_lead
Definition packets_gen.h:139
packet_game_info::free_tech_method
enum free_tech_method free_tech_method
Definition packets_gen.h:237
packet_game_info::changable_tax
bool changable_tax
Definition packets_gen.h:144
packet_game_info::steal_maps_reveals_all_cities
bool steal_maps_reveals_all_cities
Definition packets_gen.h:215
packet_game_info::init_city_radius_sq
int init_city_radius_sq
Definition packets_gen.h:190
packet_game_info::granularity
int granularity
Definition packets_gen.h:256
packet_game_info::conquest_convert_pct
int conquest_convert_pct
Definition packets_gen.h:149
packet_game_info::muuk_food_wipe
bool muuk_food_wipe
Definition packets_gen.h:206
packet_game_info::homeless_gold_upkeep
bool homeless_gold_upkeep
Definition packets_gen.h:173
packet_game_info::tired_attack
bool tired_attack
Definition packets_gen.h:241
packet_game_info::only_real_fight_makes_veteran
bool only_real_fight_makes_veteran
Definition packets_gen.h:196
packet_game_info::low_firepower_pearl_harbour
int low_firepower_pearl_harbour
Definition packets_gen.h:200
packet_game_info::base_pollution
int base_pollution
Definition packets_gen.h:128
packet_game_info::citizen_convert_speed
int citizen_convert_speed
Definition packets_gen.h:148
packet_game_info::forced_gold
int forced_gold
Definition packets_gen.h:159
packet_game_info::illness_pollution_factor
int illness_pollution_factor
Definition packets_gen.h:188
packet_game_info::base_tech_cost
int base_tech_cost
Definition packets_gen.h:129
packet_game_info::happy_cost
int happy_cost
Definition packets_gen.h:182
packet_game_info::civil_war_enabled
bool civil_war_enabled
Definition packets_gen.h:253
packet_game_info::muuk_gold_wipe
bool muuk_gold_wipe
Definition packets_gen.h:207
packet_game_info::food_cost
int food_cost
Definition packets_gen.h:157
packet_game_info::tech_leakage
enum tech_leakage_style tech_leakage
Definition packets_gen.h:233
packet_game_info::world_peace_turns
int world_peace_turns
Definition packets_gen.h:142
packet_game_info::reveal_trade_partner
bool reveal_trade_partner
Definition packets_gen.h:165
packet_game_info::airlift_from_always_enabled
bool airlift_from_always_enabled
Definition packets_gen.h:125
packet_game_info::min_tech_cost
int min_tech_cost
Definition packets_gen.h:130
packet_game_info::illness_on
bool illness_on
Definition packets_gen.h:187
packet_game_info::civil_war_bonus_unhappy
int civil_war_bonus_unhappy
Definition packets_gen.h:255
packet_game_info::only_killing_makes_veteran
bool only_killing_makes_veteran
Definition packets_gen.h:195
packet_game_info::poison_empties_food_stock
bool poison_empties_food_stock
Definition packets_gen.h:216
packet_game_info::tech_loss_allow_holes
bool tech_loss_allow_holes
Definition packets_gen.h:221
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:154
packet_game_info::tech_trade_allow_holes
bool tech_trade_allow_holes
Definition packets_gen.h:218
packet_game_info::low_firepower_nonnat_bombard
int low_firepower_nonnat_bombard
Definition packets_gen.h:202
packet_game_info::border_size_effect
int border_size_effect
Definition packets_gen.h:133
packet_game_info::tech_upkeep_divider
int tech_upkeep_divider
Definition packets_gen.h:234
packet_game_info::pillage_select
bool pillage_select
Definition packets_gen.h:214
packet_game_info::tech_parasite_allow_holes
bool tech_parasite_allow_holes
Definition packets_gen.h:220
packet_game_info::muuk_shield_wipe
bool muuk_shield_wipe
Definition packets_gen.h:208
packet_game_info::base_bribe_cost
int base_bribe_cost
Definition packets_gen.h:136
packet_game_info::low_firepower_combat_bonus
int low_firepower_combat_bonus
Definition packets_gen.h:201
packet_game_info::culture_migration_pml
int culture_migration_pml
Definition packets_gen.h:140
packet_game_info::border_city_permanent_radius_sq
int border_city_permanent_radius_sq
Definition packets_gen.h:134
packet_game_info::culture_vic_points
int culture_vic_points
Definition packets_gen.h:138
packet_game_info::low_firepower_badwallattacker
int low_firepower_badwallattacker
Definition packets_gen.h:199
packet_game_info::airlift_to_always_enabled
bool airlift_to_always_enabled
Definition packets_gen.h:126
packet_game_info::small_wonder_visibility
enum wonder_visib_type small_wonder_visibility
Definition packets_gen.h:257
packet_game_info::tech_cost_style
enum tech_cost_style tech_cost_style
Definition packets_gen.h:232
packet_game_info::combat_odds_scaled_veterancy
bool combat_odds_scaled_veterancy
Definition packets_gen.h:197
packet_game_info::unit_builders_nationality
bool unit_builders_nationality
Definition packets_gen.h:147
packet_game_info::civil_war_bonus_celebrating
int civil_war_bonus_celebrating
Definition packets_gen.h:254
packet_game_info::border_city_radius_sq
int border_city_radius_sq
Definition packets_gen.h:132
packet_game_info::default_government_id
Government_type_id default_government_id
Definition packets_gen.h:176
packet_game_info::forced_luxury
int forced_luxury
Definition packets_gen.h:160
packet_game_info::min_city_center_output
int min_city_center_output[O_LAST]
Definition packets_gen.h:205
packet_ruleset_achievement
Definition packets_gen.h:1364
packet_ruleset_achievement::id
int id
Definition packets_gen.h:1365
packet_ruleset_achievement::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1367
packet_ruleset_achievement::unique
bool unique
Definition packets_gen.h:1369
packet_ruleset_achievement::value
int value
Definition packets_gen.h:1370
packet_ruleset_achievement::type
enum achievement_type type
Definition packets_gen.h:1368
packet_ruleset_achievement::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1366
packet_ruleset_action_auto
Definition packets_gen.h:1403
packet_ruleset_action_auto::id
int id
Definition packets_gen.h:1404
packet_ruleset_action_auto::alternatives
action_id alternatives[MAX_NUM_ACTIONS]
Definition packets_gen.h:1409
packet_ruleset_action_auto::reqs_count
int reqs_count
Definition packets_gen.h:1406
packet_ruleset_action_auto::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1407
packet_ruleset_action_auto::alternatives_count
int alternatives_count
Definition packets_gen.h:1408
packet_ruleset_action_auto::cause
enum action_auto_perf_cause cause
Definition packets_gen.h:1405
packet_ruleset_action_enabler
Definition packets_gen.h:1395
packet_ruleset_action_enabler::enabled_action
action_id enabled_action
Definition packets_gen.h:1396
packet_ruleset_action_enabler::actor_reqs_count
int actor_reqs_count
Definition packets_gen.h:1397
packet_ruleset_action_enabler::actor_reqs
struct requirement actor_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1398
packet_ruleset_action_enabler::target_reqs
struct requirement target_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1400
packet_ruleset_action_enabler::target_reqs_count
int target_reqs_count
Definition packets_gen.h:1399
packet_ruleset_action
Definition packets_gen.h:1380
packet_ruleset_action::quiet
bool quiet
Definition packets_gen.h:1383
packet_ruleset_action::sub_tgt_kind
enum action_sub_target_kind sub_tgt_kind
Definition packets_gen.h:1389
packet_ruleset_action::act_kind
enum action_actor_kind act_kind
Definition packets_gen.h:1387
packet_ruleset_action::actor_consuming_always
bool actor_consuming_always
Definition packets_gen.h:1386
packet_ruleset_action::blocked_by
bv_actions blocked_by
Definition packets_gen.h:1392
packet_ruleset_action::max_distance
int max_distance
Definition packets_gen.h:1391
packet_ruleset_action::id
action_id id
Definition packets_gen.h:1381
packet_ruleset_action::min_distance
int min_distance
Definition packets_gen.h:1390
packet_ruleset_action::sub_results
bv_action_sub_results sub_results
Definition packets_gen.h:1385
packet_ruleset_action::ui_name
char ui_name[MAX_LEN_NAME]
Definition packets_gen.h:1382
packet_ruleset_action::tgt_kind
enum action_target_kind tgt_kind
Definition packets_gen.h:1388
packet_ruleset_action::result
enum action_result result
Definition packets_gen.h:1384
packet_ruleset_base
Definition packets_gen.h:1317
packet_ruleset_base::vision_subs_sq
int vision_subs_sq
Definition packets_gen.h:1323
packet_ruleset_base::vision_invis_sq
int vision_invis_sq
Definition packets_gen.h:1322
packet_ruleset_base::border_sq
int border_sq
Definition packets_gen.h:1320
packet_ruleset_base::vision_main_sq
int vision_main_sq
Definition packets_gen.h:1321
packet_ruleset_base::gui_type
enum base_gui_type gui_type
Definition packets_gen.h:1319
packet_ruleset_base::id
int id
Definition packets_gen.h:1318
packet_ruleset_building
Definition packets_gen.h:1182
packet_ruleset_building::flags
bv_impr_flags flags
Definition packets_gen.h:1197
packet_ruleset_building::id
Impr_type_id id
Definition packets_gen.h:1183
packet_ruleset_building::helptext
struct strvec * helptext
Definition packets_gen.h:1201
packet_ruleset_building::build_cost
int build_cost
Definition packets_gen.h:1194
packet_ruleset_building::obs_reqs
struct requirement obs_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1193
packet_ruleset_building::upkeep
int upkeep
Definition packets_gen.h:1195
packet_ruleset_building::soundtag_alt
char soundtag_alt[MAX_LEN_NAME]
Definition packets_gen.h:1199
packet_ruleset_building::reqs_count
int reqs_count
Definition packets_gen.h:1190
packet_ruleset_building::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1191
packet_ruleset_building::genus
enum impr_genus_id genus
Definition packets_gen.h:1184
packet_ruleset_building::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1185
packet_ruleset_building::soundtag
char soundtag[MAX_LEN_NAME]
Definition packets_gen.h:1198
packet_ruleset_building::sabotage
int sabotage
Definition packets_gen.h:1196
packet_ruleset_building::soundtag_alt2
char soundtag_alt2[MAX_LEN_NAME]
Definition packets_gen.h:1200
packet_ruleset_building::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1186
packet_ruleset_building::obs_count
int obs_count
Definition packets_gen.h:1192
packet_ruleset_building::graphic_alt2
char graphic_alt2[MAX_LEN_NAME]
Definition packets_gen.h:1189
packet_ruleset_building::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1187
packet_ruleset_building::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1188
packet_ruleset_city
Definition packets_gen.h:1171
packet_ruleset_city::style_id
int style_id
Definition packets_gen.h:1172
packet_ruleset_clause
Definition packets_gen.h:1446
packet_ruleset_clause::type
enum clause_type type
Definition packets_gen.h:1447
packet_ruleset_clause::either_reqs_count
int either_reqs_count
Definition packets_gen.h:1453
packet_ruleset_clause::either_reqs
struct requirement either_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1454
packet_ruleset_clause::receiver_reqs
struct requirement receiver_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1452
packet_ruleset_clause::receiver_reqs_count
int receiver_reqs_count
Definition packets_gen.h:1451
packet_ruleset_clause::giver_reqs_count
int giver_reqs_count
Definition packets_gen.h:1449
packet_ruleset_clause::enabled
bool enabled
Definition packets_gen.h:1448
packet_ruleset_clause::giver_reqs
struct requirement giver_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1450
packet_ruleset_control::num_goods_types
int num_goods_types
Definition packets_gen.h:1467
packet_ruleset_control::preferred_soundset
char preferred_soundset[MAX_LEN_NAME]
Definition packets_gen.h:1481
packet_ruleset_control::num_styles
int num_styles
Definition packets_gen.h:1471
packet_ruleset_control::num_extra_types
int num_extra_types
Definition packets_gen.h:1463
packet_ruleset_control::num_unit_types
int num_unit_types
Definition packets_gen.h:1459
packet_ruleset_control::version
char version[MAX_LEN_NAME]
Definition packets_gen.h:1485
packet_ruleset_control::num_impr_types
int num_impr_types
Definition packets_gen.h:1460
packet_ruleset_control::nation_count
int nation_count
Definition packets_gen.h:1474
packet_ruleset_control::num_road_types
int num_road_types
Definition packets_gen.h:1465
packet_ruleset_control::terrain_count
int terrain_count
Definition packets_gen.h:1476
packet_ruleset_control::preferred_tileset
char preferred_tileset[MAX_LEN_NAME]
Definition packets_gen.h:1480
packet_ruleset_control::popup_tech_help
bool popup_tech_help
Definition packets_gen.h:1483
packet_ruleset_control::num_music_styles
int num_music_styles
Definition packets_gen.h:1472
packet_ruleset_control::num_tech_types
int num_tech_types
Definition packets_gen.h:1462
packet_ruleset_control::num_disaster_types
int num_disaster_types
Definition packets_gen.h:1468
packet_ruleset_control::alt_dir
char alt_dir[MAX_LEN_NAME]
Definition packets_gen.h:1486
packet_ruleset_control::num_achievement_types
int num_achievement_types
Definition packets_gen.h:1469
packet_ruleset_control::num_counters
int num_counters
Definition packets_gen.h:1488
packet_ruleset_control::num_specialist_types
int num_specialist_types
Definition packets_gen.h:1477
packet_ruleset_control::preferred_musicset
char preferred_musicset[MAX_LEN_NAME]
Definition packets_gen.h:1482
packet_ruleset_control::num_tech_classes
int num_tech_classes
Definition packets_gen.h:1461
packet_ruleset_control::num_unit_classes
int num_unit_classes
Definition packets_gen.h:1458
packet_ruleset_control::num_city_styles
int num_city_styles
Definition packets_gen.h:1475
packet_ruleset_control::num_resource_types
int num_resource_types
Definition packets_gen.h:1466
packet_ruleset_control::num_multipliers
int num_multipliers
Definition packets_gen.h:1470
packet_ruleset_control::num_nation_sets
int num_nation_sets
Definition packets_gen.h:1479
packet_ruleset_control::desc_length
int desc_length
Definition packets_gen.h:1487
packet_ruleset_control::num_nation_groups
int num_nation_groups
Definition packets_gen.h:1478
packet_ruleset_control::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1484
packet_ruleset_control::num_base_types
int num_base_types
Definition packets_gen.h:1464
packet_ruleset_counter
Definition packets_gen.h:1412
packet_ruleset_counter::checkpoint
int checkpoint
Definition packets_gen.h:1417
packet_ruleset_counter::behaviour
enum counter_behaviour behaviour
Definition packets_gen.h:1419
packet_ruleset_counter::type
enum counter_target type
Definition packets_gen.h:1418
packet_ruleset_counter::helptext
struct strvec * helptext
Definition packets_gen.h:1415
packet_ruleset_counter::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1413
packet_ruleset_counter::def
int def
Definition packets_gen.h:1416
packet_ruleset_counter::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1414
packet_ruleset_description_part
Definition packets_gen.h:1495
packet_ruleset_disaster
Definition packets_gen.h:1354
packet_ruleset_disaster::frequency
int frequency
Definition packets_gen.h:1360
packet_ruleset_disaster::id
int id
Definition packets_gen.h:1355
packet_ruleset_disaster::reqs_count
int reqs_count
Definition packets_gen.h:1358
packet_ruleset_disaster::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1357
packet_ruleset_disaster::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1359
packet_ruleset_disaster::effects
bv_disaster_effects effects
Definition packets_gen.h:1361
packet_ruleset_disaster::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1356
packet_ruleset_extra_flag
Definition packets_gen.h:1311
packet_ruleset_extra_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1314
packet_ruleset_extra_flag::id
int id
Definition packets_gen.h:1312
packet_ruleset_extra
Definition packets_gen.h:1267
packet_ruleset_extra::id
int id
Definition packets_gen.h:1268
packet_ruleset_extra::removal_time
int removal_time
Definition packets_gen.h:1297
packet_ruleset_extra::defense_bonus
int defense_bonus
Definition packets_gen.h:1300
packet_ruleset_extra::infracost
int infracost
Definition packets_gen.h:1299
packet_ruleset_extra::native_to
bv_unit_classes native_to
Definition packets_gen.h:1302
packet_ruleset_extra::appearance_reqs_count
int appearance_reqs_count
Definition packets_gen.h:1287
packet_ruleset_extra::build_time_factor
int build_time_factor
Definition packets_gen.h:1296
packet_ruleset_extra::rmact_gfx_alt2
char rmact_gfx_alt2[MAX_LEN_NAME]
Definition packets_gen.h:1279
packet_ruleset_extra::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1283
packet_ruleset_extra::generated
bool generated
Definition packets_gen.h:1294
packet_ruleset_extra::disappearance_reqs_count
int disappearance_reqs_count
Definition packets_gen.h:1290
packet_ruleset_extra::appearance_chance
int appearance_chance
Definition packets_gen.h:1286
packet_ruleset_extra::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1281
packet_ruleset_extra::rmcauses
bv_rmcauses rmcauses
Definition packets_gen.h:1273
packet_ruleset_extra::act_gfx_alt2
char act_gfx_alt2[MAX_LEN_NAME]
Definition packets_gen.h:1276
packet_ruleset_extra::removal_time_factor
int removal_time_factor
Definition packets_gen.h:1298
packet_ruleset_extra::reqs_count
int reqs_count
Definition packets_gen.h:1282
packet_ruleset_extra::buildable
bool buildable
Definition packets_gen.h:1293
packet_ruleset_extra::disappearance_reqs
struct requirement disappearance_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1291
packet_ruleset_extra::flags
bv_extra_flags flags
Definition packets_gen.h:1303
packet_ruleset_extra::act_gfx_alt
char act_gfx_alt[MAX_LEN_NAME]
Definition packets_gen.h:1275
packet_ruleset_extra::hidden_by
bv_extras hidden_by
Definition packets_gen.h:1304
packet_ruleset_extra::activity_gfx
char activity_gfx[MAX_LEN_NAME]
Definition packets_gen.h:1274
packet_ruleset_extra::build_time
int build_time
Definition packets_gen.h:1295
packet_ruleset_extra::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1270
packet_ruleset_extra::eus
enum extra_unit_seen_type eus
Definition packets_gen.h:1301
packet_ruleset_extra::appearance_reqs
struct requirement appearance_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1288
packet_ruleset_extra::category
int category
Definition packets_gen.h:1271
packet_ruleset_extra::disappearance_chance
int disappearance_chance
Definition packets_gen.h:1289
packet_ruleset_extra::rmreqs_count
int rmreqs_count
Definition packets_gen.h:1284
packet_ruleset_extra::bridged_over
bv_extras bridged_over
Definition packets_gen.h:1305
packet_ruleset_extra::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1269
packet_ruleset_extra::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1280
packet_ruleset_extra::no_aggr_near_city
int no_aggr_near_city
Definition packets_gen.h:1307
packet_ruleset_extra::rmact_gfx_alt
char rmact_gfx_alt[MAX_LEN_NAME]
Definition packets_gen.h:1278
packet_ruleset_extra::rmact_gfx
char rmact_gfx[MAX_LEN_NAME]
Definition packets_gen.h:1277
packet_ruleset_extra::helptext
struct strvec * helptext
Definition packets_gen.h:1308
packet_ruleset_extra::conflicts
bv_extras conflicts
Definition packets_gen.h:1306
packet_ruleset_extra::rmreqs
struct requirement rmreqs[MAX_NUM_REQS]
Definition packets_gen.h:1285
packet_ruleset_extra::visibility_req
int visibility_req
Definition packets_gen.h:1292
packet_ruleset_extra::causes
bv_causes causes
Definition packets_gen.h:1272
packet_ruleset_game
Definition packets_gen.h:1022
packet_ruleset_goods
Definition packets_gen.h:1341
packet_ruleset_goods::helptext
struct strvec * helptext
Definition packets_gen.h:1351
packet_ruleset_goods::flags
bv_goods_flags flags
Definition packets_gen.h:1350
packet_ruleset_goods::from_pct
int from_pct
Definition packets_gen.h:1347
packet_ruleset_goods::onetime_pct
int onetime_pct
Definition packets_gen.h:1349
packet_ruleset_goods::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1343
packet_ruleset_goods::reqs_count
int reqs_count
Definition packets_gen.h:1345
packet_ruleset_goods::to_pct
int to_pct
Definition packets_gen.h:1348
packet_ruleset_goods::id
int id
Definition packets_gen.h:1342
packet_ruleset_goods::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1344
packet_ruleset_goods::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1346
packet_ruleset_government_ruler_title
Definition packets_gen.h:1051
packet_ruleset_government_ruler_title::gov
Government_type_id gov
Definition packets_gen.h:1052
packet_ruleset_government
Definition packets_gen.h:1088
packet_ruleset_impr_flag
Definition packets_gen.h:1204
packet_ruleset_impr_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1207
packet_ruleset_impr_flag::id
int id
Definition packets_gen.h:1205
packet_ruleset_multiplier
Definition packets_gen.h:1430
packet_ruleset_multiplier::stop
int stop
Definition packets_gen.h:1433
packet_ruleset_multiplier::step
int step
Definition packets_gen.h:1434
packet_ruleset_multiplier::helptext
struct strvec * helptext
Definition packets_gen.h:1443
packet_ruleset_multiplier::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1439
packet_ruleset_multiplier::id
Multiplier_type_id id
Definition packets_gen.h:1431
packet_ruleset_multiplier::offset
int offset
Definition packets_gen.h:1436
packet_ruleset_multiplier::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1442
packet_ruleset_multiplier::def
int def
Definition packets_gen.h:1435
packet_ruleset_multiplier::start
int start
Definition packets_gen.h:1432
packet_ruleset_multiplier::minimum_turns
int minimum_turns
Definition packets_gen.h:1438
packet_ruleset_multiplier::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1440
packet_ruleset_multiplier::factor
int factor
Definition packets_gen.h:1437
packet_ruleset_multiplier::reqs_count
int reqs_count
Definition packets_gen.h:1441
packet_ruleset_music
Definition packets_gen.h:1422
packet_ruleset_music::music_combat
char music_combat[MAX_LEN_NAME]
Definition packets_gen.h:1425
packet_ruleset_music::id
int id
Definition packets_gen.h:1423
packet_ruleset_music::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1427
packet_ruleset_music::reqs_count
int reqs_count
Definition packets_gen.h:1426
packet_ruleset_music::music_peaceful
char music_peaceful[MAX_LEN_NAME]
Definition packets_gen.h:1424
packet_ruleset_nation_groups
Definition packets_gen.h:1125
packet_ruleset_nation_sets
Definition packets_gen.h:1118
packet_ruleset_nation
Definition packets_gen.h:1131
packet_ruleset_nation::ngroups
int ngroups
Definition packets_gen.h:1148
packet_ruleset_nation::init_techs
int init_techs[MAX_NUM_TECH_LIST]
Definition packets_gen.h:1152
packet_ruleset_nation::leader_name
char leader_name[MAX_NUM_LEADERS][MAX_LEN_NAME]
Definition packets_gen.h:1142
packet_ruleset_nation::style
int style
Definition packets_gen.h:1140
packet_ruleset_nation::is_playable
bool is_playable
Definition packets_gen.h:1144
packet_ruleset_nation::id
Nation_type_id id
Definition packets_gen.h:1132
packet_ruleset_nation::noun_plural
char noun_plural[MAX_LEN_NAME]
Definition packets_gen.h:1136
packet_ruleset_nation::init_units_count
int init_units_count
Definition packets_gen.h:1153
packet_ruleset_nation::adjective
char adjective[MAX_LEN_NAME]
Definition packets_gen.h:1134
packet_ruleset_nation::init_buildings
Impr_type_id init_buildings[MAX_NUM_BUILDING_LIST]
Definition packets_gen.h:1156
packet_ruleset_nation::init_units
Unit_type_id init_units[MAX_NUM_UNIT_LIST]
Definition packets_gen.h:1154
packet_ruleset_nation::init_techs_count
int init_techs_count
Definition packets_gen.h:1151
packet_ruleset_nation::leader_is_male
bool leader_is_male[MAX_NUM_LEADERS]
Definition packets_gen.h:1143
packet_ruleset_nation::translation_domain
char translation_domain[MAX_LEN_NAME]
Definition packets_gen.h:1133
packet_ruleset_nation::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1137
packet_ruleset_nation::init_government_id
Government_type_id init_government_id
Definition packets_gen.h:1150
packet_ruleset_nation::leader_count
int leader_count
Definition packets_gen.h:1141
packet_ruleset_nation::groups
int groups[MAX_NUM_NATION_GROUPS]
Definition packets_gen.h:1149
packet_ruleset_nation::barbarian_type
enum barbarian_type barbarian_type
Definition packets_gen.h:1145
packet_ruleset_nation::sets
int sets[MAX_NUM_NATION_SETS]
Definition packets_gen.h:1147
packet_ruleset_nation::init_buildings_count
int init_buildings_count
Definition packets_gen.h:1155
packet_ruleset_nation::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1138
packet_ruleset_nation::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1135
packet_ruleset_nation::legend
char legend[MAX_LEN_MSG]
Definition packets_gen.h:1139
packet_ruleset_nation::nsets
int nsets
Definition packets_gen.h:1146
packet_ruleset_resource
Definition packets_gen.h:1607
packet_ruleset_resource::id
int id
Definition packets_gen.h:1608
packet_ruleset_resource::output
int output[O_LAST]
Definition packets_gen.h:1609
packet_ruleset_road
Definition packets_gen.h:1326
packet_ruleset_road::flags
bv_road_flags flags
Definition packets_gen.h:1338
packet_ruleset_road::tile_incr_const
int tile_incr_const[O_LAST]
Definition packets_gen.h:1333
packet_ruleset_road::gui_type
enum road_gui_type gui_type
Definition packets_gen.h:1328
packet_ruleset_road::integrates
bv_max_extras integrates
Definition packets_gen.h:1337
packet_ruleset_road::move_cost
int move_cost
Definition packets_gen.h:1331
packet_ruleset_road::compat
enum road_compat compat
Definition packets_gen.h:1336
packet_ruleset_road::move_mode
enum road_move_mode move_mode
Definition packets_gen.h:1332
packet_ruleset_road::first_reqs_count
int first_reqs_count
Definition packets_gen.h:1329
packet_ruleset_road::tile_bonus
int tile_bonus[O_LAST]
Definition packets_gen.h:1335
packet_ruleset_road::tile_incr
int tile_incr[O_LAST]
Definition packets_gen.h:1334
packet_ruleset_road::id
int id
Definition packets_gen.h:1327
packet_ruleset_road::first_reqs
struct requirement first_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1330
packet_ruleset_specialist
Definition packets_gen.h:1039
packet_ruleset_specialist::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1042
packet_ruleset_specialist::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1045
packet_ruleset_specialist::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1047
packet_ruleset_specialist::id
Specialist_type_id id
Definition packets_gen.h:1040
packet_ruleset_specialist::reqs_count
int reqs_count
Definition packets_gen.h:1046
packet_ruleset_specialist::short_name
char short_name[MAX_LEN_NAME]
Definition packets_gen.h:1043
packet_ruleset_specialist::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1044
packet_ruleset_specialist::plural_name
char plural_name[MAX_LEN_NAME]
Definition packets_gen.h:1041
packet_ruleset_specialist::helptext
struct strvec * helptext
Definition packets_gen.h:1048
packet_ruleset_style
Definition packets_gen.h:1165
packet_ruleset_style::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1167
packet_ruleset_style::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1168
packet_ruleset_style::id
int id
Definition packets_gen.h:1166
packet_ruleset_summary
Definition packets_gen.h:1491
packet_ruleset_summary::text
char text[MAX_LEN_CONTENT]
Definition packets_gen.h:1492
packet_ruleset_tech_class
Definition packets_gen.h:1075
packet_ruleset_tech_class::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1077
packet_ruleset_tech_class::id
int id
Definition packets_gen.h:1076
packet_ruleset_tech_class::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1078
packet_ruleset_tech_class::cost_pct
int cost_pct
Definition packets_gen.h:1079
packet_ruleset_tech_flag
Definition packets_gen.h:1082
packet_ruleset_tech_flag::id
int id
Definition packets_gen.h:1083
packet_ruleset_tech_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1085
packet_ruleset_tech
Definition packets_gen.h:1058
packet_ruleset_tech::research_reqs_count
int research_reqs_count
Definition packets_gen.h:1061
packet_ruleset_tech::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1068
packet_ruleset_tech::removed
bool removed
Definition packets_gen.h:1064
packet_ruleset_tech::research_reqs
struct requirement research_reqs[MAX_NUM_REQS]
Definition packets_gen.h:1062
packet_ruleset_tech::id
int id
Definition packets_gen.h:1059
packet_ruleset_tech::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1071
packet_ruleset_tech::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1069
packet_ruleset_tech::num_reqs
int num_reqs
Definition packets_gen.h:1067
packet_ruleset_tech::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1072
packet_ruleset_tech::flags
bv_tech_flags flags
Definition packets_gen.h:1065
packet_ruleset_tech::helptext
struct strvec * helptext
Definition packets_gen.h:1070
packet_ruleset_tech::tclass
int tclass
Definition packets_gen.h:1063
packet_ruleset_tech::root_req
int root_req
Definition packets_gen.h:1060
packet_ruleset_tech::cost
float cost
Definition packets_gen.h:1066
packet_ruleset_terrain_flag
Definition packets_gen.h:1250
packet_ruleset_terrain_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1253
packet_ruleset_terrain
Definition packets_gen.h:1210
packet_ruleset_terrain::extra_removal_times
int extra_removal_times[MAX_EXTRA_TYPES]
Definition packets_gen.h:1243
packet_ruleset_terrain::cultivate_time
int cultivate_time
Definition packets_gen.h:1230
packet_ruleset_terrain::irrigation_food_incr
int irrigation_food_incr
Definition packets_gen.h:1233
packet_ruleset_terrain::base_time
int base_time
Definition packets_gen.h:1227
packet_ruleset_terrain::transform_result
Terrain_type_id transform_result
Definition packets_gen.h:1238
packet_ruleset_terrain::tclass
int tclass
Definition packets_gen.h:1212
packet_ruleset_terrain::extra_count
int extra_count
Definition packets_gen.h:1242
packet_ruleset_terrain::mining_shield_incr
int mining_shield_incr
Definition packets_gen.h:1235
packet_ruleset_terrain::resource_freq
int resource_freq[MAX_EXTRA_TYPES]
Definition packets_gen.h:1225
packet_ruleset_terrain::resources
Resource_type_id resources[MAX_EXTRA_TYPES]
Definition packets_gen.h:1224
packet_ruleset_terrain::irrigation_time
int irrigation_time
Definition packets_gen.h:1234
packet_ruleset_terrain::placing_time
int placing_time
Definition packets_gen.h:1240
packet_ruleset_terrain::flags
bv_terrain_flags flags
Definition packets_gen.h:1213
packet_ruleset_terrain::transform_time
int transform_time
Definition packets_gen.h:1239
packet_ruleset_terrain::defense_bonus
int defense_bonus
Definition packets_gen.h:1221
packet_ruleset_terrain::plant_time
int plant_time
Definition packets_gen.h:1232
packet_ruleset_terrain::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:1217
packet_ruleset_terrain::num_resources
int num_resources
Definition packets_gen.h:1223
packet_ruleset_terrain::output
int output[O_LAST]
Definition packets_gen.h:1222
packet_ruleset_terrain::animal
int animal
Definition packets_gen.h:1237
packet_ruleset_terrain::color_red
int color_red
Definition packets_gen.h:1244
packet_ruleset_terrain::helptext
struct strvec * helptext
Definition packets_gen.h:1247
packet_ruleset_terrain::native_to
bv_unit_classes native_to
Definition packets_gen.h:1214
packet_ruleset_terrain::pillage_time
int pillage_time
Definition packets_gen.h:1241
packet_ruleset_terrain::cultivate_result
Terrain_type_id cultivate_result
Definition packets_gen.h:1229
packet_ruleset_terrain::color_green
int color_green
Definition packets_gen.h:1245
packet_ruleset_terrain::road_time
int road_time
Definition packets_gen.h:1228
packet_ruleset_terrain::plant_result
Terrain_type_id plant_result
Definition packets_gen.h:1231
packet_ruleset_terrain::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1215
packet_ruleset_terrain::road_output_incr_pct
int road_output_incr_pct[O_LAST]
Definition packets_gen.h:1226
packet_ruleset_terrain::movement_cost
int movement_cost
Definition packets_gen.h:1220
packet_ruleset_terrain::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:1218
packet_ruleset_terrain::graphic_alt2
char graphic_alt2[MAX_LEN_NAME]
Definition packets_gen.h:1219
packet_ruleset_terrain::mining_time
int mining_time
Definition packets_gen.h:1236
packet_ruleset_terrain::id
Terrain_type_id id
Definition packets_gen.h:1211
packet_ruleset_terrain::color_blue
int color_blue
Definition packets_gen.h:1246
packet_ruleset_terrain::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1216
packet_ruleset_trade
Definition packets_gen.h:1373
packet_ruleset_trade::cancelling
enum trade_route_illegal_cancelling cancelling
Definition packets_gen.h:1376
packet_ruleset_trade::trade_pct
int trade_pct
Definition packets_gen.h:1375
packet_ruleset_trade::id
int id
Definition packets_gen.h:1374
packet_ruleset_trade::bonus_type
enum trade_route_bonus_type bonus_type
Definition packets_gen.h:1377
packet_ruleset_unit_bonus
Definition packets_gen.h:1002
packet_ruleset_unit_bonus::unit
Unit_type_id unit
Definition packets_gen.h:1003
packet_ruleset_unit_class_flag
Definition packets_gen.h:1016
packet_ruleset_unit_class_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1019
packet_ruleset_unit_class_flag::id
int id
Definition packets_gen.h:1017
packet_ruleset_unit_class
Definition packets_gen.h:1256
packet_ruleset_unit_class::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:1259
packet_ruleset_unit_class::helptext
struct strvec * helptext
Definition packets_gen.h:1264
packet_ruleset_unit_class::flags
bv_unit_class_flags flags
Definition packets_gen.h:1263
packet_ruleset_unit_class::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1258
packet_ruleset_unit_class::non_native_def_pct
int non_native_def_pct
Definition packets_gen.h:1262
packet_ruleset_unit_class::hp_loss_pct
int hp_loss_pct
Definition packets_gen.h:1261
packet_ruleset_unit_class::id
int id
Definition packets_gen.h:1257
packet_ruleset_unit_class::min_speed
int min_speed
Definition packets_gen.h:1260
packet_ruleset_unit_flag
Definition packets_gen.h:1010
packet_ruleset_unit_flag::id
int id
Definition packets_gen.h:1011
packet_ruleset_unit_flag::helptxt
char helptxt[MAX_LEN_PACKET]
Definition packets_gen.h:1013
packet_ruleset_unit
Definition packets_gen.h:951
packet_ruleset_unit::paratroopers_range
int paratroopers_range
Definition packets_gen.h:980
packet_ruleset_unit::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition packets_gen.h:956
packet_ruleset_unit::vlayer
enum vision_layer vlayer
Definition packets_gen.h:995
packet_ruleset_unit::tp_defense
enum transp_def_type tp_defense
Definition packets_gen.h:990
packet_ruleset_unit::unit_class_id
int unit_class_id
Definition packets_gen.h:962
packet_ruleset_unit::rule_name
char rule_name[MAX_LEN_NAME]
Definition packets_gen.h:954
packet_ruleset_unit::vision_radius_sq
int vision_radius_sq
Definition packets_gen.h:970
packet_ruleset_unit::obsoleted_by
int obsoleted_by
Definition packets_gen.h:974
packet_ruleset_unit::upkeep
int upkeep[O_LAST]
Definition packets_gen.h:979
packet_ruleset_unit::power_fact
int power_fact[MAX_VET_LEVELS]
Definition packets_gen.h:983
packet_ruleset_unit::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:953
packet_ruleset_unit::hp
int hp
Definition packets_gen.h:972
packet_ruleset_unit::pop_cost
int pop_cost
Definition packets_gen.h:964
packet_ruleset_unit::city_slots
int city_slots
Definition packets_gen.h:989
packet_ruleset_unit::graphic_alt2
char graphic_alt2[MAX_LEN_NAME]
Definition packets_gen.h:957
packet_ruleset_unit::firepower
int firepower
Definition packets_gen.h:973
packet_ruleset_unit::fuel
int fuel
Definition packets_gen.h:977
packet_ruleset_unit::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition packets_gen.h:955
packet_ruleset_unit::convert_time
int convert_time
Definition packets_gen.h:976
packet_ruleset_unit::helptext
struct strvec * helptext
Definition packets_gen.h:996
packet_ruleset_unit::sound_fight_alt
char sound_fight_alt[MAX_LEN_NAME]
Definition packets_gen.h:961
packet_ruleset_unit::disembarks
bv_unit_classes disembarks
Definition packets_gen.h:994
packet_ruleset_unit::veteran_levels
int veteran_levels
Definition packets_gen.h:981
packet_ruleset_unit::move_rate
int move_rate
Definition packets_gen.h:967
packet_ruleset_unit::attack_strength
int attack_strength
Definition packets_gen.h:965
packet_ruleset_unit::cargo
bv_unit_classes cargo
Definition packets_gen.h:991
packet_ruleset_unit::build_cost
int build_cost
Definition packets_gen.h:963
packet_ruleset_unit::transport_capacity
int transport_capacity
Definition packets_gen.h:971
packet_ruleset_unit::flags
bv_unit_type_flags flags
Definition packets_gen.h:997
packet_ruleset_unit::sound_move_alt
char sound_move_alt[MAX_LEN_NAME]
Definition packets_gen.h:959
packet_ruleset_unit::happy_cost
int happy_cost
Definition packets_gen.h:978
packet_ruleset_unit::worker
bool worker
Definition packets_gen.h:999
packet_ruleset_unit::targets
bv_unit_classes targets
Definition packets_gen.h:992
packet_ruleset_unit::defense_strength
int defense_strength
Definition packets_gen.h:966
packet_ruleset_unit::build_reqs
struct requirement build_reqs[MAX_NUM_REQS]
Definition packets_gen.h:969
packet_ruleset_unit::base_raise_chance
int base_raise_chance[MAX_VET_LEVELS]
Definition packets_gen.h:985
packet_ruleset_unit::work_raise_chance
int work_raise_chance[MAX_VET_LEVELS]
Definition packets_gen.h:986
packet_ruleset_unit::sound_fight
char sound_fight[MAX_LEN_NAME]
Definition packets_gen.h:960
packet_ruleset_unit::embarks
bv_unit_classes embarks
Definition packets_gen.h:993
packet_ruleset_unit::build_reqs_count
int build_reqs_count
Definition packets_gen.h:968
packet_ruleset_unit::city_size
int city_size
Definition packets_gen.h:988
packet_ruleset_unit::bombard_rate
int bombard_rate
Definition packets_gen.h:987
packet_ruleset_unit::veteran_name
char veteran_name[MAX_VET_LEVELS][MAX_LEN_NAME]
Definition packets_gen.h:982
packet_ruleset_unit::converted_to
int converted_to
Definition packets_gen.h:975
packet_ruleset_unit::sound_move
char sound_move[MAX_LEN_NAME]
Definition packets_gen.h:958
packet_ruleset_unit::roles
bv_unit_type_roles roles
Definition packets_gen.h:998
packet_ruleset_unit::id
Unit_type_id id
Definition packets_gen.h:952
packet_ruleset_unit::move_bonus
int move_bonus[MAX_VET_LEVELS]
Definition packets_gen.h:984
packet_team_name_info
Definition packets_gen.h:287
packet_web_ruleset_unit_addition
Definition packets_gen.h:1897
part
Definition goto.c:52
range
Definition unittype.c:879
req_vec_problem
Definition requirements.h:295
requirement
Definition requirements.h:81
requirement::quiet
bool quiet
Definition requirements.h:86
requirement::survives
bool survives
Definition requirements.h:84
requirement::present
bool present
Definition requirements.h:85
requirement::source
struct universal source
Definition requirements.h:82
rgbcolor
Definition rgbcolor.h:33
rgbcolor::g
int g
Definition rgbcolor.h:34
rgbcolor::b
int b
Definition rgbcolor.h:34
rgbcolor::r
int r
Definition rgbcolor.h:34
road_type
Definition road.h:71
road_type::gui_type
enum road_gui_type gui_type
Definition road.h:80
road_type::first_reqs
struct requirement_vector first_reqs
Definition road.h:82
road_type::move_mode
enum road_move_mode move_mode
Definition road.h:75
road_type::tile_bonus
int tile_bonus[O_LAST]
Definition road.h:78
road_type::tile_incr_const
int tile_incr_const[O_LAST]
Definition road.h:76
road_type::tile_incr
int tile_incr[O_LAST]
Definition road.h:77
road_type::flags
bv_road_flags flags
Definition road.h:85
road_type::move_cost
int move_cost
Definition road.h:74
road_type::compat
enum road_compat compat
Definition road.h:79
road_type::integrates
bv_max_extras integrates
Definition road.h:84
rscompat_info
Definition rscompat.h:30
rscompat_info::compat_mode
bool compat_mode
Definition rscompat.h:31
section_file
Definition section_file.h:36
section
Definition section_file.h:28
server
Definition servers.h:29
specialist
Definition specialist.h:29
specialist::reqs
struct requirement_vector reqs
Definition specialist.h:38
specialist::graphic_alt
char graphic_alt[MAX_LEN_NAME]
Definition specialist.h:36
specialist::helptext
struct strvec * helptext
Definition specialist.h:40
specialist::graphic_str
char graphic_str[MAX_LEN_NAME]
Definition specialist.h:35
specialist::name
struct name_translation name
Definition specialist.h:31
specialist::abbreviation
struct name_translation abbreviation
Definition specialist.h:32
strvec
Definition string_vector.c:29
strvec::vec
char ** vec
Definition string_vector.c:30
terrain
Definition terrain.h:75
trade_route_settings
Definition traderoutes.h:75
trade_route_settings::bonus_type
enum trade_route_bonus_type bonus_type
Definition traderoutes.h:78
trade_route_settings::trade_pct
int trade_pct
Definition traderoutes.h:76
trade_route_settings::cancelling
enum trade_route_illegal_cancelling cancelling
Definition traderoutes.h:77
trait_limits
Definition traits.h:43
trait_limits::fixed
int fixed
Definition traits.h:46
trait_limits::min
int min
Definition traits.h:44
trait_limits::max
int max
Definition traits.h:45
unit_class
Definition unittype.h:149
unit_type
Definition unittype.h:507
universal::kind
enum universals_n kind
Definition fc_types.h:910
veteran_level
Definition unittype.h:493
veteran_system
Definition unittype.h:501
veteran_system::definitions
struct veteran_level * definitions
Definition unittype.h:504
veteran_system::levels
int levels
Definition unittype.h:502
world::map
struct civ_map map
Definition world_object.h:38
style_by_rule_name
struct nation_style * style_by_rule_name(const char *name)
Definition style.c:117
style_by_number
struct nation_style * style_by_number(int id)
Definition style.c:88
styles_alloc
void styles_alloc(int count)
Definition style.c:36
music_style_by_number
struct music_style * music_style_by_number(int id)
Definition style.c:171
style_number
int style_number(const struct nation_style *pstyle)
Definition style.c:68
music_styles_alloc
void music_styles_alloc(int count)
Definition style.c:133
style_index
int style_index(const struct nation_style *pstyle)
Definition style.c:78
style.h
music_styles_iterate
#define music_styles_iterate(_p)
Definition style.h:72
music_styles_iterate_end
#define music_styles_iterate_end
Definition style.h:79
styles_iterate
#define styles_iterate(_p)
Definition style.h:46
styles_iterate_end
#define styles_iterate_end
Definition style.h:52
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
fc_isspace
bool fc_isspace(char c)
Definition support.c:1240
fc_strlcat
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:822
fc_vsnprintf
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
fc_tolower
char fc_tolower(char c)
Definition support.c:1273
support.h
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:189
RETURN_VALUE_AFTER_EXIT
#define RETURN_VALUE_AFTER_EXIT(_val_)
Definition support.h:146
fc__attribute
#define fc__attribute(x)
Definition support.h:99
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
team_slot_by_number
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:175
team_slot_defined_name
const char * team_slot_defined_name(const struct team_slot *tslot)
Definition team.c:277
team_slot_index
int team_slot_index(const struct team_slot *tslot)
Definition team.c:138
team_slot_count
int team_slot_count(void)
Definition team.c:112
team_slot_set_defined_name
void team_slot_set_defined_name(struct team_slot *tslot, const char *team_name)
Definition team.c:288
team_slots_iterate_end
#define team_slots_iterate_end
Definition team.h:77
team_slots_iterate
#define team_slots_iterate(_tslot)
Definition team.h:72
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
tech_flag_id_name_cb
const char * tech_flag_id_name_cb(enum tech_flag_id flag)
Definition tech.c:433
set_user_tech_flag_name
void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt)
Definition tech.c:404
valid_advance
struct advance * valid_advance(struct advance *padvance)
Definition tech.c:152
techs_precalc_data
void techs_precalc_data(void)
Definition tech.c:225
advance_rule_name
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:309
tech_flag_helptxt
const char * tech_flag_helptxt(enum tech_flag_id id)
Definition tech.c:445
advance_by_rule_name
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:200
tech_class_by_rule_name
struct tech_class * tech_class_by_rule_name(const char *name)
Definition tech.c:361
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
tech.h
tech_class_index
#define tech_class_index(_ptclass_)
Definition tech.h:193
A_NEVER
#define A_NEVER
Definition tech.h:51
tech_class_iterate_end
#define tech_class_iterate_end
Definition tech.h:204
MAX_NUM_USER_TECH_FLAGS
#define MAX_NUM_USER_TECH_FLAGS
Definition tech.h:108
advance_iterate_all_end
#define advance_iterate_all_end
Definition tech.h:280
AR_TWO
@ AR_TWO
Definition tech.h:112
AR_ROOT
@ AR_ROOT
Definition tech.h:113
AR_ONE
@ AR_ONE
Definition tech.h:111
advance_iterate_all
#define advance_iterate_all(_p)
Definition tech.h:279
advance_count
static Tech_type_id advance_count(void)
Definition tech.h:170
A_FIRST
#define A_FIRST
Definition tech.h:44
A_NONE
#define A_NONE
Definition tech.h:43
advance_iterate
#define advance_iterate(_p)
Definition tech.h:276
tech_class_iterate
#define tech_class_iterate(_p)
Definition tech.h:198
advance_iterate_end
#define advance_iterate_end
Definition tech.h:277
A_LAST
#define A_LAST
Definition tech.h:45
terrain_by_rule_name
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:186
terrain_count
Terrain_type_id terrain_count(void)
Definition terrain.c:118
terrain_flag_id_name_cb
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:817
terrain_index
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
terrain_by_number
struct terrain * terrain_by_number(const Terrain_type_id type)
Definition terrain.c:156
terrain_flag_helptxt
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Definition terrain.c:829
resource_type_init
struct resource_type * resource_type_init(struct extra_type *pextra)
Definition terrain.c:272
set_user_terrain_flag_name
void set_user_terrain_flag_name(enum terrain_flag_id id, const char *name, const char *helptxt)
Definition terrain.c:788
terrain_number
Terrain_type_id terrain_number(const struct terrain *pterrain)
Definition terrain.c:147
RESOURCE_FREQUENCY_MAXIMUM
#define RESOURCE_FREQUENCY_MAXIMUM
Definition terrain.h:102
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:266
T_NONE
#define T_NONE
Definition terrain.h:61
TERRAIN_UNKNOWN_IDENTIFIER
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:88
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:272
RESOURCE_NONE_IDENTIFIER
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:52
RESOURCE_NULL_IDENTIFIER
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:51
RESOURCE_FREQUENCY_MINIMUM
#define RESOURCE_FREQUENCY_MINIMUM
Definition terrain.h:100
MAX_NUM_TERRAINS
#define MAX_NUM_TERRAINS
Definition terrain.h:69
T_FIRST
#define T_FIRST
Definition terrain.h:65
MAX_NUM_USER_TER_FLAGS
#define MAX_NUM_USER_TER_FLAGS
Definition terrain.h:32
terrain_resources_iterate_end
#define terrain_resources_iterate_end
Definition terrain.h:294
terrain_resources_iterate
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:285
RESOURCE_FREQUENCY_DEFAULT
#define RESOURCE_FREQUENCY_DEFAULT
Definition terrain.h:101
ACTIVITY_FACTOR
#define ACTIVITY_FACTOR
Definition tile.h:166
goods_number
Goods_type_id goods_number(const struct goods_type *pgood)
Definition traderoutes.c:592
trade_route_cancelling_type_by_name
enum trade_route_illegal_cancelling trade_route_cancelling_type_by_name(const char *name)
Definition traderoutes.c:184
trade_route_settings_by_type
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Definition traderoutes.c:201
goods_rule_name
const char * goods_rule_name(struct goods_type *pgood)
Definition traderoutes.c:633
goods_index
Goods_type_id goods_index(const struct goods_type *pgood)
Definition traderoutes.c:605
trade_route_type_by_name
enum trade_route_type trade_route_type_by_name(const char *name)
Definition traderoutes.c:158
traderoutes.h
goods_type_iterate_end
#define goods_type_iterate_end
Definition traderoutes.h:236
TRI_LAST
@ TRI_LAST
Definition traderoutes.h:33
goods_type_iterate
#define goods_type_iterate(_p)
Definition traderoutes.h:230
trade_route_type
trade_route_type
Definition traderoutes.h:37
TRT_NATIONAL
@ TRT_NATIONAL
Definition traderoutes.h:38
TRT_LAST
@ TRT_LAST
Definition traderoutes.h:48
TRAIT_DEFAULT_VALUE
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
unit.h
set_unit_class_caches
void set_unit_class_caches(struct unit_class *pclass)
Definition unittype.c:2742
unit_class_flag_helptxt
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1854
unit_type_by_rule_name
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1767
utype_has_role
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:199
unit_type_action_cache_init
void unit_type_action_cache_init(void)
Definition unittype.c:931
set_unit_type_caches
void set_unit_type_caches(struct unit_type *ptype)
Definition unittype.c:2801
role_unit_precalcs
void role_unit_precalcs(void)
Definition unittype.c:2175
veteran_system_definition
void veteran_system_definition(struct veteran_system *vsystem, int level, const char *vlist_name, int vlist_power, int vlist_move, int vlist_raise, int vlist_wraise)
Definition unittype.c:2671
utype_count
Unit_type_id utype_count(void)
Definition unittype.c:80
utype_veteran_levels
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2613
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
utype_veteran_level
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2583
uclass_rule_name
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1641
utype_number
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
unit_class_by_rule_name
struct unit_class * unit_class_by_rule_name(const char *s)
Definition unittype.c:1784
unit_type_flag_helptxt
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1917
utype_index
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
set_user_unit_class_flag_name
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1812
veteran_system_new
struct veteran_system * veteran_system_new(int count)
Definition unittype.c:2640
uclass_number
Unit_Class_id uclass_number(const struct unit_class *pclass)
Definition unittype.c:2467
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
set_user_unit_type_flag_name
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1876
unittype.h
uclass_has_flag
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
utype_class
#define utype_class(_t_)
Definition unittype.h:756
combat_bonus_list_iterate_end
#define combat_bonus_list_iterate_end
Definition unittype.h:489
L_FIRST
#define L_FIRST
Definition unittype.h:356
combat_bonus_list_iterate
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:487
unit_tech_reqs_iterate_end
#define unit_tech_reqs_iterate_end
Definition unittype.h:885
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:912
unit_tech_reqs_iterate
#define unit_tech_reqs_iterate(_utype_, _p)
Definition unittype.h:879
MAX_NUM_USER_UNIT_FLAGS
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:338
utype_has_flag
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
UTYF_LAST_USER_FLAG
#define UTYF_LAST_USER_FLAG
Definition unittype.h:337
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:859
U_LAST
#define U_LAST
Definition unittype.h:40
uclass_index
#define uclass_index(_c_)
Definition unittype.h:749
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:919
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:866
MAX_NUM_USER_UCLASS_FLAGS
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:128