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