Freeciv-3.2: /fast/freeciv/nightly/S3_2/tools/ruleutil/rulesave.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
rulesave.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "astring.h"
20#include "registry.h"
21#include "string_vector.h"
22
23/* common */
24#include "achievements.h"
25#include "counters.h"
26#include "game.h"
27#include "government.h"
28#include "map.h"
29#include "movement.h"
30#include "multipliers.h"
31#include "nation.h"
32#include "rgbcolor.h"
33#include "sex.h"
34#include "specialist.h"
35#include "style.h"
36#include "unittype.h"
37#include "version.h"
38
39/* server */
40#include "ruleset.h"
41#include "settings.h"
42
43/* tools/ruleutil */
44#include "comments.h"
45
46#include "rulesave.h"
47
48/* Ruleset format version */
49/*
50 * 1 - Freeciv-2.6
51 * 10 - Freeciv-3.0
52 * 20 - Freeciv-3.1
53 * 30 - Freeciv-3.2
54 */
55#define FORMAT_VERSION RSFORMAT_3_2
56
57/**********************************************************************/
60 static struct section_file *create_ruleset_file(const char *rsname,
61 const char *rstype)
62{
63 struct section_file *sfile = secfile_new(TRUE);
64 char buf[500];
65
66 comment_file_header(sfile);
67
68 if (rsname != NULL && rsname[0] != '\0') {
69 fc_snprintf(buf, sizeof(buf), "%s %s data for Freeciv", rsname, rstype);
70 } else {
71 fc_snprintf(buf, sizeof(buf), "Template %s data for Freeciv", rstype);
72 }
73
74 secfile_insert_str(sfile, buf, "datafile.description");
75 secfile_insert_str(sfile, freeciv_datafile_version(), "datafile.ruledit");
76 secfile_insert_str(sfile, RULESET_CAPABILITIES, "datafile.options");
77 secfile_insert_int(sfile, FORMAT_VERSION, "datafile.format_version");
78
79 return sfile;
80}
81
82/**********************************************************************/
85 static bool save_default_int(struct section_file *sfile, int value,
86 int default_value, const char *path,
87 const char *entry)
88{
89 if (value != default_value) {
90 if (entry != NULL) {
91 secfile_insert_int(sfile, value,
92 "%s.%s", path, entry);
93 } else {
94 secfile_insert_int(sfile, value,
95 "%s", path);
96 }
97 }
98
99 return TRUE;
100}
101
102/**********************************************************************/
105 static bool save_default_bool(struct section_file *sfile, bool value,
106 bool default_value, const char *path,
107 const char *entry)
108{
109 if ((value && !default_value)
110 || (!value && default_value)) {
111 if (entry != NULL) {
112 secfile_insert_bool(sfile, value,
113 "%s.%s", path, entry);
114 } else {
115 secfile_insert_bool(sfile, value,
116 "%s", path);
117 }
118 }
119
120 return TRUE;
121}
122
123/**********************************************************************/
126 static bool save_name_translation(struct section_file *sfile,
127 struct name_translation *name,
128 const char *path)
129{
130 struct entry *mod_entry;
131
132 mod_entry = secfile_insert_str(sfile,
133 untranslated_name(name),
134 "%s.name", path);
135 entry_str_set_gt_marking(mod_entry, TRUE);
136 if (strcmp(skip_intl_qualifier_prefix(untranslated_name(name)),
137 rule_name_get(name))) {
138 secfile_insert_str(sfile,
139 rule_name_get(name),
140 "%s.rule_name", path);
141 }
142
143 return TRUE;
144}
145
146/**********************************************************************/
149 static bool save_reqs_vector(struct section_file *sfile,
150 const struct requirement_vector *reqs,
151 const char *path, const char *entry)
152{
153 int i;
154 bool includes_negated = FALSE;
155 bool includes_surviving = FALSE;
156 bool includes_quiet = FALSE;
157
158 requirement_vector_iterate(reqs, preq) {
159 if (!preq->present) {
160 includes_negated = TRUE;
161 }
162 if (preq->survives) {
163 includes_surviving = TRUE;
164 }
165 if (preq->quiet) {
166 includes_quiet = TRUE;
167 }
168 } requirement_vector_iterate_end;
169
170 i = 0;
171 requirement_vector_iterate(reqs, preq) {
172 secfile_insert_str(sfile,
173 universals_n_name(preq->source.kind),
174 "%s.%s%d.type", path, entry, i);
175 secfile_insert_str(sfile,
176 universal_rule_name(&(preq->source)),
177 "%s.%s%d.name", path, entry, i);
178 secfile_insert_str(sfile,
179 req_range_name(preq->range),
180 "%s.%s%d.range", path, entry, i);
181
182 if (includes_surviving) {
183 secfile_insert_bool(sfile,
184 preq->survives,
185 "%s.%s%d.survives", path, entry, i);
186 }
187
188 if (includes_negated) {
189 secfile_insert_bool(sfile,
190 preq->present,
191 "%s.%s%d.present", path, entry, i);
192 }
193
194 if (includes_quiet) {
195 secfile_insert_bool(sfile,
196 preq->quiet,
197 "%s.%s%d.quiet", path, entry, i);
198 }
199
200 i++;
201 } requirement_vector_iterate_end;
202
203 return TRUE;
204}
205
206/**********************************************************************/
209 static bool save_tech_list(struct section_file *sfile, int *input,
210 const char *path, const char *entry)
211{
212 const char *tech_names[MAX_NUM_TECH_LIST];
213 int set_count;
214 int i;
215
216 set_count = 0;
217 for (i = 0; input[i] != A_LAST && i < MAX_NUM_TECH_LIST; i++) {
218 tech_names[set_count++] = advance_rule_name(advance_by_number(input[i]));
219 }
220
221 if (set_count > 0) {
222 secfile_insert_str_vec(sfile, tech_names, set_count,
223 "%s.%s", path, entry);
224 }
225
226 return TRUE;
227}
228
229/**********************************************************************/
232 static bool save_tech_ref(struct section_file *sfile,
233 const struct advance *padv,
234 const char *path, const char *entry)
235{
236 if (padv == A_NEVER) {
237 secfile_insert_str(sfile, "Never", "%s.%s", path, entry);
238 } else {
239 secfile_insert_str(sfile, advance_rule_name(padv),
240 "%s.%s", path, entry);
241 }
242
243 return TRUE;
244}
245
246/**********************************************************************/
249 static bool save_terrain_ref(struct section_file *sfile,
250 const struct terrain *save,
251 const struct terrain *pthis,
252 const char *path, const char *entry)
253{
254 if (save == NULL) {
255 secfile_insert_str(sfile, "none", "%s.%s", path, entry);
256 } else if (save == pthis) {
257 secfile_insert_str(sfile, "yes", "%s.%s", path, entry);
258 } else {
259 secfile_insert_str(sfile, terrain_rule_name(save),
260 "%s.%s", path, entry);
261 }
262
263 return TRUE;
264}
265
266/**********************************************************************/
269 static bool save_gov_ref(struct section_file *sfile,
270 const struct government *gov,
271 const char *path, const char *entry)
272{
273 secfile_insert_str(sfile, government_rule_name(gov), "%s.%s", path, entry);
274
275 return TRUE;
276}
277
278/**********************************************************************/
282 static bool save_building_list(struct section_file *sfile, int *input,
283 const char *path, const char *entry)
284{
285 const char *building_names[MAX_NUM_BUILDING_LIST];
286 int set_count;
287 int i;
288
289 set_count = 0;
290 for (i = 0; input[i] != B_LAST && i < MAX_NUM_BUILDING_LIST; i++) {
291 building_names[set_count++] = improvement_rule_name(improvement_by_number(input[i]));
292 }
293
294 if (set_count > 0) {
295 secfile_insert_str_vec(sfile, building_names, set_count,
296 "%s.%s", path, entry);
297 }
298
299 return TRUE;
300}
301
302/**********************************************************************/
306 static bool save_unit_list(struct section_file *sfile, struct unit_type **input,
307 const char *path, const char *entry)
308{
309 const char *unit_names[MAX_NUM_UNIT_LIST];
310 int set_count;
311 int i;
312
313 set_count = 0;
314 for (i = 0; input[i] != NULL && i < MAX_NUM_UNIT_LIST; i++) {
315 unit_names[set_count++] = utype_rule_name(input[i]);
316 }
317
318 if (set_count > 0) {
319 secfile_insert_str_vec(sfile, unit_names, set_count,
320 "%s.%s", path, entry);
321 }
322
323 return TRUE;
324}
325
326/**********************************************************************/
329 static bool save_uclass_vec(struct section_file *sfile,
330 bv_unit_classes *bits,
331 const char *path, const char *entry,
332 bool unreachable_only)
333{
334 const char *class_names[UCL_LAST];
335 int classes = 0;
336
337 unit_class_iterate(pcargo) {
338 if (BV_ISSET(*(bits), uclass_index(pcargo))
339 && (uclass_has_flag(pcargo, UCF_UNREACHABLE)
340 || !unreachable_only)) {
341 class_names[classes++] = uclass_rule_name(pcargo);
342 }
343 } unit_class_iterate_end;
344
345 if (classes > 0) {
346 secfile_insert_str_vec(sfile, class_names, classes,
347 "%s.%s", path, entry);
348 }
349
350 return TRUE;
351}
352
353/**********************************************************************/
356 static bool save_strvec(struct section_file *sfile,
357 struct strvec *to_save,
358 const char *path, const char *entry)
359{
360 if (to_save != NULL) {
361 int sect_count = strvec_size(to_save);
362 const char *sections[sect_count];
363 int i;
364
365 for (i = 0; i < sect_count; i++) {
366 sections[i] = strvec_get(to_save, i);
367 }
368
369 secfile_insert_str_vec(sfile, sections, sect_count, "%s.%s", path, entry);
370 }
371
372 return TRUE;
373}
374
375/**********************************************************************/
378 static bool save_ruleset_file(struct section_file *sfile, const char *filename)
379{
380 return secfile_save(sfile, filename, 0, FZ_PLAIN);
381}
382
383/**********************************************************************/
386 static bool save_buildings_ruleset(const char *filename, const char *name)
387{
388 struct section_file *sfile = create_ruleset_file(name, "building");
389 int sect_idx;
390 int i;
391 bool uflags_building = FALSE;
392
393 if (sfile == NULL) {
394 return FALSE;
395 }
396
397 for (i = 0; i < MAX_NUM_USER_BUILDING_FLAGS; i++) {
398 const char *flagname = impr_flag_id_name_cb(i + IF_USER_FLAG_1);
399 const char *helptxt = impr_flag_helptxt(i + IF_USER_FLAG_1);
400
401 if (flagname != NULL) {
402 if (!uflags_building) {
403 comment_uflags_building(sfile);
404 uflags_building = TRUE;
405 }
406
407 secfile_insert_str(sfile, flagname, "control.building_flags%d.name", i);
408
409 /* Save the user flag help text even when it is undefined. That makes
410 * the formatting code happy. The resulting "" is ignored when the
411 * ruleset is loaded. */
412 secfile_insert_str(sfile, helptxt,
413 "control.building_flags%d.helptxt", i);
414 }
415 }
416
417 comment_buildings(sfile);
418
419 sect_idx = 0;
420 improvement_re_active_iterate(pb) {
421 if (!pb->ruledit_disabled) {
422 char path[512];
423 const char *flag_names[IF_COUNT];
424 int set_count;
425 int flagi;
426
427 fc_snprintf(path, sizeof(path), "building_%d", sect_idx++);
428
429 save_name_translation(sfile, &(pb->name), path);
430
431 secfile_insert_str(sfile, impr_genus_id_name(pb->genus),
432 "%s.genus", path);
433
434 if (strcmp(pb->graphic_str, "-")) {
435 secfile_insert_str(sfile, pb->graphic_str, "%s.graphic", path);
436 }
437 if (strcmp(pb->graphic_alt, "-")) {
438 secfile_insert_str(sfile, pb->graphic_alt, "%s.graphic_alt", path);
439 }
440 if (strcmp(pb->graphic_alt2, "-")) {
441 secfile_insert_str(sfile, pb->graphic_alt2, "%s.graphic_alt2", path);
442 }
443 if (strcmp(pb->soundtag, "-")) {
444 secfile_insert_str(sfile, pb->soundtag, "%s.sound", path);
445 }
446 if (strcmp(pb->soundtag_alt, "-")) {
447 secfile_insert_str(sfile, pb->soundtag_alt, "%s.sound_alt", path);
448 }
449 if (strcmp(pb->soundtag_alt2, "-")) {
450 secfile_insert_str(sfile, pb->soundtag_alt2, "%s.sound_alt2", path);
451 }
452
453 save_reqs_vector(sfile, &(pb->reqs), path, "reqs");
454 save_reqs_vector(sfile, &(pb->obsolete_by), path, "obsolete_by");
455
456 secfile_insert_int(sfile, pb->build_cost, "%s.build_cost", path);
457 secfile_insert_int(sfile, pb->upkeep, "%s.upkeep", path);
458 secfile_insert_int(sfile, pb->sabotage, "%s.sabotage", path);
459
460 set_count = 0;
461 for (flagi = 0; flagi < IF_COUNT; flagi++) {
462 if (improvement_has_flag(pb, flagi)) {
463 flag_names[set_count++] = impr_flag_id_name(flagi);
464 }
465 }
466
467 if (set_count > 0) {
468 secfile_insert_str_vec(sfile, flag_names, set_count,
469 "%s.flags", path);
470 }
471
472 save_strvec(sfile, pb->helptext, path, "helptext");
473 }
474 } improvement_re_active_iterate_end;
475
476 return save_ruleset_file(sfile, filename);
477}
478
479/**********************************************************************/
482 static bool save_styles_ruleset(const char *filename, const char *name)
483{
484 struct section_file *sfile = create_ruleset_file(name, "styles");
485 int sect_idx;
486 int i;
487
488 if (sfile == NULL) {
489 return FALSE;
490 }
491
492 comment_styles(sfile);
493
494 sect_idx = 0;
495 styles_re_active_iterate(pstyle) {
496 char path[512];
497
498 fc_snprintf(path, sizeof(path), "style_%d", sect_idx++);
499
500 save_name_translation(sfile, &(pstyle->name), path);
501 } styles_re_active_iterate_end;
502
503 comment_citystyles(sfile);
504
505 sect_idx = 0;
506 for (i = 0; i < game.control.num_city_styles; i++) {
507 char path[512];
508
509 fc_snprintf(path, sizeof(path), "citystyle_%d", sect_idx++);
510
511 save_name_translation(sfile, &(city_styles[i].name), path);
512
513 secfile_insert_str(sfile, city_styles[i].graphic, "%s.graphic", path);
514 secfile_insert_str(sfile, city_styles[i].graphic_alt, "%s.graphic_alt", path);
515 if (strcmp(city_styles[i].citizens_graphic, "-")) {
516 secfile_insert_str(sfile, city_styles[i].citizens_graphic,
517 "%s.citizens_graphic", path);
518 }
519
520 save_reqs_vector(sfile, &(city_styles[i].reqs), path, "reqs");
521 }
522
523 comment_musicstyles(sfile);
524
525 sect_idx = 0;
526 music_styles_iterate(pmus) {
527 char path[512];
528
529 fc_snprintf(path, sizeof(path), "musicstyle_%d", sect_idx++);
530
531 secfile_insert_str(sfile, pmus->music_peaceful, "%s.music_peaceful", path);
532 secfile_insert_str(sfile, pmus->music_combat, "%s.music_combat", path);
533
534 save_reqs_vector(sfile, &(pmus->reqs), path, "reqs");
535 } music_styles_iterate_end;
536
537 return save_ruleset_file(sfile, filename);
538}
539
540/**********************************************************************/
546 static bool save_action_auto_uflag_block(struct section_file *sfile,
547 const int aap,
548 const char *uflags_path,
549 bool (*unexpected_req)(
550 const struct requirement *preq))
551{
552 enum unit_type_flag_id protecor_flag[MAX_NUM_USER_UNIT_FLAGS];
553 size_t i;
554 size_t ret;
555
556 const struct action_auto_perf *auto_perf =
557 action_auto_perf_by_number(aap);
558
559 i = 0;
560 requirement_vector_iterate(&auto_perf->reqs, req) {
561 fc_assert(req->range == REQ_RANGE_LOCAL);
562
563 if (req->source.kind == VUT_UTFLAG) {
564 fc_assert(!req->present);
565
566 protecor_flag[i++] = req->source.value.unitflag;
567 } else if (unexpected_req(req)) {
568 struct astring astr;
569
570 log_error("Can't handle action auto performer requirement %s",
571 req_to_fstring(req, &astr));
572 astr_free(&astr);
573
574 return FALSE;
575 }
576 } requirement_vector_iterate_end;
577
578 ret = secfile_insert_enum_vec(sfile, &protecor_flag, i,
579 unit_type_flag_id,
580 "%s", uflags_path);
581
582 if (ret != i) {
583 log_error("%s: didn't save all unit type flags.", uflags_path);
584
585 return FALSE;
586 }
587
588 return TRUE;
589}
590
591/**********************************************************************/
597 static bool save_action_auto_actions(struct section_file *sfile,
598 const int aap,
599 const char *actions_path)
600{
601 enum gen_action unit_acts[MAX_NUM_ACTIONS];
602 size_t i, j;
603 size_t ret;
604
605 const struct action_auto_perf *auto_perf =
606 action_auto_perf_by_number(aap);
607
608 for (i = 0, j = 0;
609 i < NUM_ACTIONS && auto_perf->alternatives[i] != ACTION_NONE;
610 i++) {
611 struct action *paction = action_by_number(auto_perf->alternatives[i]);
612
613 if (!action_is_in_use(paction)) {
614 /* Don't mention non enabled actions. */
615 continue;
616 }
617
618 /* This action is included in the output. */
619 unit_acts[j] = auto_perf->alternatives[i];
620 j++;
621 }
622
623 action_array_end((action_id *)unit_acts, j);
624 ret = secfile_insert_enum_vec(sfile, &unit_acts, j, gen_action,
625 "%s", actions_path);
626
627 if (ret != j) {
628 log_error("%s: didn't save all actions.", actions_path);
629
630 return FALSE;
631 }
632
633 return TRUE;
634}
635
636/**********************************************************************/
640 static bool unexpected_non_otype(const struct requirement *req)
641{
642 return !(req->source.kind == VUT_OTYPE && req->present);
643}
644
645/**********************************************************************/
650 static bool save_muuk_action_auto(struct section_file *sfile,
651 const int aap,
652 const char *item)
653{
654 char uflags_path[100];
655 char action_path[100];
656
657 fc_snprintf(uflags_path, sizeof(uflags_path),
658 "missing_unit_upkeep.%s_protected", item);
659 fc_snprintf(action_path, sizeof(action_path),
660 "missing_unit_upkeep.%s_unit_act", item);
661
662 return (save_action_auto_uflag_block(sfile, aap, uflags_path,
663 unexpected_non_otype)
664 && save_action_auto_actions(sfile, aap, action_path));
665}
666
667/**********************************************************************/
670 static bool save_cities_ruleset(const char *filename, const char *name)
671{
672 struct section_file *sfile = create_ruleset_file(name, "cities");
673 int sect_idx;
674
675 if (sfile == NULL) {
676 return FALSE;
677 }
678
679 comment_specialists(sfile);
680
681 sect_idx = 0;
682 specialist_type_iterate(sp) {
683 struct specialist *s = specialist_by_number(sp);
684 char path[512];
685
686 fc_snprintf(path, sizeof(path), "specialist_%d", sect_idx++);
687
688 save_name_translation(sfile, &(s->name), path);
689
690 if (strcmp(rule_name_get(&s->name), rule_name_get(&s->abbreviation))) {
691 secfile_insert_str(sfile, rule_name_get(&s->abbreviation),
692 "%s.short_name", path);
693 }
694
695 save_reqs_vector(sfile, &(s->reqs), path, "reqs");
696
697 secfile_insert_str(sfile, s->graphic_str, "%s.graphic", path);
698 if (strcmp(s->graphic_alt, "-")) {
699 secfile_insert_str(sfile, s->graphic_alt, "%s.graphic_alt", path);
700 }
701
702 save_strvec(sfile, s->helptext, path, "helptext");
703
704 } specialist_type_iterate_end;
705
706 if (game.info.celebratesize != GAME_DEFAULT_CELEBRATESIZE) {
707 secfile_insert_int(sfile, game.info.celebratesize,
708 "parameters.celebrate_size_limit");
709 }
710 if (game.info.add_to_size_limit != GAME_DEFAULT_ADDTOSIZE) {
711 secfile_insert_int(sfile, game.info.add_to_size_limit,
712 "parameters.add_to_size_limit");
713 }
714 if (game.info.angrycitizen != GAME_DEFAULT_ANGRYCITIZEN) {
715 secfile_insert_bool(sfile, game.info.angrycitizen,
716 "parameters.angry_citizens");
717 }
718 if (game.info.changable_tax != GAME_DEFAULT_CHANGABLE_TAX) {
719 secfile_insert_bool(sfile, game.info.changable_tax,
720 "parameters.changable_tax");
721 }
722 if (game.info.forced_science != 0) {
723 secfile_insert_int(sfile, game.info.forced_science,
724 "parameters.forced_science");
725 }
726 if (game.info.forced_luxury != 100) {
727 secfile_insert_int(sfile, game.info.forced_luxury,
728 "parameters.forced_luxury");
729 }
730 if (game.info.forced_gold != 0) {
731 secfile_insert_int(sfile, game.info.forced_gold,
732 "parameters.forced_gold");
733 }
734 if (game.server.vision_reveal_tiles != GAME_DEFAULT_VISION_REVEAL_TILES) {
735 secfile_insert_bool(sfile, game.server.vision_reveal_tiles,
736 "parameters.vision_reveal_tiles");
737 }
738 if (game.info.pop_report_zeroes != 1) {
739 secfile_insert_int(sfile, game.info.pop_report_zeroes,
740 "parameters.pop_report_zeroes");
741 }
742
743 save_default_bool(sfile, game.info.citizen_nationality,
744 RS_DEFAULT_NATIONALITY,
745 "citizen.nationality", NULL);
746 save_default_bool(sfile, game.info.unit_builders_nationality,
747 RS_DEFAULT_UBUILD_NAT,
748 "citizen.ubuilder_nationality", NULL);
749 save_default_int(sfile, game.info.citizen_convert_speed,
750 RS_DEFAULT_CONVERT_SPEED,
751 "citizen.convert_speed", NULL);
752 if (game.info.conquest_convert_pct != 0) {
753 secfile_insert_int(sfile, game.info.conquest_convert_pct,
754 "citizen.conquest_convert_pct");
755 }
756
757 if (game.info.citizen_partisans_pct != 0) {
758 secfile_insert_int(sfile, game.info.citizen_partisans_pct,
759 "citizen.partisans_pct");
760 }
761
762 save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_FOOD,
763 "food");
764 if (game.info.muuk_food_wipe != RS_DEFAULT_MUUK_FOOD_WIPE) {
765 secfile_insert_bool(sfile, game.info.muuk_food_wipe,
766 "missing_unit_upkeep.food_wipe");
767 }
768
769 save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_GOLD,
770 "gold");
771 if (game.info.muuk_gold_wipe != RS_DEFAULT_MUUK_GOLD_WIPE) {
772 secfile_insert_bool(sfile, game.info.muuk_gold_wipe,
773 "missing_unit_upkeep.gold_wipe");
774 }
775
776 save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_SHIELD,
777 "shield");
778 if (game.info.muuk_shield_wipe != RS_DEFAULT_MUUK_SHIELD_WIPE) {
779 secfile_insert_bool(sfile, game.info.muuk_shield_wipe,
780 "missing_unit_upkeep.shield_wipe");
781 }
782
783 return save_ruleset_file(sfile, filename);
784}
785
786/**************************************************************************
787 Effect saving callback data structure.
788**************************************************************************/
789 typedef struct {
790 int idx;
791 struct section_file *sfile;
792} effect_cb_data;
793
794/**********************************************************************/
797 static bool effect_save(struct effect *peffect, void *data)
798{
799 effect_cb_data *cbdata = (effect_cb_data *)data;
800 char path[512];
801
802 if (peffect->rulesave.do_not_save) {
803 /* Is supposed to be skipped. */
804 return TRUE;
805 }
806
807 fc_snprintf(path, sizeof(path), "effect_%d", cbdata->idx++);
808
809 secfile_insert_str(cbdata->sfile,
810 effect_type_name(peffect->type),
811 "%s.type", path);
812 secfile_insert_int(cbdata->sfile, peffect->value, "%s.value", path);
813
814 save_reqs_vector(cbdata->sfile, &peffect->reqs, path, "reqs");
815
816 if (peffect->rulesave.comment != NULL) {
817 secfile_insert_str(cbdata->sfile, peffect->rulesave.comment,
818 "%s.comment", path);
819 }
820
821 return TRUE;
822}
823
824/**********************************************************************/
827 static bool save_effects_ruleset(const char *filename, const char *name)
828{
829 struct section_file *sfile = create_ruleset_file(name, "effect");
830 effect_cb_data data;
831 int i;
832 int sidx;
833
834 if (sfile == NULL) {
835 return FALSE;
836 }
837
838 data.idx = 0;
839 data.sfile = sfile;
840
841 comment_ueffs(sfile);
842
843 sidx = 0;
844 for (i = EFT_USER_EFFECT_1 ; i <= EFT_USER_EFFECT_LAST; i++) {
845 enum effect_type val = user_effect_ai_valued_as(i);
846
847 if (val != i) {
848 char path[512];
849
850 fc_snprintf(path, sizeof(path), "ueff_%d", sidx++);
851
852 secfile_insert_str(sfile, effect_type_name(i),
853 "%s.type", path);
854 secfile_insert_str(sfile, effect_type_name(val),
855 "%s.ai_valued_as", path);
856 }
857 }
858
859 comment_effects(sfile);
860
861 if (!iterate_effect_cache(effect_save, &data)) {
862 return FALSE;
863 }
864
865 return save_ruleset_file(sfile, filename);
866}
867
868/**********************************************************************/
871 static bool save_action_ui_name(struct section_file *sfile,
872 int act, const char *entry_name)
873{
874 const char *ui_name = action_by_number(act)->ui_name;
875
876 if (ui_name == NULL) {
877 fc_assert(ui_name != NULL);
878
879 return FALSE;
880 }
881
882 if (strcmp(ui_name, action_ui_name_default(act))) {
883 secfile_insert_str(sfile, ui_name,
884 "actions.%s", entry_name);
885 }
886
887 return TRUE;
888}
889
890/**********************************************************************/
893 static bool save_action_max_range(struct section_file *sfile,
894 action_id act)
895{
896 struct action *paction = action_by_number(act);
897
898 if (paction->max_distance == ACTION_DISTANCE_UNLIMITED) {
899 return secfile_insert_str(sfile, RS_ACTION_NO_MAX_DISTANCE,
900 "actions.%s",
901 action_max_range_ruleset_var_name(act)) != NULL;
902 } else {
903 return save_default_int(sfile, action_by_number(act)->max_distance,
904 actres_max_range_default(paction->result),
905 "actions",
906 action_max_range_ruleset_var_name(act));
907 }
908}
909
910/**********************************************************************/
913 static bool save_action_range(struct section_file *sfile, action_id act)
914{
915 struct action *paction = action_by_number(act);
916
917 if (action_min_range_ruleset_var_name(act) != NULL) {
918 /* Min range can be loaded from the ruleset. */
919 save_default_int(sfile,
920 paction->min_distance,
921 actres_min_range_default(paction->result),
922 "actions",
923 action_min_range_ruleset_var_name(act));
924 }
925
926 if (action_max_range_ruleset_var_name(act) != NULL) {
927 /* Max range can be loaded from the ruleset. */
928 if (!save_action_max_range(sfile, act)) {
929 return FALSE;
930 }
931 }
932
933 return TRUE;
934}
935
936/**********************************************************************/
939 static bool save_action_kind(struct section_file *sfile, action_id act)
940{
941 if (action_target_kind_ruleset_var_name(act) != NULL) {
942 struct action *paction = action_by_number(act);
943
944 /* Target kind can be loaded from the ruleset. */
945 if (!action_is_in_use(paction)) {
946 /* Don't save the default for actions that aren't enabled. */
947 return TRUE;
948 }
949
950 secfile_insert_enum(sfile,
951 action_by_number(act)->target_kind,
952 action_target_kind,
953 "actions.%s",
954 action_target_kind_ruleset_var_name(act));
955 }
956
957 return TRUE;
958}
959
960/**********************************************************************/
963 static bool save_action_actor_consuming_always(struct section_file *sfile,
964 action_id act)
965{
966 if (action_actor_consuming_always_ruleset_var_name(act) != NULL) {
967 struct action *paction = action_by_number(act);
968
969 /* Actor consumption can be loaded from the ruleset. */
970 if (!action_is_in_use(paction)) {
971 /* Don't save value for actions that aren't enabled. */
972 return TRUE;
973 }
974
975 save_default_bool(sfile,
976 action_by_number(act)->actor_consuming_always,
977 RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS,
978 "actions",
979 action_actor_consuming_always_ruleset_var_name(act));
980 }
981
982 return TRUE;
983}
984
985/**********************************************************************/
988 static bool save_action_blocked_by(struct section_file *sfile,
989 struct action *paction)
990{
991 enum gen_action action_vec[MAX_NUM_ACTIONS];
992 char comment[1024];
993 int i = 0;
994
995 if (action_blocked_by_ruleset_var_name(paction) == NULL) {
996 /* Action blocked by shouldn't be written to the ruleset for this
997 * action. */
998 return TRUE;
999 }
1000
1001 if (!action_is_in_use(paction)) {
1002 /* Don't save value for actions that aren't enabled. */
1003 return TRUE;
1004 }
1005
1006 fc_snprintf(comment, sizeof(comment),
1007 "Forbid \"%s\" if any one of the listed actions are legal.",
1008 action_rule_name(paction));
1009
1010 action_iterate(blocker_id) {
1011 struct action *pblocker = action_by_number(blocker_id);
1012
1013 if (!action_is_in_use(pblocker)) {
1014 /* Don't save value for actions that aren't enabled. */
1015 continue;
1016 }
1017
1018 if (BV_ISSET(paction->blocked_by, blocker_id)) {
1019 action_vec[i] = blocker_id;
1020 i++;
1021 }
1022 } action_iterate_end;
1023
1024 if (secfile_insert_enum_vec_comment(
1025 sfile, &action_vec, i, gen_action, comment, "actions.%s",
1026 action_blocked_by_ruleset_var_name(paction))
1027 != i) {
1028 log_error("Didn't save all %s blocking actions.",
1029 action_rule_name(paction));
1030
1031 return FALSE;
1032 }
1033
1034 return TRUE;
1035}
1036
1037/**********************************************************************/
1041 static bool save_action_post_success_force(struct section_file *sfile,
1042 int performer_slot,
1043 struct action *paction)
1044{
1045 char action_list_path[100];
1046
1047 if (action_post_success_forced_ruleset_var_name(paction) == NULL) {
1048 /* Not relevant. */
1049 return TRUE;
1050 }
1051
1052 if (!action_is_in_use(paction)) {
1053 /* Don't save value for actions that aren't enabled. */
1054 return TRUE;
1055 }
1056
1057 fc_snprintf(action_list_path, sizeof(action_list_path),
1058 "actions.%s",
1059 action_post_success_forced_ruleset_var_name(paction));
1060 if (!save_action_auto_actions(sfile, performer_slot, action_list_path)) {
1061 return FALSE;
1062 }
1063
1064 return TRUE;
1065}
1066
1067/**********************************************************************/
1070 static bool save_bv_actions(struct section_file *sfile,
1071 bv_actions content,
1072 const char *path)
1073{
1074 enum gen_action action_vec[MAX_NUM_ACTIONS];
1075 int i = 0;
1076
1077 action_iterate(act_id) {
1078 struct action *paction = action_by_number(act_id);
1079
1080 if (!action_is_in_use(paction)) {
1081 /* Don't save value for actions that aren't enabled. */
1082 continue;
1083 }
1084
1085 if (BV_ISSET(content, act_id)) {
1086 action_vec[i] = act_id;
1087 i++;
1088 }
1089 } action_iterate_end;
1090
1091 if (secfile_insert_enum_vec(sfile, &action_vec, i, gen_action,
1092 "%s", path) != i) {
1093 log_error("Didn't save all of %s.", path);
1094
1095 return FALSE;
1096 }
1097
1098 return TRUE;
1099}
1100/**********************************************************************/
1103 static bool save_actions_ruleset(const char *filename, const char *name)
1104{
1105 struct section_file *sfile = create_ruleset_file(name, "actions");
1106 enum gen_action action_vec[MAX_NUM_ACTIONS];
1107 int i = 0;
1108 int sect_idx = 0;
1109
1110 /* TODO: move action logic from save_game_ruleset to here */
1111 if (sfile == NULL) {
1112 return FALSE;
1113 }
1114 {
1115 /* Action auto performers aren't ready to be exposed in the ruleset
1116 * yet. The behavior when two action auto performers for the same
1117 * cause can fire isn't set in stone yet. How is one of them chosen?
1118 * What if all the actions of the chosen action auto performer turned
1119 * out to be illegal but one of the other action auto performers that
1120 * fired has legal actions? These issues can decide what other action
1121 * rules action auto performers can represent in the future. Deciding
1122 * should therefore wait until a rule needs action auto performers to
1123 * work a certain way. */
1124 /* Only one action auto performer, ACTION_AUTO_MOVED_ADJ, is caused
1125 * by AAPC_UNIT_MOVED_ADJ. It is therefore safe to expose the full
1126 * requirement vector to the ruleset. */
1127 const struct action_auto_perf *auto_perf =
1128 action_auto_perf_by_number(ACTION_AUTO_MOVED_ADJ);
1129
1130 comment_auto_attack(sfile);
1131
1132 save_reqs_vector(sfile, &auto_perf->reqs,
1133 "auto_attack", "if_attacker");
1134
1135 save_action_auto_actions(sfile, ACTION_AUTO_MOVED_ADJ,
1136 "auto_attack.attack_actions");
1137 }
1138
1139 comment_actions_dc_initial_odds(sfile);
1140 if (!save_bv_actions(sfile, game.info.diplchance_initial_odds,
1141 "actions.diplchance_initial_odds")) {
1142 return FALSE;
1143 }
1144
1145 if (!save_action_post_success_force(sfile, ACTION_AUTO_POST_BRIBE,
1146 action_by_number(
1147 ACTION_SPY_BRIBE_UNIT))) {
1148 log_error("Didn't save all post success forced actions.");
1149 return FALSE;
1150 }
1151
1152 if (!save_action_post_success_force(sfile, ACTION_AUTO_POST_ATTACK,
1153 action_by_number(ACTION_ATTACK))) {
1154 log_error("Didn't save all post success forced actions.");
1155 return FALSE;
1156 }
1157
1158 if (!save_action_post_success_force(sfile, ACTION_AUTO_POST_WIPE_UNITS,
1159 action_by_number(ACTION_WIPE_UNITS))) {
1160 log_error("Didn't save all post success forced actions.");
1161 return FALSE;
1162 }
1163
1164 if (!save_action_auto_actions(sfile, ACTION_AUTO_ESCAPE_CITY,
1165 "actions.escape_city")) {
1166 log_error("Didn't save all escape city forced actions.");
1167 return FALSE;
1168 }
1169
1170 if (!save_action_auto_actions(sfile, ACTION_AUTO_ESCAPE_STACK,
1171 "actions.unit_stack_death")) {
1172 log_error("Didn't save all escape unit stack death forced actions.");
1173 return FALSE;
1174 }
1175
1176 save_default_bool(sfile, game.info.poison_empties_food_stock,
1177 RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK,
1178 "actions.poison_empties_food_stock", NULL);
1179
1180 save_default_bool(sfile, game.info.steal_maps_reveals_all_cities,
1181 RS_DEFAULT_STEAL_MAP_REVEALS_CITIES,
1182 "actions.steal_maps_reveals_all_cities", NULL);
1183
1184 comment_actions_ui_names(sfile);
1185
1186 action_iterate(act_id) {
1187 struct action *act = action_by_number(act_id);
1188
1189 save_action_ui_name(sfile,
1190 act_id, action_ui_name_ruleset_var_name(act_id));
1191 save_action_kind(sfile, act_id);
1192 save_action_range(sfile, act_id);
1193 save_action_actor_consuming_always(sfile, act_id);
1194 save_action_blocked_by(sfile, act);
1195 } action_iterate_end;
1196
1197 comment_actions_quiet_actions(sfile);
1198
1199 i = 0;
1200 action_iterate(act) {
1201 if (action_by_number(act)->quiet) {
1202 action_vec[i] = act;
1203 i++;
1204 }
1205 } action_iterate_end;
1206
1207 if (secfile_insert_enum_vec(sfile, &action_vec, i, gen_action,
1208 "actions.quiet_actions") != i) {
1209 log_error("Didn't save all quiet actions.");
1210
1211 return FALSE;
1212 }
1213
1214 comment_enablers(sfile);
1215 sect_idx = 0;
1216 action_enablers_iterate(pae) {
1217 char path[512];
1218
1219 if (pae->ruledit_disabled) {
1220 continue;
1221 }
1222
1223 fc_snprintf(path, sizeof(path), "actionenabler_%d", sect_idx++);
1224
1225 secfile_insert_str(sfile, action_rule_name(enabler_get_action(pae)),
1226 "%s.action", path);
1227
1228 save_reqs_vector(sfile, &(pae->actor_reqs), path, "actor_reqs");
1229 save_reqs_vector(sfile, &(pae->target_reqs), path, "target_reqs");
1230 } action_enablers_iterate_end;
1231
1232 return save_ruleset_file(sfile, filename);
1233}
1234
1235/**********************************************************************/
1238 static bool save_game_ruleset(const char *filename, const char *name)
1239{
1240 struct section_file *sfile = create_ruleset_file(name, "game");
1241 int sect_idx;
1242 int col_idx;
1243 int set_count;
1244 enum gameloss_style gs;
1245 const char *style_names[32]; /* FIXME: Should determine max length automatically.
1246 * currently it's 3 (bits 0,1, and 2) so there's plenty of
1247 * safety margin here. */
1248 const char *tnames[game.server.ruledit.named_teams];
1249 enum trade_route_type trt;
1250 int i;
1251 bool locks;
1252
1253 if (sfile == NULL) {
1254 return FALSE;
1255 }
1256
1257 if (game.server.ruledit.description_file != NULL) {
1258 secfile_insert_str(sfile, game.server.ruledit.description_file,
1259 "ruledit.description_file");
1260 }
1261
1262 if (game.control.preferred_tileset[0] != '\0') {
1263 secfile_insert_str(sfile, game.control.preferred_tileset,
1264 "tileset.preferred");
1265 }
1266 if (game.control.preferred_soundset[0] != '\0') {
1267 secfile_insert_str(sfile, game.control.preferred_soundset,
1268 "soundset.preferred");
1269 }
1270 if (game.control.preferred_musicset[0] != '\0') {
1271 secfile_insert_str(sfile, game.control.preferred_musicset,
1272 "musicset.preferred");
1273 }
1274
1275 secfile_insert_str(sfile, game.control.name, "about.name");
1276 secfile_insert_str(sfile, game.control.version, "about.version");
1277
1278 if (game.control.alt_dir[0] != '\0') {
1279 secfile_insert_str(sfile, game.control.alt_dir, "about.alt_dir");
1280 }
1281
1282 if (game.ruleset_summary != NULL) {
1283 struct entry *mod_entry;
1284
1285 mod_entry = secfile_insert_str(sfile, game.ruleset_summary,
1286 "about.summary");
1287 entry_str_set_gt_marking(mod_entry, TRUE);
1288 }
1289
1290 if (game.ruleset_description != NULL) {
1291 if (game.server.ruledit.description_file == NULL) {
1292 secfile_insert_str(sfile, game.ruleset_description,
1293 "about.description");
1294 } else {
1295 secfile_insert_filereference(sfile, game.server.ruledit.description_file,
1296 "about.description");
1297 }
1298 }
1299
1300 if (game.ruleset_capabilities != NULL) {
1301 secfile_insert_str(sfile, game.ruleset_capabilities,
1302 "about.capabilities");
1303 } else {
1304 secfile_insert_str(sfile, "", "about.capabilities");
1305 }
1306
1307 save_tech_list(sfile, game.rgame.global_init_techs,
1308 "options", "global_init_techs");
1309 save_building_list(sfile, game.rgame.global_init_buildings,
1310 "options", "global_init_buildings");
1311
1312 save_default_bool(sfile, game.control.popup_tech_help,
1313 FALSE,
1314 "options.popup_tech_help", NULL);
1315 save_default_int(sfile, game.info.base_pollution,
1316 RS_DEFAULT_BASE_POLLUTION,
1317 "civstyle.base_pollution", NULL);
1318
1319 set_count = 0;
1320 for (gs = gameloss_style_begin(); gs != gameloss_style_end(); gs = gameloss_style_next(gs)) {
1321 if (game.info.gameloss_style & gs) {
1322 style_names[set_count++] = gameloss_style_name(gs);
1323 }
1324 }
1325
1326 if (set_count > 0) {
1327 comment_civstyle_gameloss_style(sfile);
1328
1329 secfile_insert_str_vec(sfile, style_names, set_count,
1330 "civstyle.gameloss_style");
1331 }
1332
1333 save_default_int(sfile, game.info.happy_cost,
1334 RS_DEFAULT_HAPPY_COST,
1335 "civstyle.happy_cost", NULL);
1336 save_default_int(sfile, game.info.food_cost,
1337 RS_DEFAULT_FOOD_COST,
1338 "civstyle.food_cost", NULL);
1339 save_default_bool(sfile, game.info.civil_war_enabled,
1340 TRUE,
1341 "civstyle.civil_war_enabled", NULL);
1342 save_default_int(sfile, game.info.civil_war_bonus_celebrating,
1343 RS_DEFAULT_CIVIL_WAR_CELEB,
1344 "civstyle.civil_war_bonus_celebrating", NULL);
1345 save_default_int(sfile, game.info.civil_war_bonus_unhappy,
1346 RS_DEFAULT_CIVIL_WAR_UNHAPPY,
1347 "civstyle.civil_war_bonus_unhappy", NULL);
1348 save_default_bool(sfile,
1349 BV_ISSET(action_by_number(ACTION_PARADROP)->sub_results,
1350 ACT_SUB_RES_MAY_EMBARK),
1351 FALSE,
1352 "civstyle.paradrop_to_transport", NULL);
1353 save_default_int(sfile, game.info.base_bribe_cost,
1354 RS_DEFAULT_BASE_BRIBE_COST,
1355 "civstyle.base_bribe_cost", NULL);
1356 if (game.server.ransom_gold != RS_DEFAULT_RANSOM_GOLD) {
1357 comment_civstyle_ransom_gold(sfile);
1358 }
1359 save_default_int(sfile, game.server.ransom_gold,
1360 RS_DEFAULT_RANSOM_GOLD,
1361 "civstyle.ransom_gold", NULL);
1362 save_default_bool(sfile, game.info.pillage_select,
1363 RS_DEFAULT_PILLAGE_SELECT,
1364 "civstyle.pillage_select", NULL);
1365 save_default_bool(sfile, game.info.tech_steal_allow_holes,
1366 RS_DEFAULT_TECH_STEAL_HOLES,
1367 "civstyle.tech_steal_allow_holes", NULL);
1368 save_default_bool(sfile, game.info.tech_trade_allow_holes,
1369 RS_DEFAULT_TECH_TRADE_HOLES,
1370 "civstyle.tech_trade_allow_holes", NULL);
1371 save_default_bool(sfile, game.info.tech_trade_loss_allow_holes,
1372 RS_DEFAULT_TECH_TRADE_LOSS_HOLES,
1373 "civstyle.tech_trade_loss_allow_holes", NULL);
1374 save_default_bool(sfile, game.info.tech_parasite_allow_holes,
1375 RS_DEFAULT_TECH_PARASITE_HOLES,
1376 "civstyle.tech_parasite_allow_holes", NULL);
1377 save_default_bool(sfile, game.info.tech_loss_allow_holes,
1378 RS_DEFAULT_TECH_LOSS_HOLES,
1379 "civstyle.tech_loss_allow_holes", NULL);
1380 save_default_int(sfile, game.server.upgrade_veteran_loss,
1381 RS_DEFAULT_UPGRADE_VETERAN_LOSS,
1382 "civstyle.upgrade_veteran_loss", NULL);
1383 save_default_int(sfile, game.server.autoupgrade_veteran_loss,
1384 RS_DEFAULT_UPGRADE_VETERAN_LOSS,
1385 "civstyle.autoupgrade_veteran_loss", NULL);
1386
1387 comment_civstyle_granary(sfile);
1388
1389 secfile_insert_int_vec(sfile, game.info.granary_food_ini,
1390 game.info.granary_num_inis,
1391 "civstyle.granary_food_ini");
1392
1393 save_default_int(sfile, game.info.granary_food_inc,
1394 RS_DEFAULT_GRANARY_FOOD_INC,
1395 "civstyle.granary_food_inc", NULL);
1396
1397 output_type_iterate(o) {
1398 char buffer[256];
1399
1400 fc_snprintf(buffer, sizeof(buffer),
1401 "civstyle.min_city_center_%s",
1402 get_output_identifier(o));
1403
1404 save_default_int(sfile, game.info.min_city_center_output[o],
1405 RS_DEFAULT_CITY_CENTER_OUTPUT,
1406 buffer, NULL);
1407 } output_type_iterate_end;
1408
1409 save_default_int(sfile, game.server.init_vis_radius_sq,
1410 RS_DEFAULT_VIS_RADIUS_SQ,
1411 "civstyle.init_vis_radius_sq", NULL);
1412 save_default_int(sfile, game.info.init_city_radius_sq,
1413 RS_DEFAULT_CITY_RADIUS_SQ,
1414 "civstyle.init_city_radius_sq", NULL);
1415
1416 comment_civstyle_gold_upkeep_style(sfile);
1417
1418 if (0 != fc_strcasecmp(gold_upkeep_style_name(game.info.gold_upkeep_style),
1419 RS_DEFAULT_GOLD_UPKEEP_STYLE)) {
1420 secfile_insert_str(sfile,
1421 gold_upkeep_style_name(game.info.gold_upkeep_style),
1422 "civstyle.gold_upkeep_style");
1423 }
1424 if (game.info.homeless_gold_upkeep) {
1425 comment_civstyle_homeless_gold_upkeep(sfile);
1426 }
1427 save_default_bool(sfile, game.info.homeless_gold_upkeep, FALSE,
1428 "civstyle.homeless_gold_upkeep", NULL);
1429 save_default_int(sfile, game.info.granularity,
1430 1, "civstyle.output_granularity", NULL);
1431
1432 if (game.info.airlift_from_always_enabled || !game.info.airlift_to_always_enabled) {
1433 comment_civstyle_airlift_always(sfile);
1434 }
1435 save_default_bool(sfile, game.info.airlift_from_always_enabled,
1436 FALSE, "civstyle.airlift_from_always_enabled", NULL);
1437 save_default_bool(sfile, game.info.airlift_to_always_enabled,
1438 TRUE, "civstyle.airlift_to_always_enabled", NULL);
1439
1440 if (fc_strcasecmp(wonder_visib_type_name(game.info.small_wonder_visibility),
1441 RS_DEFAULT_SMALL_WONDER_VISIBILITY)) {
1442 comment_wonder_visibility_small_wonders(sfile);
1443 secfile_insert_str(sfile,
1444 wonder_visib_type_name(game.info.small_wonder_visibility),
1445 "wonder_visibility.small_wonders");
1446 }
1447
1448 save_default_bool(sfile, game.info.illness_on,
1449 RS_DEFAULT_ILLNESS_ON,
1450 "illness.illness_on", NULL);
1451 save_default_int(sfile, game.info.illness_base_factor,
1452 RS_DEFAULT_ILLNESS_BASE_FACTOR,
1453 "illness.illness_base_factor", NULL);
1454 save_default_int(sfile, game.info.illness_min_size,
1455 RS_DEFAULT_ILLNESS_MIN_SIZE,
1456 "illness.illness_min_size", NULL);
1457 save_default_int(sfile, game.info.illness_trade_infection,
1458 RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT,
1459 "illness.illness_trade_infection", NULL);
1460 save_default_int(sfile, game.info.illness_pollution_factor,
1461 RS_DEFAULT_ILLNESS_POLLUTION_PCT,
1462 "illness.illness_pollution_factor", NULL);
1463 comment_incite_cost(sfile);
1464 save_default_int(sfile, game.server.base_incite_cost,
1465 RS_DEFAULT_INCITE_BASE_COST,
1466 "incite_cost.base_incite_cost", NULL);
1467 save_default_int(sfile, game.server.incite_improvement_factor,
1468 RS_DEFAULT_INCITE_IMPROVEMENT_FCT,
1469 "incite_cost.improvement_factor", NULL);
1470 save_default_int(sfile, game.server.incite_unit_factor,
1471 RS_DEFAULT_INCITE_UNIT_FCT,
1472 "incite_cost.unit_factor", NULL);
1473 save_default_int(sfile, game.server.incite_total_factor,
1474 RS_DEFAULT_INCITE_TOTAL_FCT,
1475 "incite_cost.total_factor", NULL);
1476
1477 if (game.info.tired_attack != RS_DEFAULT_TIRED_ATTACK) {
1478 comment_combat_rules_tired_attack(sfile);
1479 }
1480 save_default_bool(sfile, game.info.tired_attack,
1481 RS_DEFAULT_TIRED_ATTACK,
1482 "combat_rules.tired_attack", NULL);
1483 if (game.info.only_killing_makes_veteran != RS_DEFAULT_ONLY_KILLING_VETERAN) {
1484 comment_combat_rules_only_killing_veteran(sfile);
1485 }
1486 save_default_bool(sfile, game.info.only_killing_makes_veteran,
1487 RS_DEFAULT_ONLY_KILLING_VETERAN,
1488 "combat_rules.only_killing_makes_veteran", NULL);
1489 if (game.info.only_real_fight_makes_veteran != RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN) {
1490 comment_combat_rules_only_real_fight_veteran(sfile);
1491 }
1492 save_default_bool(sfile, game.info.only_real_fight_makes_veteran,
1493 RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN,
1494 "combat_rules.only_real_fight_makes_veteran", NULL);
1495 if (game.info.combat_odds_scaled_veterancy != RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY) {
1496 comment_combat_rules_scaled_veterancy(sfile);
1497 }
1498 save_default_bool(sfile, game.info.combat_odds_scaled_veterancy,
1499 RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY,
1500 "combat_rules.combat_odds_scaled_veterancy", NULL);
1501 if (game.info.damage_reduces_bombard_rate != RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE) {
1502 comment_combat_rules_damage_reduces_bombard_rate(sfile);
1503 }
1504 save_default_bool(sfile, game.info.damage_reduces_bombard_rate,
1505 RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE,
1506 "combat_rules.damage_reduces_bombard_rate", NULL);
1507 if (game.info.low_firepower_badwallattacker != 1) {
1508 comment_combat_rules_low_fp_badwallattacker(sfile);
1509 }
1510 save_default_int(sfile, game.info.low_firepower_badwallattacker, 1,
1511 "combat_rules.low_firepower_badwallattacker", NULL);
1512 if (game.info.low_firepower_pearl_harbour != 1) {
1513 comment_combat_rules_low_fp_pearl_harbour(sfile);
1514 }
1515 save_default_int(sfile, game.info.low_firepower_pearl_harbour, 1,
1516 "combat_rules.low_firepower_pearl_harbour", NULL);
1517 if (game.info.low_firepower_combat_bonus != 1) {
1518 comment_combat_rules_low_fp_combat_bonus(sfile);
1519 }
1520 save_default_int(sfile, game.info.low_firepower_combat_bonus, 1,
1521 "combat_rules.low_firepower_combat_bonus", NULL);
1522 if (game.info.low_firepower_nonnat_bombard != 1) {
1523 comment_combat_rules_low_fp_nonnat_bombard(sfile);
1524 }
1525 save_default_int(sfile, game.info.low_firepower_nonnat_bombard, 1,
1526 "combat_rules.low_firepower_nonnat_bombard", NULL);
1527 if (game.info.nuke_pop_loss_pct != RS_DEFAULT_NUKE_POP_LOSS_PCT) {
1528 comment_combat_rules_nuke_pop_loss(sfile);
1529 }
1530 save_default_int(sfile, game.info.nuke_pop_loss_pct,
1531 RS_DEFAULT_NUKE_POP_LOSS_PCT,
1532 "combat_rules.nuke_pop_loss_pct", NULL);
1533 if (game.info.nuke_defender_survival_chance_pct
1534 != RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT) {
1535 comment_combat_rules_nuke_defender_survival(sfile);
1536 }
1537 save_default_int(sfile, game.info.nuke_defender_survival_chance_pct,
1538 RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT,
1539 "combat_rules.nuke_defender_survival_chance_pct", NULL);
1540 save_default_int(sfile, game.info.border_city_radius_sq,
1541 RS_DEFAULT_BORDER_RADIUS_SQ_CITY,
1542 "borders.radius_sq_city", NULL);
1543 save_default_int(sfile, game.info.border_size_effect,
1544 RS_DEFAULT_BORDER_SIZE_EFFECT,
1545 "borders.size_effect", NULL);
1546 if (game.info.border_city_permanent_radius_sq
1547 != RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT) {
1548 comment_borders_radius_permanent(sfile);
1549 }
1550 save_default_int(sfile, game.info.border_city_permanent_radius_sq,
1551 RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT,
1552 "borders.radius_sq_city_permanent", NULL);
1553
1554 comment_research_tech_cost_style(sfile);
1555 secfile_insert_str(sfile, tech_cost_style_name(game.info.tech_cost_style),
1556 "research.tech_cost_style");
1557 if (game.info.base_tech_cost != RS_DEFAULT_BASE_TECH_COST) {
1558 comment_research_base_tech_cost(sfile);
1559 }
1560 save_default_int(sfile, game.info.base_tech_cost,
1561 RS_DEFAULT_BASE_TECH_COST,
1562 "research.base_tech_cost", NULL);
1563 if (game.info.min_tech_cost != RS_DEFAULT_MIN_TECH_COST) {
1564 comment_research_min_tech_cost(sfile);
1565 }
1566 save_default_int(sfile, game.info.min_tech_cost,
1567 RS_DEFAULT_MIN_TECH_COST,
1568 "research.min_tech_cost", NULL);
1569 comment_research_tech_leakage(sfile);
1570 secfile_insert_str(sfile, tech_leakage_style_name(game.info.tech_leakage),
1571 "research.tech_leakage");
1572 comment_research_upkeep_style(sfile);
1573 secfile_insert_str(sfile, tech_upkeep_style_name(game.info.tech_upkeep_style),
1574 "research.tech_upkeep_style");
1575 save_default_int(sfile, game.info.tech_upkeep_divider,
1576 RS_DEFAULT_TECH_UPKEEP_DIVIDER,
1577 "research.tech_upkeep_divider", NULL);
1578 comment_research_free_tech_method(sfile);
1579 secfile_insert_str(sfile, free_tech_method_name(game.info.free_tech_method),
1580 "research.free_tech_method");
1581
1582 save_default_int(sfile, game.info.culture_vic_points,
1583 RS_DEFAULT_CULTURE_VIC_POINTS,
1584 "culture.victory_min_points", NULL);
1585 save_default_int(sfile, game.info.culture_vic_lead,
1586 RS_DEFAULT_CULTURE_VIC_LEAD,
1587 "culture.victory_lead_pct", NULL);
1588 if (game.info.culture_migration_pml != RS_DEFAULT_CULTURE_MIGRATION_PML) {
1589 comment_culture_migration_pml(sfile);
1590 }
1591 save_default_int(sfile, game.info.culture_migration_pml,
1592 RS_DEFAULT_CULTURE_MIGRATION_PML,
1593 "culture.migration_pml", NULL);
1594 if (game.info.history_interest_pml != RS_DEFAULT_HISTORY_INTEREST_PML) {
1595 comment_culture_history_interest(sfile);
1596 }
1597 save_default_int(sfile, game.info.history_interest_pml,
1598 RS_DEFAULT_HISTORY_INTEREST_PML,
1599 "culture.history_interest_pml", NULL);
1600
1601 save_default_bool(sfile, game.calendar.calendar_skip_0,
1602 RS_DEFAULT_CALENDAR_SKIP_0,
1603 "calendar.skip_year_0", NULL);
1604 save_default_int(sfile, game.server.start_year,
1605 GAME_DEFAULT_START_YEAR,
1606 "calendar.start_year", NULL);
1607 if (game.calendar.calendar_fragments != 0) {
1608 comment_calendar_fragments(sfile);
1609 }
1610 save_default_int(sfile, game.calendar.calendar_fragments,
1611 0, "calendar.fragments", NULL);
1612
1613 for (i = 0; i < MAX_CALENDAR_FRAGMENTS; i++) {
1614 if (game.calendar.calendar_fragment_name[i][0] != '\0') {
1615 secfile_insert_str(sfile, game.calendar.calendar_fragment_name[i],
1616 "calendar.fragment_name%d", i);
1617 }
1618 }
1619
1620 if (strcmp(game.calendar.positive_year_label, RS_DEFAULT_POS_YEAR_LABEL)) {
1621 secfile_insert_str(sfile, game.calendar.positive_year_label,
1622 "calendar.positive_label");
1623 }
1624 if (strcmp(game.calendar.negative_year_label, RS_DEFAULT_NEG_YEAR_LABEL)) {
1625 secfile_insert_str(sfile, game.calendar.negative_year_label,
1626 "calendar.negative_label");
1627 }
1628
1629 if (game.plr_bg_color != NULL) {
1630 rgbcolor_save(sfile, game.plr_bg_color, "playercolors.background");
1631 }
1632
1633 col_idx = 0;
1634 rgbcolor_list_iterate(game.server.plr_colors, pcol) {
1635 rgbcolor_save(sfile, pcol, "playercolors.colorlist%d", col_idx++);
1636 } rgbcolor_list_iterate_end;
1637
1638
1639 if (game.server.ruledit.named_teams > 0) {
1640 for (i = 0; i < game.server.ruledit.named_teams; i++) {
1641 tnames[i] = team_slot_rule_name(team_slot_by_number(i));
1642 }
1643
1644 secfile_insert_str_vec(sfile, tnames,
1645 game.server.ruledit.named_teams,
1646 "teams.names");
1647 }
1648
1649 comment_disasters(sfile);
1650
1651 sect_idx = 0;
1652 disaster_type_iterate(pd) {
1653 char path[512];
1654 enum disaster_effect_id de;
1655 const char *effect_names[DE_COUNT];
1656
1657 fc_snprintf(path, sizeof(path), "disaster_%d", sect_idx++);
1658
1659 save_name_translation(sfile, &(pd->name), path);
1660 save_reqs_vector(sfile, &(pd->reqs), path, "reqs");
1661 if (pd->frequency != GAME_DEFAULT_DISASTER_FREQ) {
1662 secfile_insert_int(sfile, pd->frequency,
1663 "%s.frequency", path);
1664 }
1665
1666 set_count = 0;
1667 for (de = disaster_effect_id_begin();
1668 de != disaster_effect_id_end();
1669 de = disaster_effect_id_next(de)) {
1670 if (BV_ISSET(pd->effects, de)) {
1671 effect_names[set_count++] = disaster_effect_id_name(de);
1672 }
1673 }
1674
1675 if (set_count > 0) {
1676 secfile_insert_str_vec(sfile, effect_names, set_count,
1677 "%s.effects", path);
1678 }
1679 } disaster_type_iterate_end;
1680
1681 comment_achievements(sfile);
1682
1683 sect_idx = 0;
1684 achievements_iterate(pach) {
1685 char path[512];
1686
1687 fc_snprintf(path, sizeof(path), "achievement_%d", sect_idx++);
1688
1689 save_name_translation(sfile, &(pach->name), path);
1690
1691 secfile_insert_str(sfile, achievement_type_name(pach->type),
1692 "%s.type", path);
1693
1694 save_default_bool(sfile, pach->unique,
1695 GAME_DEFAULT_ACH_UNIQUE,
1696 path, "unique");
1697 save_default_int(sfile, pach->value,
1698 GAME_DEFAULT_ACH_VALUE,
1699 path, "value");
1700 save_default_int(sfile, pach->culture,
1701 0, path, "culture");
1702
1703 secfile_insert_str(sfile, pach->first_msg, "%s.first_msg", path);
1704 if (pach->cons_msg != NULL) {
1705 secfile_insert_str(sfile, pach->cons_msg, "%s.cons_msg", path);
1706 }
1707
1708 } achievements_iterate_end;
1709
1710 comment_trade_settings(sfile);
1711
1712 set_count = 0;
1713 for (trt = 0; trt < TRT_LAST; trt++) {
1714 struct trade_route_settings *set = trade_route_settings_by_type(trt);
1715 const char *cancelling = trade_route_cancelling_type_name(set->cancelling);
1716
1717 if (set->trade_pct != 100 || strcmp(cancelling, "Active")) {
1718 char path[256];
1719
1720 fc_snprintf(path, sizeof(path),
1721 "trade.settings%d", set_count++);
1722
1723 secfile_insert_str(sfile, trade_route_type_name(trt),
1724 "%s.type", path);
1725 secfile_insert_int(sfile, set->trade_pct,
1726 "%s.pct", path);
1727 secfile_insert_str(sfile, cancelling,
1728 "%s.cancelling", path);
1729 secfile_insert_str(sfile, trade_route_bonus_type_name(set->bonus_type),
1730 "%s.bonus", path);
1731 }
1732 }
1733
1734 save_default_int(sfile, game.info.min_trade_route_val,
1735 0, "trade.min_trade_route_val", NULL);
1736
1737 save_default_bool(sfile, game.info.reveal_trade_partner,
1738 FALSE, "trade.reveal_trade_partner", NULL);
1739
1740 if (game.info.goods_selection != RS_DEFAULT_GOODS_SELECTION) {
1741 secfile_insert_str(sfile, goods_selection_method_name(game.info.goods_selection),
1742 "trade.goods_selection");
1743 }
1744
1745 /* Goods */
1746 comment_goods(sfile);
1747
1748 sect_idx = 0;
1749 goods_type_re_active_iterate(pgood) {
1750 char path[512];
1751 const char *flag_names[GF_COUNT];
1752 int flagi;
1753
1754 fc_snprintf(path, sizeof(path), "goods_%d", sect_idx++);
1755
1756 save_name_translation(sfile, &(pgood->name), path);
1757
1758 save_reqs_vector(sfile, &(pgood->reqs), path, "reqs");
1759
1760 save_default_int(sfile, pgood->from_pct, 100, path, "from_pct");
1761 save_default_int(sfile, pgood->to_pct, 100, path, "to_pct");
1762 save_default_int(sfile, pgood->onetime_pct, 100, path, "onetime_pct");
1763
1764 set_count = 0;
1765 for (flagi = 0; flagi < GF_COUNT; flagi++) {
1766 if (goods_has_flag(pgood, flagi)) {
1767 flag_names[set_count++] = goods_flag_id_name(flagi);
1768 }
1769 }
1770
1771 if (set_count > 0) {
1772 secfile_insert_str_vec(sfile, flag_names, set_count,
1773 "%s.flags", path);
1774 }
1775
1776 save_strvec(sfile, pgood->helptext, path, "helptext");
1777 } goods_type_re_active_iterate_end;
1778
1779 /* Clauses */
1780 comment_clauses(sfile);
1781
1782 sect_idx = 0;
1783 for (i = 0; i < CLAUSE_COUNT; i++) {
1784 struct clause_info *info = clause_info_get(i);
1785
1786 if (info->enabled) {
1787 char path[512];
1788
1789 fc_snprintf(path, sizeof(path), "clause_%d", sect_idx++);
1790
1791 secfile_insert_str(sfile, clause_type_name(info->type),
1792 "%s.type", path);
1793 save_reqs_vector(sfile, &(info->giver_reqs), path, "giver_reqs");
1794 save_reqs_vector(sfile, &(info->receiver_reqs), path, "receiver_reqs");
1795 }
1796 }
1797
1798 /* Counters */
1799 comment_counters(sfile);
1800
1801 sect_idx = 0;
1802 counters_re_iterate(pcounter) {
1803 char path[512];
1804
1805 fc_snprintf(path, sizeof(path), "counter_%d", sect_idx++);
1806
1807 save_name_translation(sfile, &(pcounter->name), path);
1808
1809 save_default_int(sfile, pcounter->def, 0, path, "def");
1810 save_default_int(sfile, pcounter->checkpoint, 0, path, "checkpoint");
1811
1812 secfile_insert_str(sfile, counter_behaviour_name(pcounter->type), "%s.type", path);
1813 if ((NULL != pcounter->helptext)
1814 && (0 < strvec_size(pcounter->helptext))) {
1815 save_strvec(sfile, pcounter->helptext, "%s.helptext", path);
1816 }
1817
1818 } counters_re_iterate_end;
1819
1820 locks = FALSE;
1821 settings_iterate(SSET_ALL, pset) {
1822 if (setting_ruleset_locked(pset)) {
1823 locks = TRUE;
1824 break;
1825 }
1826 } settings_iterate_end;
1827
1828 set_count = 0;
1829 settings_iterate(SSET_ALL, pset) {
1830 struct sf_cb_data info = { pset, FALSE };
1831
1832 if (setting_get_setdef(pset) == SETDEF_RULESET || setting_ruleset_locked(pset)) {
1833 secfile_insert_str(sfile, setting_name(pset),
1834 "settings.set%d.name", set_count);
1835 switch (setting_type(pset)) {
1836 case SST_BOOL:
1837 secfile_insert_bool(sfile, setting_bool_get(pset),
1838 "settings.set%d.value", set_count);
1839 break;
1840 case SST_INT:
1841 secfile_insert_int(sfile, setting_int_get(pset),
1842 "settings.set%d.value", set_count);
1843 break;
1844 case SST_STRING:
1845 secfile_insert_str(sfile, setting_str_get(pset),
1846 "settings.set%d.value", set_count);
1847 break;
1848 case SST_ENUM:
1849 secfile_insert_enum_data(sfile, read_enum_value(pset), FALSE,
1850 setting_enum_secfile_str, &info,
1851 "settings.set%d.value", set_count);
1852 break;
1853 case SST_BITWISE:
1854 secfile_insert_enum_data(sfile, setting_bitwise_get(pset), TRUE,
1855 setting_bitwise_secfile_str, &info,
1856 "settings.set%d.value", set_count);
1857 break;
1858 case SST_COUNT:
1859 fc_assert(setting_type(pset) != SST_COUNT);
1860 secfile_insert_str(sfile, "Unknown setting type",
1861 "settings.set%d.value", set_count);
1862 break;
1863 }
1864
1865 if (locks) {
1866 secfile_insert_bool(sfile, setting_ruleset_locked(pset),
1867 "settings.set%d.lock", set_count);
1868 }
1869
1870 set_count++;
1871 }
1872 } settings_iterate_end;
1873
1874 return save_ruleset_file(sfile, filename);
1875}
1876
1877/**********************************************************************/
1880 static bool save_governments_ruleset(const char *filename, const char *name)
1881{
1882 struct section_file *sfile = create_ruleset_file(name, "government");
1883 int sect_idx;
1884
1885 if (sfile == NULL) {
1886 return FALSE;
1887 }
1888
1889 save_gov_ref(sfile, game.government_during_revolution, "governments",
1890 "during_revolution");
1891
1892 comment_govs(sfile);
1893
1894 sect_idx = 0;
1895 governments_re_active_iterate(pg) {
1896 char path[512];
1897 struct ruler_title *prtitle;
1898
1899 fc_snprintf(path, sizeof(path), "government_%d", sect_idx++);
1900
1901 save_name_translation(sfile, &(pg->name), path);
1902
1903 secfile_insert_str(sfile, pg->graphic_str, "%s.graphic", path);
1904 secfile_insert_str(sfile, pg->graphic_alt, "%s.graphic_alt", path);
1905
1906 save_reqs_vector(sfile, &(pg->reqs), path, "reqs");
1907
1908 if (pg->ai.better != NULL) {
1909 save_gov_ref(sfile, pg->ai.better, path,
1910 "ai_better");
1911 }
1912
1913 ruler_title_hash_lookup(pg->ruler_titles, NULL,
1914 &prtitle);
1915 if (prtitle != NULL) {
1916 const char *title;
1917
1918 title = ruler_title_male_untranslated_name(prtitle);
1919 if (title != NULL) {
1920 secfile_insert_str(sfile, title,
1921 "%s.ruler_male_title", path);
1922 }
1923
1924 title = ruler_title_female_untranslated_name(prtitle);
1925 if (title != NULL) {
1926 secfile_insert_str(sfile, title,
1927 "%s.ruler_female_title", path);
1928 }
1929 }
1930
1931 save_strvec(sfile, pg->helptext, path, "helptext");
1932
1933 } governments_re_active_iterate_end;
1934
1935 comment_policies(sfile);
1936
1937 sect_idx = 0;
1938 multipliers_iterate(pmul) {
1939 if (!pmul->ruledit_disabled) {
1940 char path[512];
1941
1942 fc_snprintf(path, sizeof(path), "multiplier_%d", sect_idx++);
1943
1944 save_name_translation(sfile, &(pmul->name), path);
1945
1946 secfile_insert_int(sfile, pmul->start, "%s.start", path);
1947 secfile_insert_int(sfile, pmul->stop, "%s.stop", path);
1948 secfile_insert_int(sfile, pmul->step, "%s.step", path);
1949 secfile_insert_int(sfile, pmul->def, "%s.default", path);
1950
1951 save_default_int(sfile, pmul->offset, 0, path, "offset");
1952 save_default_int(sfile, pmul->factor, 100, path, "factor");
1953 save_default_int(sfile, pmul->minimum_turns, 0, path, "minimum_turns");
1954
1955 save_reqs_vector(sfile, &(pmul->reqs), path, "reqs");
1956
1957 save_strvec(sfile, pmul->helptext, path, "helptext");
1958 }
1959 } multipliers_iterate_end;
1960
1961 return save_ruleset_file(sfile, filename);
1962}
1963
1964/**********************************************************************/
1967 static bool save_traits(struct trait_limits *traits,
1968 struct trait_limits *default_traits,
1969 struct section_file *sfile,
1970 const char *secname, const char *field_prefix)
1971{
1972 enum trait tr;
1973
1974 /* FIXME: Use specenum trait names without duplicating them here.
1975 * Just needs to take care of case.
1976 * This list is also duplicated in ruleset.c:ruleset_load_traits() */
1977 const char *trait_names[] = {
1978 "expansionist",
1979 "trader",
1980 "aggressive",
1981 "builder",
1982 NULL
1983 };
1984
1985 for (tr = trait_begin(); tr != trait_end() && trait_names[tr] != NULL;
1986 tr = trait_next(tr)) {
1987 int default_default;
1988
1989 default_default = (traits[tr].min + traits[tr].max) / 2;
1990
1991 if ((default_traits == NULL && traits[tr].min != TRAIT_DEFAULT_VALUE)
1992 || (default_traits != NULL && traits[tr].min != default_traits[tr].min)) {
1993 secfile_insert_int(sfile, traits[tr].min, "%s.%s%s_min", secname, field_prefix,
1994 trait_names[tr]);
1995 }
1996 if ((default_traits == NULL && traits[tr].max != TRAIT_DEFAULT_VALUE)
1997 || (default_traits != NULL && traits[tr].max != default_traits[tr].max)) {
1998 secfile_insert_int(sfile, traits[tr].max, "%s.%s%s_max", secname, field_prefix,
1999 trait_names[tr]);
2000 }
2001 if (default_default != traits[tr].fixed) {
2002 secfile_insert_int(sfile, traits[tr].fixed, "%s.%s%s_default", secname, field_prefix,
2003 trait_names[tr]);
2004 }
2005 }
2006
2007 return TRUE;
2008}
2009
2010/**********************************************************************/
2013 static bool save_nation(struct section_file *sfile, struct nation_type *pnat,
2014 int sect_idx)
2015{
2016 char path[512];
2017 int max_items = nation_city_list_size(pnat->server.default_cities);
2018 char *city_str[max_items];
2019 max_items = MAX(max_items, MAX_NUM_NATION_SETS + MAX_NUM_NATION_GROUPS);
2020 max_items = MAX(max_items, game.control.nation_count);
2021 const char *list_items[max_items];
2022 int set_count;
2023 int subsect_idx;
2024
2025 fc_snprintf(path, sizeof(path), "nation_%d", sect_idx++);
2026
2027 if (pnat->translation_domain == NULL) {
2028 secfile_insert_str(sfile, "freeciv-core", "%s.translation_domain", path);
2029 } else {
2030 secfile_insert_str(sfile, pnat->translation_domain, "%s.translation_domain", path);
2031 }
2032
2033 save_name_translation(sfile, &(pnat->adjective), path);
2034 secfile_insert_str(sfile, untranslated_name(&(pnat->noun_plural)), "%s.plural", path);
2035
2036 set_count = 0;
2037 nation_sets_iterate(pset) {
2038 if (nation_is_in_set(pnat, pset)) {
2039 list_items[set_count++] = nation_set_rule_name(pset);
2040 }
2041 } nation_sets_iterate_end;
2042 nation_groups_iterate(pgroup) {
2043 if (nation_is_in_group(pnat, pgroup)) {
2044 list_items[set_count++] = nation_group_rule_name(pgroup);
2045 }
2046 } nation_groups_iterate_end;
2047
2048 if (set_count > 0) {
2049 secfile_insert_str_vec(sfile, list_items, set_count, "%s.groups", path);
2050 }
2051
2052 set_count = 0;
2053 nation_list_iterate(pnat->server.conflicts_with, pconfl) {
2054 list_items[set_count++] = nation_rule_name(pconfl);
2055 } nation_list_iterate_end;
2056 if (set_count > 0) {
2057 secfile_insert_str_vec(sfile, list_items, set_count, "%s.conflicts_with", path);
2058 }
2059
2060 subsect_idx = 0;
2061 nation_leader_list_iterate(pnat->leaders, pleader) {
2062 secfile_insert_str(sfile, nation_leader_name(pleader), "%s.leaders%d.name",
2063 path, subsect_idx);
2064 secfile_insert_str(sfile,
2065 nation_leader_is_male(pleader) ?
2066 sex_rule_name(SEX_MALE) : sex_rule_name(SEX_FEMALE),
2067 "%s.leaders%d.sex", path, subsect_idx++);
2068 } nation_leader_list_iterate_end;
2069
2070 if (pnat->server.rgb != NULL) {
2071 rgbcolor_save(sfile, pnat->server.rgb, "%s.color", path);
2072 }
2073
2074 save_traits(pnat->server.traits, game.server.default_traits,
2075 sfile, path, "trait_");
2076
2077 if (!pnat->is_playable) {
2078 secfile_insert_bool(sfile, pnat->is_playable, "%s.is_playable", path);
2079 }
2080
2081 if (pnat->barb_type != NOT_A_BARBARIAN) {
2082 secfile_insert_str(sfile, barbarian_type_name(pnat->barb_type),
2083 "%s.barbarian_type", path);
2084 }
2085
2086 if (strcmp(pnat->flag_graphic_str, "-")) {
2087 secfile_insert_str(sfile, pnat->flag_graphic_str, "%s.flag", path);
2088 }
2089 if (strcmp(pnat->flag_graphic_alt, "-")) {
2090 secfile_insert_str(sfile, pnat->flag_graphic_alt, "%s.flag_alt", path);
2091 }
2092
2093 subsect_idx = 0;
2094 governments_iterate(pgov) {
2095 struct ruler_title *prtitle;
2096
2097 if (ruler_title_hash_lookup(pgov->ruler_titles, pnat, &prtitle)) {
2098 secfile_insert_str(sfile, government_rule_name(pgov),
2099 "%s.ruler_titles%d.government", path, subsect_idx);
2100 secfile_insert_str(sfile, ruler_title_male_untranslated_name(prtitle),
2101 "%s.ruler_titles%d.male_title", path, subsect_idx);
2102 secfile_insert_str(sfile, ruler_title_female_untranslated_name(prtitle),
2103 "%s.ruler_titles%d.female_title", path, subsect_idx++);
2104 }
2105 } governments_iterate_end;
2106
2107 secfile_insert_str(sfile, style_rule_name(pnat->style), "%s.style", path);
2108
2109 set_count = 0;
2110 nation_list_iterate(pnat->server.civilwar_nations, pconfl) {
2111 list_items[set_count++] = nation_rule_name(pconfl);
2112 } nation_list_iterate_end;
2113 if (set_count > 0) {
2114 secfile_insert_str_vec(sfile, list_items, set_count, "%s.civilwar_nations", path);
2115 }
2116
2117 save_tech_list(sfile, pnat->init_techs, path, "init_techs");
2118 save_building_list(sfile, pnat->init_buildings, path, "init_buildings");
2119 save_unit_list(sfile, pnat->init_units, path, "init_units");
2120
2121 if (pnat->init_government) {
2122 secfile_insert_str(sfile, government_rule_name(pnat->init_government),
2123 "%s.init_government", path);
2124 }
2125
2126 set_count = 0;
2127 nation_city_list_iterate(pnat->server.default_cities, pncity) {
2128 bool list_started = FALSE;
2129
2130 city_str[set_count] = fc_malloc(strlen(nation_city_name(pncity)) + strlen(" (!river")
2131 + strlen(")")
2132 + MAX_NUM_TERRAINS * (strlen(", ") + MAX_LEN_NAME));
2133
2134 strcpy(city_str[set_count], nation_city_name(pncity));
2135 switch (nation_city_river_preference(pncity)) {
2136 case NCP_DISLIKE:
2137 strcat(city_str[set_count], " (!river");
2138 list_started = TRUE;
2139 break;
2140 case NCP_LIKE:
2141 strcat(city_str[set_count], " (river");
2142 list_started = TRUE;
2143 break;
2144 case NCP_NONE:
2145 break;
2146 }
2147
2148 terrain_type_iterate(pterr) {
2149 const char *pref = NULL;
2150
2151 switch (nation_city_terrain_preference(pncity, pterr)) {
2152 case NCP_DISLIKE:
2153 pref = "!";
2154 break;
2155 case NCP_LIKE:
2156 pref = "";
2157 break;
2158 case NCP_NONE:
2159 pref = NULL;
2160 break;
2161 }
2162
2163 if (pref != NULL) {
2164 if (list_started) {
2165 strcat(city_str[set_count], ", ");
2166 } else {
2167 strcat(city_str[set_count], " (");
2168 list_started = TRUE;
2169 }
2170 strcat(city_str[set_count], pref);
2171 strcat(city_str[set_count], terrain_rule_name(pterr));
2172 }
2173
2174 } terrain_type_iterate_end;
2175
2176 if (list_started) {
2177 strcat(city_str[set_count], ")");
2178 }
2179
2180 list_items[set_count] = city_str[set_count];
2181 set_count++;
2182 } nation_city_list_iterate_end;
2183 if (set_count > 0) {
2184 int i;
2185
2186 secfile_insert_str_vec(sfile, list_items, set_count, "%s.cities", path);
2187
2188 for (i = 0; i < set_count; i++) {
2189 FC_FREE(city_str[i]);
2190 }
2191 }
2192
2193 secfile_insert_str(sfile, pnat->legend, "%s.legend", path);
2194
2195 return TRUE;
2196}
2197
2198/**********************************************************************/
2201 static bool save_nations_ruleset(const char *filename, const char *name,
2202 struct rule_data *data)
2203{
2204 struct section_file *sfile = create_ruleset_file(name, "nation");
2205
2206 if (sfile == NULL) {
2207 return FALSE;
2208 }
2209
2210 if (data->nationlist != NULL || game.server.ruledit.embedded_nations != NULL) {
2211 comment_nations_ruledit(sfile);
2212 if (data->nationlist != NULL) {
2213 secfile_insert_str(sfile, data->nationlist, "ruledit.nationlist");
2214 }
2215 if (game.server.ruledit.embedded_nations != NULL) {
2216 int i;
2217 const char **tmp = fc_malloc(game.server.ruledit.embedded_nations_count * sizeof(char *));
2218
2219 /* Dance around the secfile_insert_str_vec() parameter type (requires extra const)
2220 * resrictions */
2221 for (i = 0; i < game.server.ruledit.embedded_nations_count; i++) {
2222 tmp[i] = game.server.ruledit.embedded_nations[i];
2223 }
2224
2225 secfile_insert_str_vec(sfile, tmp,
2226 game.server.ruledit.embedded_nations_count,
2227 "ruledit.embedded_nations");
2228 free(tmp);
2229 }
2230 }
2231
2232 save_traits(game.server.default_traits, NULL, sfile,
2233 "default_traits", "");
2234
2235 if (data->nationlist == NULL) {
2236 if (game.server.ruledit.allowed_govs != NULL) {
2237 secfile_insert_str_vec(sfile, game.server.ruledit.allowed_govs,
2238 game.server.ruledit.ag_count,
2239 "compatibility.allowed_govs");
2240 }
2241 if (game.server.ruledit.allowed_terrains != NULL) {
2242 secfile_insert_str_vec(sfile, game.server.ruledit.allowed_terrains,
2243 game.server.ruledit.at_count,
2244 "compatibility.allowed_terrains");
2245 }
2246 if (game.server.ruledit.allowed_styles != NULL) {
2247 secfile_insert_str_vec(sfile, game.server.ruledit.allowed_styles,
2248 game.server.ruledit.as_count,
2249 "compatibility.allowed_styles");
2250 }
2251 }
2252
2253 if (game.default_government != NULL) {
2254 secfile_insert_str(sfile, government_rule_name(game.default_government),
2255 "compatibility.default_government");
2256 }
2257
2258 if (data->nationlist != NULL) {
2259 secfile_insert_include(sfile, data->nationlist);
2260
2261 if (game.server.ruledit.embedded_nations != NULL) {
2262 int sect_idx;
2263
2264 comment_nations(sfile);
2265
2266 for (sect_idx = 0; sect_idx < game.server.ruledit.embedded_nations_count;
2267 sect_idx++) {
2268 struct nation_type *pnat
2269 = nation_by_rule_name(game.server.ruledit.embedded_nations[sect_idx]);
2270
2271 if (pnat == NULL) {
2272 log_error("Embedded nation \"%s\" not found!",
2273 game.server.ruledit.embedded_nations[sect_idx]);
2274 } else {
2275 save_nation(sfile, pnat, sect_idx);
2276 }
2277 }
2278 }
2279 } else {
2280 int sect_idx = 0;
2281
2282 comment_nationsets(sfile);
2283
2284 nation_sets_iterate(pset) {
2285 char path[512];
2286
2287 fc_snprintf(path, sizeof(path), "nset_%d", sect_idx++);
2288
2289 /* We don't use save_name_translation() for this as name and rule_name must
2290 * always be saved separately */
2291 secfile_insert_str(sfile, nation_set_untranslated_name(pset), "%s.name", path);
2292 secfile_insert_str(sfile, nation_set_rule_name(pset), "%s.rule_name", path);
2293 secfile_insert_str(sfile, nation_set_description(pset), "%s.description", path);
2294 } nation_sets_iterate_end;
2295
2296 comment_nationgroups(sfile);
2297
2298 sect_idx = 0;
2299 nation_groups_iterate(pgroup) {
2300 char path[512];
2301
2302 fc_snprintf(path, sizeof(path), "ngroup_%d", sect_idx++);
2303
2304 save_name_translation(sfile, &(pgroup->name), path);
2305
2306 secfile_insert_int(sfile, pgroup->server.match, "%s.match", path);
2307 if (pgroup->hidden) {
2308 secfile_insert_bool(sfile, pgroup->hidden, "%s.hidden", path);
2309 }
2310 } nation_groups_iterate_end;
2311
2312 comment_nations(sfile);
2313
2314 sect_idx = 0;
2315 nations_iterate(pnat) {
2316 save_nation(sfile, pnat, sect_idx++);
2317 } nations_iterate_end;
2318 }
2319
2320 return save_ruleset_file(sfile, filename);
2321}
2322
2323/**********************************************************************/
2326 static bool save_techs_ruleset(const char *filename, const char *name)
2327{
2328 struct section_file *sfile = create_ruleset_file(name, "tech");
2329 int i;
2330 int sect_idx;
2331 struct advance *a_none = advance_by_number(A_NONE);
2332 bool uflags_tech = FALSE;
2333
2334 if (sfile == NULL) {
2335 return FALSE;
2336 }
2337
2338 for (i = 0; i < MAX_NUM_USER_TECH_FLAGS; i++) {
2339 const char *flagname = tech_flag_id_name_cb(i + TECH_USER_1);
2340 const char *helptxt = tech_flag_helptxt(i + TECH_USER_1);
2341
2342 if (flagname != NULL) {
2343 if (!uflags_tech) {
2344 comment_uflags_tech(sfile);
2345 uflags_tech = TRUE;
2346 }
2347
2348 secfile_insert_str(sfile, flagname, "control.flags%d.name", i);
2349
2350 /* Save the user flag help text even when it is undefined. That makes
2351 * the formatting code happy. The resulting "" is ignored when the
2352 * ruleset is loaded. */
2353 secfile_insert_str(sfile, helptxt, "control.flags%d.helptxt", i);
2354 }
2355 }
2356
2357 comment_tech_classes(sfile);
2358
2359 sect_idx = 0;
2360 tech_class_iterate(ptclass) {
2361 char path[512];
2362
2363 fc_snprintf(path, sizeof(path), "techclass_%d", sect_idx++);
2364
2365 save_name_translation(sfile, &(ptclass->name), path);
2366 } tech_class_iterate_end;
2367
2368 comment_techs(sfile);
2369
2370 sect_idx = 0;
2371 advance_re_active_iterate(pa) {
2372 if (pa->require[AR_ONE] != A_NEVER) {
2373 char path[512];
2374 const char *flag_names[TF_COUNT];
2375 int set_count;
2376 int flagi;
2377
2378 fc_snprintf(path, sizeof(path), "advance_%d", sect_idx++);
2379
2380 save_name_translation(sfile, &(pa->name), path);
2381
2382 if (game.control.num_tech_classes > 0) {
2383 if (pa->tclass != NULL) {
2384 secfile_insert_str(sfile, tech_class_rule_name(pa->tclass),
2385 "%s.class", path);
2386 }
2387 }
2388
2389 save_tech_ref(sfile, pa->require[AR_ONE], path, "req1");
2390 save_tech_ref(sfile, pa->require[AR_TWO], path, "req2");
2391 if (pa->require[AR_ROOT] != a_none && !pa->inherited_root_req) {
2392 save_tech_ref(sfile, pa->require[AR_ROOT], path, "root_req");
2393 }
2394
2395 save_reqs_vector(sfile, &(pa->research_reqs), path,
2396 "research_reqs");
2397
2398 secfile_insert_str(sfile, pa->graphic_str, "%s.graphic", path);
2399 if (strcmp("-", pa->graphic_alt)) {
2400 secfile_insert_str(sfile, pa->graphic_alt, "%s.graphic_alt", path);
2401 }
2402 if (pa->bonus_message != NULL) {
2403 secfile_insert_str(sfile, pa->bonus_message, "%s.bonus_message", path);
2404 }
2405
2406 set_count = 0;
2407 for (flagi = 0; flagi < TF_COUNT; flagi++) {
2408 if (advance_has_flag(advance_index(pa), flagi)) {
2409 flag_names[set_count++] = tech_flag_id_name(flagi);
2410 }
2411 }
2412
2413 if (set_count > 0) {
2414 secfile_insert_str_vec(sfile, flag_names, set_count,
2415 "%s.flags", path);
2416 }
2417 if (pa->cost >= 0) {
2418 secfile_insert_int(sfile, pa->cost, "%s.cost", path);
2419 }
2420
2421 save_strvec(sfile, pa->helptext, path, "helptext");
2422 }
2423
2424 } advance_re_active_iterate_end;
2425
2426 return save_ruleset_file(sfile, filename);
2427}
2428
2429/**********************************************************************/
2432 static bool save_terrain_ruleset(const char *filename, const char *name)
2433{
2434 struct section_file *sfile = create_ruleset_file(name, "terrain");
2435 int sect_idx;
2436 int i;
2437 bool uflags_terr = FALSE;
2438 bool uflags_extra = FALSE;
2439
2440 if (sfile == NULL) {
2441 return FALSE;
2442 }
2443
2444 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
2445 const char *flagname = terrain_flag_id_name_cb(i + TER_USER_1);
2446 const char *helptxt = terrain_flag_helptxt(i + TER_USER_1);
2447
2448 if (flagname != NULL) {
2449 if (!uflags_terr) {
2450 comment_uflags_terrain(sfile);
2451 uflags_terr = TRUE;
2452 }
2453
2454 secfile_insert_str(sfile, flagname, "control.flags%d.name", i);
2455
2456 /* Save the user flag help text even when it is undefined. That makes
2457 * the formatting code happy. The resulting "" is ignored when the
2458 * ruleset is loaded. */
2459 secfile_insert_str(sfile, helptxt, "control.flags%d.helptxt", i);
2460 }
2461 }
2462
2463 for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
2464 const char *flagname = extra_flag_id_name_cb(i + EF_USER_FLAG_1);
2465 const char *helptxt = extra_flag_helptxt(i + EF_USER_FLAG_1);
2466
2467 if (flagname != NULL) {
2468 if (!uflags_extra) {
2469 /* TODO: Uncomment this, once there's a way to stop
2470 * the comment getting written inside preceding
2471 * terrain flags table. */
2472 /* comment_uflags_extra(sfile); */
2473 uflags_extra = TRUE;
2474 }
2475
2476 secfile_insert_str(sfile, flagname, "control.extra_flags%d.name", i);
2477
2478 /* Save the user flag help text even when it is undefined. That makes
2479 * the formatting code happy. The resulting "" is ignored when the
2480 * ruleset is loaded. */
2481 secfile_insert_str(sfile, helptxt,
2482 "control.extra_flags%d.helptxt", i);
2483 }
2484 }
2485
2486 if (terrain_control.ocean_reclaim_requirement_pct <= 100) {
2487 secfile_insert_int(sfile, terrain_control.ocean_reclaim_requirement_pct,
2488 "parameters.ocean_reclaim_requirement");
2489 }
2490 if (terrain_control.land_channel_requirement_pct <= 100) {
2491 secfile_insert_int(sfile, terrain_control.land_channel_requirement_pct,
2492 "parameters.land_channel_requirement");
2493 }
2494 if (terrain_control.terrain_thaw_requirement_pct <= 100) {
2495 secfile_insert_int(sfile, terrain_control.terrain_thaw_requirement_pct,
2496 "parameters.thaw_requirement");
2497 }
2498 if (terrain_control.terrain_freeze_requirement_pct <= 100) {
2499 secfile_insert_int(sfile, terrain_control.terrain_freeze_requirement_pct,
2500 "parameters.freeze_requirement");
2501 }
2502 if (terrain_control.lake_max_size != 0) {
2503 secfile_insert_int(sfile, terrain_control.lake_max_size,
2504 "parameters.lake_max_size");
2505 }
2506 if (terrain_control.min_start_native_area != 0) {
2507 secfile_insert_int(sfile, terrain_control.min_start_native_area,
2508 "parameters.min_start_native_area");
2509 }
2510 if (terrain_control.move_fragments != 3) {
2511 secfile_insert_int(sfile, terrain_control.move_fragments,
2512 "parameters.move_fragments");
2513 }
2514 if (terrain_control.igter_cost != 1) {
2515 secfile_insert_int(sfile, terrain_control.igter_cost,
2516 "parameters.igter_cost");
2517 }
2518 if (terrain_control.pythagorean_diagonal != RS_DEFAULT_PYTHAGOREAN_DIAGONAL) {
2519 secfile_insert_bool(sfile, terrain_control.pythagorean_diagonal,
2520 "parameters.pythagorean_diagonal");
2521 }
2522 if (wld.map.server.ocean_resources) {
2523 secfile_insert_bool(sfile, TRUE,
2524 "parameters.ocean_resources");
2525 }
2526
2527 comment_terrains(sfile);
2528
2529 sect_idx = 0;
2530 terrain_type_iterate(pterr) {
2531 char path[512];
2532 char identifier[2];
2533 int r;
2534 const char *flag_names[TER_USER_LAST];
2535 const char *puc_names[UCL_LAST];
2536 int flagi;
2537 int set_count;
2538
2539 fc_snprintf(path, sizeof(path), "terrain_%d", sect_idx++);
2540
2541 save_name_translation(sfile, &(pterr->name), path);
2542
2543 secfile_insert_str(sfile, pterr->graphic_str, "%s.graphic", path);
2544 secfile_insert_str(sfile, pterr->graphic_alt, "%s.graphic_alt", path);
2545 secfile_insert_str(sfile, pterr->graphic_alt2, "%s.graphic_alt2", path);
2546 identifier[0] = pterr->identifier;
2547 identifier[1] = '\0';
2548 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2549
2550 secfile_insert_str(sfile, terrain_class_name(pterr->tclass),
2551 "%s.class", path);
2552
2553 secfile_insert_int(sfile, pterr->movement_cost, "%s.movement_cost", path);
2554 secfile_insert_int(sfile, pterr->defense_bonus, "%s.defense_bonus", path);
2555
2556 output_type_iterate(o) {
2557 if (pterr->output[o] != 0) {
2558 secfile_insert_int(sfile, pterr->output[o], "%s.%s", path,
2559 get_output_identifier(o));
2560 }
2561 } output_type_iterate_end;
2562
2563 /* Check resource count */
2564 for (r = 0; pterr->resources[r] != NULL; r++) {
2565 /* Just increasing r as long as there is resources */
2566 }
2567
2568 {
2569 const char *resource_names[r];
2570 bool save_frequencies = FALSE;
2571
2572 r = 0;
2573 terrain_resources_iterate(pterr, res, freq) {
2574 resource_names[r++] = extra_rule_name(res);
2575 if (freq != RESOURCE_FREQUENCY_DEFAULT) {
2576 save_frequencies = TRUE;
2577 }
2578 } terrain_resources_iterate_end;
2579
2580 secfile_insert_str_vec(sfile, resource_names, r,
2581 "%s.resources", path);
2582
2583 if (save_frequencies) {
2584 secfile_insert_int_vec(sfile, pterr->resource_freq, r,
2585 "%s.resource_freq", path);
2586 }
2587 }
2588
2589 output_type_iterate(o) {
2590 if (pterr->road_output_incr_pct[o] != 0) {
2591 secfile_insert_int(sfile, pterr->road_output_incr_pct[o],
2592 "%s.road_%s_incr_pct", path,
2593 get_output_identifier(o));
2594 }
2595 } output_type_iterate_end;
2596
2597 secfile_insert_int(sfile, pterr->base_time, "%s.base_time", path);
2598 secfile_insert_int(sfile, pterr->road_time, "%s.road_time", path);
2599
2600 save_terrain_ref(sfile, pterr->cultivate_result, pterr, path,
2601 "cultivate_result");
2602 secfile_insert_int(sfile, pterr->cultivate_time,
2603 "%s.cultivate_time", path);
2604
2605 save_terrain_ref(sfile, pterr->plant_result, pterr, path,
2606 "plant_result");
2607 secfile_insert_int(sfile, pterr->plant_time,
2608 "%s.plant_time", path);
2609
2610 secfile_insert_int(sfile, pterr->irrigation_food_incr,
2611 "%s.irrigation_food_incr", path);
2612 secfile_insert_int(sfile, pterr->irrigation_time,
2613 "%s.irrigation_time", path);
2614
2615 secfile_insert_int(sfile, pterr->mining_shield_incr,
2616 "%s.mining_shield_incr", path);
2617 secfile_insert_int(sfile, pterr->mining_time,
2618 "%s.mining_time", path);
2619
2620 save_terrain_ref(sfile, pterr->transform_result, pterr, path,
2621 "transform_result");
2622 secfile_insert_int(sfile, pterr->transform_time,
2623 "%s.transform_time", path);
2624
2625 if (pterr->animal != NULL) {
2626 secfile_insert_str(sfile, utype_rule_name(pterr->animal),
2627 "%s.animal", path);
2628 } else {
2629 secfile_insert_str(sfile, "None",
2630 "%s.animal", path);
2631 }
2632
2633 secfile_insert_int(sfile, pterr->placing_time,
2634 "%s.placing_time", path);
2635 secfile_insert_int(sfile, pterr->pillage_time,
2636 "%s.pillage_time", path);
2637
2638 i = 0;
2639 extra_type_iterate(pextra) {
2640 int rmtime = pterr->extra_removal_times[extra_index(pextra)];
2641
2642 if (rmtime != 0) {
2643 secfile_insert_str(sfile, extra_rule_name(pextra),
2644 "%s.extra_settings%d.extra",
2645 path, i);
2646 secfile_insert_int(sfile, rmtime,
2647 "%s.extra_settings%d.removal_time",
2648 path, i++);
2649 }
2650 } extra_type_iterate_end;
2651
2652 save_terrain_ref(sfile, pterr->warmer_wetter_result, pterr, path,
2653 "warmer_wetter_result");
2654 save_terrain_ref(sfile, pterr->warmer_drier_result, pterr, path,
2655 "warmer_drier_result");
2656 save_terrain_ref(sfile, pterr->cooler_wetter_result, pterr, path,
2657 "cooler_wetter_result");
2658 save_terrain_ref(sfile, pterr->cooler_drier_result, pterr, path,
2659 "cooler_drier_result");
2660
2661 set_count = 0;
2662 for (flagi = 0; flagi < TER_USER_LAST; flagi++) {
2663 if (terrain_has_flag(pterr, flagi)) {
2664 flag_names[set_count++] = terrain_flag_id_name(flagi);
2665 }
2666 }
2667
2668 if (set_count > 0) {
2669 secfile_insert_str_vec(sfile, flag_names, set_count,
2670 "%s.flags", path);
2671 }
2672
2673 {
2674 enum mapgen_terrain_property mtp;
2675
2676 for (mtp = mapgen_terrain_property_begin();
2677 mtp != mapgen_terrain_property_end();
2678 mtp = mapgen_terrain_property_next(mtp)) {
2679 if (pterr->property[mtp] != 0) {
2680 secfile_insert_int(sfile, pterr->property[mtp],
2681 "%s.property_%s", path,
2682 mapgen_terrain_property_name(mtp));
2683 }
2684 }
2685 }
2686
2687 set_count = 0;
2688 unit_class_iterate(puc) {
2689 if (BV_ISSET(pterr->native_to, uclass_index(puc))) {
2690 puc_names[set_count++] = uclass_rule_name(puc);
2691 }
2692 } unit_class_iterate_end;
2693
2694 if (set_count > 0) {
2695 secfile_insert_str_vec(sfile, puc_names, set_count,
2696 "%s.native_to", path);
2697 }
2698
2699 rgbcolor_save(sfile, pterr->rgb, "%s.color", path);
2700
2701 save_strvec(sfile, pterr->helptext, path, "helptext");
2702
2703 } terrain_type_iterate_end;
2704
2705 comment_resources(sfile);
2706
2707 sect_idx = 0;
2708 extra_type_by_cause_iterate(EC_RESOURCE, pres) {
2709 if (!pres->ruledit_disabled) {
2710 char path[512];
2711 char identifier[2];
2712
2713 fc_snprintf(path, sizeof(path), "resource_%d", sect_idx++);
2714
2715 secfile_insert_str(sfile, extra_rule_name(pres),
2716 "%s.extra", path);
2717
2718 output_type_iterate(o) {
2719 if (pres->data.resource->output[o] != 0) {
2720 secfile_insert_int(sfile, pres->data.resource->output[o], "%s.%s",
2721 path, get_output_identifier(o));
2722 }
2723 } output_type_iterate_end;
2724
2725 if (pres->data.resource->id_old_save != '\0') {
2726 identifier[0] = pres->data.resource->id_old_save;
2727 identifier[1] = '\0';
2728 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2729 }
2730 }
2731 } extra_type_by_cause_iterate_end;
2732
2733 secfile_insert_str(sfile, terrain_control.gui_type_base0,
2734 "extraui.ui_name_base_fortress");
2735 secfile_insert_str(sfile, terrain_control.gui_type_base1,
2736 "extraui.ui_name_base_airbase");
2737
2738 comment_extras(sfile);
2739
2740 sect_idx = 0;
2741 extra_type_re_active_iterate(pextra) {
2742 char path[512];
2743 const char *flag_names[EF_COUNT];
2744 const char *cause_names[EC_COUNT];
2745 const char *puc_names[UCL_LAST];
2746 const char *extra_names[MAX_EXTRA_TYPES];
2747 int flagi;
2748 int causei;
2749 int set_count;
2750 bool worker_cause;
2751
2752 fc_snprintf(path, sizeof(path), "extra_%d", sect_idx++);
2753
2754 save_name_translation(sfile, &(pextra->name), path);
2755
2756 secfile_insert_str(sfile, extra_category_name(pextra->category),
2757 "%s.category", path);
2758
2759 set_count = 0;
2760 for (causei = 0; causei < EC_COUNT; causei++) {
2761 if (is_extra_caused_by(pextra, causei)) {
2762 cause_names[set_count++] = extra_cause_name(causei);
2763 }
2764 }
2765
2766 if (set_count > 0) {
2767 secfile_insert_str_vec(sfile, cause_names, set_count,
2768 "%s.causes", path);
2769 }
2770
2771 set_count = 0;
2772 for (causei = 0; causei < ERM_COUNT; causei++) {
2773 if (is_extra_removed_by(pextra, causei)) {
2774 cause_names[set_count++] = extra_rmcause_name(causei);
2775 }
2776 }
2777
2778 if (set_count > 0) {
2779 secfile_insert_str_vec(sfile, cause_names, set_count,
2780 "%s.rmcauses", path);
2781 }
2782
2783 if (strcmp(pextra->graphic_str, "-")) {
2784 secfile_insert_str(sfile, pextra->graphic_str, "%s.graphic", path);
2785 }
2786 if (strcmp(pextra->graphic_alt, "-")) {
2787 secfile_insert_str(sfile, pextra->graphic_alt, "%s.graphic_alt", path);
2788 }
2789 if (strcmp(pextra->activity_gfx, "-")) {
2790 secfile_insert_str(sfile, pextra->activity_gfx, "%s.activity_gfx", path);
2791 }
2792 if (strcmp(pextra->act_gfx_alt, "-")) {
2793 secfile_insert_str(sfile, pextra->act_gfx_alt, "%s.act_gfx_alt", path);
2794 }
2795 if (strcmp(pextra->act_gfx_alt2, "-")) {
2796 secfile_insert_str(sfile, pextra->act_gfx_alt2, "%s.act_gfx_alt2", path);
2797 }
2798 if (strcmp(pextra->rmact_gfx, "-")) {
2799 secfile_insert_str(sfile, pextra->rmact_gfx, "%s.rmact_gfx", path);
2800 }
2801 if (strcmp(pextra->rmact_gfx_alt, "-")) {
2802 secfile_insert_str(sfile, pextra->rmact_gfx_alt, "%s.rmact_gfx_alt", path);
2803 }
2804
2805 save_reqs_vector(sfile, &(pextra->reqs), path, "reqs");
2806 save_reqs_vector(sfile, &(pextra->rmreqs), path, "rmreqs");
2807 save_reqs_vector(sfile, &(pextra->appearance_reqs), path, "appearance_reqs");
2808 save_reqs_vector(sfile, &(pextra->disappearance_reqs), path, "disappearance_reqs");
2809
2810 worker_cause = is_extra_caused_by_worker_action(pextra);
2811 if ((!pextra->buildable && worker_cause)
2812 || (pextra->buildable && !worker_cause)) {
2813 secfile_insert_bool(sfile, pextra->buildable, "%s.buildable", path);
2814 }
2815 if (!pextra->generated) {
2816 secfile_insert_bool(sfile, pextra->generated, "%s.generated", path);
2817 }
2818 secfile_insert_int(sfile, pextra->build_time, "%s.build_time", path);
2819 secfile_insert_int(sfile, pextra->removal_time, "%s.removal_time", path);
2820 if (pextra->build_time_factor != 1) {
2821 secfile_insert_int(sfile, pextra->build_time_factor, "%s.build_time_factor", path);
2822 }
2823 if (pextra->removal_time_factor != 1) {
2824 secfile_insert_int(sfile, pextra->removal_time_factor, "%s.removal_time_factor", path);
2825 }
2826 if (pextra->infracost != 0) {
2827 secfile_insert_int(sfile, pextra->infracost, "%s.infracost", path);
2828 }
2829 if (pextra->defense_bonus != 0) {
2830 secfile_insert_int(sfile, pextra->defense_bonus, "%s.defense_bonus", path);
2831 }
2832 if (pextra->eus != EUS_NORMAL) {
2833 secfile_insert_str(sfile, extra_unit_seen_type_name(pextra->eus),
2834 "%s.unit_seen", path);
2835 }
2836 if (is_extra_caused_by(pextra, EC_APPEARANCE)
2837 && pextra->appearance_chance != RS_DEFAULT_EXTRA_APPEARANCE) {
2838 secfile_insert_int(sfile, pextra->appearance_chance, "%s.appearance_chance", path);
2839 }
2840 if (is_extra_removed_by(pextra, ERM_DISAPPEARANCE)
2841 && pextra->disappearance_chance != RS_DEFAULT_EXTRA_DISAPPEARANCE) {
2842 secfile_insert_int(sfile, pextra->disappearance_chance, "%s.disappearance_chance",
2843 path);
2844 }
2845
2846 set_count = 0;
2847 unit_class_iterate(puc) {
2848 if (BV_ISSET(pextra->native_to, uclass_index(puc))) {
2849 puc_names[set_count++] = uclass_rule_name(puc);
2850 }
2851 } unit_class_iterate_end;
2852
2853 if (set_count > 0) {
2854 secfile_insert_str_vec(sfile, puc_names, set_count,
2855 "%s.native_to", path);
2856 }
2857
2858 if (pextra->no_aggr_near_city >= 0) {
2859 secfile_insert_int(sfile, pextra->no_aggr_near_city,
2860 "%s.no_aggr_near_city", path);
2861 }
2862
2863 set_count = 0;
2864 for (flagi = 0; flagi < EF_COUNT; flagi++) {
2865 if (extra_has_flag(pextra, flagi)) {
2866 flag_names[set_count++] = extra_flag_id_name(flagi);
2867 }
2868 }
2869
2870 if (set_count > 0) {
2871 secfile_insert_str_vec(sfile, flag_names, set_count,
2872 "%s.flags", path);
2873 }
2874
2875 set_count = 0;
2876 extra_type_iterate(confl) {
2877 if (!can_extras_coexist(pextra, confl)) {
2878 extra_names[set_count++] = extra_rule_name(confl);
2879 }
2880 } extra_type_iterate_end;
2881
2882 if (set_count > 0) {
2883 secfile_insert_str_vec(sfile, extra_names, set_count,
2884 "%s.conflicts", path);
2885 }
2886
2887 set_count = 0;
2888 extra_type_iterate(top) {
2889 if (BV_ISSET(pextra->hidden_by, extra_index(top))) {
2890 extra_names[set_count++] = extra_rule_name(top);
2891 }
2892 } extra_type_iterate_end;
2893
2894 if (set_count > 0) {
2895 secfile_insert_str_vec(sfile, extra_names, set_count,
2896 "%s.hidden_by", path);
2897 }
2898
2899 set_count = 0;
2900 extra_type_iterate(top) {
2901 if (BV_ISSET(pextra->bridged_over, extra_index(top))) {
2902 extra_names[set_count++] = extra_rule_name(top);
2903 }
2904 } extra_type_iterate_end;
2905
2906 if (set_count > 0) {
2907 secfile_insert_str_vec(sfile, extra_names, set_count,
2908 "%s.bridged_over", path);
2909 }
2910
2911 save_strvec(sfile, pextra->helptext, path, "helptext");
2912
2913 } extra_type_re_active_iterate_end;
2914
2915 comment_bases(sfile);
2916
2917 sect_idx = 0;
2918 extra_type_by_cause_iterate(EC_BASE, pextra) {
2919 if (!pextra->ruledit_disabled) {
2920 char path[512];
2921 struct base_type *pbase = extra_base_get(pextra);
2922
2923 fc_snprintf(path, sizeof(path), "base_%d", sect_idx++);
2924
2925 secfile_insert_str(sfile, extra_rule_name(pextra),
2926 "%s.extra", path);
2927
2928 secfile_insert_str(sfile, base_gui_type_name(pbase->gui_type),
2929 "%s.gui_type", path);
2930
2931 if (pbase->border_sq >= 0) {
2932 secfile_insert_int(sfile, pbase->border_sq, "%s.border_sq", path);
2933 }
2934 if (pbase->vision_main_sq >= 0) {
2935 secfile_insert_int(sfile, pbase->vision_main_sq, "%s.vision_main_sq", path);
2936 }
2937 if (pbase->vision_invis_sq >= 0) {
2938 secfile_insert_int(sfile, pbase->vision_invis_sq, "%s.vision_invis_sq", path);
2939 }
2940 if (pbase->vision_subs_sq >= 0) {
2941 secfile_insert_int(sfile, pbase->vision_subs_sq, "%s.vision_subs_sq", path);
2942 }
2943 }
2944 } extra_type_by_cause_iterate_end;
2945
2946 comment_roads(sfile);
2947
2948 sect_idx = 0;
2949 extra_type_by_cause_iterate(EC_ROAD, pextra) {
2950 if (!pextra->ruledit_disabled) {
2951 struct road_type *proad = extra_road_get(pextra);
2952 char path[512];
2953 const char *flag_names[RF_COUNT];
2954 int flagi;
2955 int set_count;
2956
2957 fc_snprintf(path, sizeof(path), "road_%d", sect_idx++);
2958
2959 secfile_insert_str(sfile, extra_rule_name(pextra),
2960 "%s.extra", path);
2961
2962 secfile_insert_int(sfile, proad->move_cost, "%s.move_cost", path);
2963
2964 if (proad->move_mode != RMM_FAST_ALWAYS) {
2965 secfile_insert_str(sfile, road_move_mode_name(proad->move_mode),
2966 "%s.move_mode", path);
2967 }
2968
2969 output_type_iterate(o) {
2970 if (proad->tile_incr_const[o] != 0) {
2971 secfile_insert_int(sfile, proad->tile_incr_const[o],
2972 "%s.%s_incr_const", path, get_output_identifier(o));
2973 }
2974 if (proad->tile_incr[o] != 0) {
2975 secfile_insert_int(sfile, proad->tile_incr[o],
2976 "%s.%s_incr", path, get_output_identifier(o));
2977 }
2978 if (proad->tile_bonus[o] != 0) {
2979 secfile_insert_int(sfile, proad->tile_bonus[o],
2980 "%s.%s_bonus", path, get_output_identifier(o));
2981 }
2982 } output_type_iterate_end;
2983
2984 switch (proad->compat) {
2985 case ROCO_ROAD:
2986 secfile_insert_str(sfile, "Road", "%s.compat_special", path);
2987 break;
2988 case ROCO_RAILROAD:
2989 secfile_insert_str(sfile, "Railroad", "%s.compat_special", path);
2990 break;
2991 case ROCO_RIVER:
2992 secfile_insert_str(sfile, "River", "%s.compat_special", path);
2993 break;
2994 case ROCO_NONE:
2995 secfile_insert_str(sfile, "None", "%s.compat_special", path);
2996 break;
2997 }
2998
2999 secfile_insert_str(sfile, road_gui_type_name(proad->gui_type),
3000 "%s.gui_type", path);
3001
3002 set_count = 0;
3003 for (flagi = 0; flagi < RF_COUNT; flagi++) {
3004 if (road_has_flag(proad, flagi)) {
3005 flag_names[set_count++] = road_flag_id_name(flagi);
3006 }
3007 }
3008
3009 if (set_count > 0) {
3010 secfile_insert_str_vec(sfile, flag_names, set_count,
3011 "%s.flags", path);
3012 }
3013 }
3014 } extra_type_by_cause_iterate_end;
3015
3016 return save_ruleset_file(sfile, filename);
3017}
3018
3019/**********************************************************************/
3022 static bool save_veteran_system(struct section_file *sfile, const char *path,
3023 struct veteran_system *vsystem)
3024{
3025 const char *vlist_name[vsystem->levels];
3026 int vlist_power[vsystem->levels];
3027 int vlist_raise[vsystem->levels];
3028 int vlist_wraise[vsystem->levels];
3029 int vlist_move[vsystem->levels];
3030 int i;
3031
3032 for (i = 0; i < vsystem->levels; i++) {
3033 vlist_name[i] = rule_name_get(&(vsystem->definitions[i].name));
3034 vlist_power[i] = vsystem->definitions[i].power_fact;
3035 vlist_raise[i] = vsystem->definitions[i].base_raise_chance;
3036 vlist_wraise[i] = vsystem->definitions[i].work_raise_chance;
3037 vlist_move[i] = vsystem->definitions[i].move_bonus;
3038 }
3039
3040 secfile_insert_str_vec(sfile, vlist_name, vsystem->levels,
3041 "%s.veteran_names", path);
3042 secfile_insert_int_vec(sfile, vlist_power, vsystem->levels,
3043 "%s.veteran_power_fact", path);
3044 secfile_insert_int_vec(sfile, vlist_raise, vsystem->levels,
3045 "%s.veteran_base_raise_chance", path);
3046 secfile_insert_int_vec(sfile, vlist_wraise, vsystem->levels,
3047 "%s.veteran_work_raise_chance", path);
3048 secfile_insert_int_vec(sfile, vlist_move, vsystem->levels,
3049 "%s.veteran_move_bonus", path);
3050
3051 return TRUE;
3052}
3053
3054/**********************************************************************/
3057 static bool save_combat_bonuses(struct section_file *sfile,
3058 struct unit_type *put,
3059 char *path)
3060{
3061 int i;
3062 bool has_quiet = FALSE;
3063
3064 combat_bonus_list_iterate(put->bonuses, pbonus) {
3065 if (pbonus->quiet) {
3066 has_quiet = TRUE;
3067 }
3068 } combat_bonus_list_iterate_end;
3069
3070 i = 0;
3071
3072 combat_bonus_list_iterate(put->bonuses, pbonus) {
3073 secfile_insert_str(sfile, unit_type_flag_id_name(pbonus->flag),
3074 "%s.bonuses%d.flag", path, i);
3075 secfile_insert_str(sfile, combat_bonus_type_name(pbonus->type),
3076 "%s.bonuses%d.type", path, i);
3077 secfile_insert_int(sfile, pbonus->value,
3078 "%s.bonuses%d.value", path, i);
3079
3080 if (has_quiet) {
3081 secfile_insert_bool(sfile, pbonus->quiet,
3082 "%s.bonuses%d.quiet", path, i);
3083 }
3084
3085 i++;
3086 } combat_bonus_list_iterate_end;
3087
3088 return TRUE;
3089}
3090
3091/**********************************************************************/
3094 static bool save_units_ruleset(const char *filename, const char *name)
3095{
3096 struct section_file *sfile = create_ruleset_file(name, "unit");
3097 int i;
3098 int sect_idx;
3099 bool uflags_utype = FALSE;
3100 bool uflags_uclass = FALSE;
3101
3102 if (sfile == NULL) {
3103 return FALSE;
3104 }
3105
3106 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
3107 const char *flagname = unit_type_flag_id_name_cb(i + UTYF_USER_FLAG_1);
3108 const char *helptxt = unit_type_flag_helptxt(i + UTYF_USER_FLAG_1);
3109
3110 if (flagname != NULL) {
3111 if (!uflags_utype) {
3112 comment_uflags_utype(sfile);
3113 uflags_utype = TRUE;
3114 }
3115
3116 secfile_insert_str(sfile, flagname, "control.flags%d.name", i);
3117
3118 /* Save the user flag help text even when it is undefined. That makes
3119 * the formatting code happy. The resulting "" is ignored when the
3120 * ruleset is loaded. */
3121 secfile_insert_str(sfile, helptxt, "control.flags%d.helptxt", i);
3122 }
3123 }
3124
3125 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
3126 const char *flagname = unit_class_flag_id_name_cb(i + UCF_USER_FLAG_1);
3127 const char *helptxt = unit_class_flag_helptxt(i + UCF_USER_FLAG_1);
3128
3129 if (flagname != NULL) {
3130 if (!uflags_uclass) {
3131 /* TODO: Uncomment this, once there's a way to stop
3132 * the comment getting written inside preceding
3133 * utype flags table. */
3134 /* comment_uflags_uclass(sfile); */
3135 uflags_uclass = TRUE;
3136 }
3137
3138 secfile_insert_str(sfile, flagname, "control.class_flags%d.name", i);
3139
3140 /* Save the user flag help text even when it is undefined. That makes
3141 * the formatting code happy. The resulting "" is ignored when the
3142 * ruleset is loaded. */
3143 secfile_insert_str(sfile, helptxt,
3144 "control.class_flags%d.helptxt", i);
3145 }
3146 }
3147
3148 save_veteran_system(sfile, "veteran_system", game.veteran);
3149
3150 comment_uclasses(sfile);
3151
3152 sect_idx = 0;
3153 unit_class_re_active_iterate(puc) {
3154 char path[512];
3155 const char *flag_names[UCF_COUNT];
3156 int flagi;
3157 int set_count;
3158
3159 fc_snprintf(path, sizeof(path), "unitclass_%d", sect_idx++);
3160
3161 save_name_translation(sfile, &(puc->name), path);
3162
3163 secfile_insert_int(sfile, puc->min_speed / SINGLE_MOVE,
3164 "%s.min_speed", path);
3165 secfile_insert_int(sfile, puc->hp_loss_pct, "%s.hp_loss_pct", path);
3166 if (puc->non_native_def_pct != 100) {
3167 secfile_insert_int(sfile, puc->non_native_def_pct,
3168 "%s.non_native_def_pct", path);
3169 }
3170
3171 set_count = 0;
3172 for (flagi = 0; flagi < UCF_COUNT; flagi++) {
3173 if (uclass_has_flag(puc, flagi)) {
3174 flag_names[set_count++] = unit_class_flag_id_name(flagi);
3175 }
3176 }
3177
3178 if (set_count > 0) {
3179 secfile_insert_str_vec(sfile, flag_names, set_count,
3180 "%s.flags", path);
3181 }
3182
3183 save_strvec(sfile, puc->helptext, path, "helptext");
3184
3185 } unit_class_re_active_iterate_end;
3186
3187 comment_utypes(sfile);
3188
3189 sect_idx = 0;
3190 unit_type_re_active_iterate(put) {
3191 if (!put->ruledit_disabled) {
3192 char path[512];
3193 const char *flag_names[UTYF_LAST_USER_FLAG + 1];
3194 int flagi;
3195 int set_count;
3196
3197 fc_snprintf(path, sizeof(path), "unit_%d", sect_idx++);
3198
3199 save_name_translation(sfile, &(put->name), path);
3200
3201 secfile_insert_str(sfile, uclass_rule_name(put->uclass),
3202 "%s.class", path);
3203
3204 save_reqs_vector(sfile, &(put->build_reqs), path, "reqs");
3205
3206 if (put->obsoleted_by != NULL) {
3207 secfile_insert_str(sfile, utype_rule_name(put->obsoleted_by),
3208 "%s.obsolete_by", path);
3209 }
3210
3211 secfile_insert_str(sfile, put->graphic_str, "%s.graphic", path);
3212 if (strcmp("-", put->graphic_alt)) {
3213 secfile_insert_str(sfile, put->graphic_alt, "%s.graphic_alt", path);
3214 }
3215 if (strcmp("-", put->graphic_alt2)) {
3216 secfile_insert_str(sfile, put->graphic_alt2, "%s.graphic_alt2", path);
3217 }
3218 if (strcmp("-", put->sound_move)) {
3219 secfile_insert_str(sfile, put->sound_move, "%s.sound_move", path);
3220 }
3221 if (strcmp("-", put->sound_move_alt)) {
3222 secfile_insert_str(sfile, put->sound_move_alt, "%s.sound_move_alt", path);
3223 }
3224 if (strcmp("-", put->sound_fight)) {
3225 secfile_insert_str(sfile, put->sound_fight, "%s.sound_fight", path);
3226 }
3227 if (strcmp("-", put->sound_fight_alt)) {
3228 secfile_insert_str(sfile, put->sound_fight_alt, "%s.sound_fight_alt", path);
3229 }
3230
3231 secfile_insert_int(sfile, put->build_cost, "%s.build_cost", path);
3232 secfile_insert_int(sfile, put->pop_cost, "%s.pop_cost", path);
3233 secfile_insert_int(sfile, put->attack_strength, "%s.attack", path);
3234 secfile_insert_int(sfile, put->defense_strength, "%s.defense", path);
3235 secfile_insert_int(sfile, put->move_rate / SINGLE_MOVE, "%s.move_rate", path);
3236 secfile_insert_int(sfile, put->vision_radius_sq, "%s.vision_radius_sq", path);
3237 secfile_insert_int(sfile, put->transport_capacity, "%s.transport_cap", path);
3238
3239 save_uclass_vec(sfile, &(put->cargo), path, "cargo", FALSE);
3240 save_uclass_vec(sfile, &(put->embarks), path, "embarks", TRUE);
3241 save_uclass_vec(sfile, &(put->disembarks), path, "disembarks", TRUE);
3242
3243 if (put->vlayer != V_MAIN) {
3244 secfile_insert_str(sfile, vision_layer_name(put->vlayer),
3245 "%s.vision_layer", path);
3246 }
3247
3248 secfile_insert_int(sfile, put->hp, "%s.hitpoints", path);
3249 secfile_insert_int(sfile, put->firepower, "%s.firepower", path);
3250 secfile_insert_int(sfile, put->fuel, "%s.fuel", path);
3251 secfile_insert_int(sfile, put->happy_cost, "%s.uk_happy", path);
3252
3253 output_type_iterate(o) {
3254 if (put->upkeep[o] != 0) {
3255 secfile_insert_int(sfile, put->upkeep[o], "%s.uk_%s",
3256 path, get_output_identifier(o));
3257 }
3258 } output_type_iterate_end;
3259
3260 if (put->converted_to != NULL) {
3261 secfile_insert_str(sfile, utype_rule_name(put->converted_to),
3262 "%s.convert_to", path);
3263 }
3264 if (put->convert_time != 1) {
3265 secfile_insert_int(sfile, put->convert_time, "%s.convert_time", path);
3266 }
3267
3268 save_combat_bonuses(sfile, put, path);
3269 save_uclass_vec(sfile, &(put->targets), path, "targets", TRUE);
3270
3271 if (put->veteran != NULL) {
3272 save_veteran_system(sfile, path, put->veteran);
3273 }
3274
3275 if (put->paratroopers_range != 0) {
3276 secfile_insert_int(sfile, put->paratroopers_range,
3277 "%s.paratroopers_range", path);
3278 }
3279 if (put->bombard_rate != 0) {
3280 secfile_insert_int(sfile, put->bombard_rate,
3281 "%s.bombard_rate", path);
3282 }
3283 if (put->city_slots != 0) {
3284 secfile_insert_int(sfile, put->city_slots,
3285 "%s.city_slots", path);
3286 }
3287 if (put->city_size != 1) {
3288 secfile_insert_int(sfile, put->city_size,
3289 "%s.city_size", path);
3290 }
3291
3292 secfile_insert_str(sfile, transp_def_type_name(put->tp_defense),
3293 "%s.tp_defense", path);
3294
3295 set_count = 0;
3296 for (flagi = 0; flagi <= UTYF_LAST_USER_FLAG; flagi++) {
3297 if (utype_has_flag(put, flagi)) {
3298 flag_names[set_count++] = unit_type_flag_id_name(flagi);
3299 }
3300 }
3301
3302 if (set_count > 0) {
3303 secfile_insert_str_vec(sfile, flag_names, set_count,
3304 "%s.flags", path);
3305 }
3306
3307 set_count = 0;
3308 for (flagi = L_FIRST; flagi < L_LAST; flagi++) {
3309 if (utype_has_role(put, flagi)) {
3310 flag_names[set_count++] = unit_role_id_name(flagi);
3311 }
3312 }
3313
3314 if (set_count > 0) {
3315 secfile_insert_str_vec(sfile, flag_names, set_count,
3316 "%s.roles", path);
3317 }
3318
3319 save_strvec(sfile, put->helptext, path, "helptext");
3320 }
3321 } unit_type_re_active_iterate_end;
3322
3323 return save_ruleset_file(sfile, filename);
3324}
3325
3326/**********************************************************************/
3329 static bool save_script_lua(const char *filename, const char *name,
3330 const char *buffer)
3331{
3332 if (buffer != NULL) {
3333 FILE *ffile = fc_fopen(filename, "w");
3334 int full_len = strlen(buffer);
3335 int len;
3336
3337 if (ffile != NULL) {
3338 len = fwrite(buffer, 1, full_len, ffile);
3339
3340 if (len != full_len) {
3341 return FALSE;
3342 }
3343
3344 fclose(ffile);
3345 } else {
3346 return FALSE;
3347 }
3348 }
3349
3350 return TRUE;
3351}
3352
3353/**********************************************************************/
3356 static bool save_luadata(const char *filename)
3357{
3358 if (game.server.luadata != NULL) {
3359 return secfile_save(game.server.luadata, filename, 0, FZ_PLAIN);
3360 }
3361
3362 return TRUE;
3363}
3364
3365/**********************************************************************/
3368 bool save_ruleset(const char *path, const char *name, struct rule_data *data)
3369{
3370 if (make_dir(path)) {
3371 bool success = TRUE;
3372 char filename[500];
3373
3374 if (success) {
3375 fc_snprintf(filename, sizeof(filename), "%s/buildings.ruleset", path);
3376 success = save_buildings_ruleset(filename, name);
3377 }
3378
3379 if (success) {
3380 fc_snprintf(filename, sizeof(filename), "%s/styles.ruleset", path);
3381 success = save_styles_ruleset(filename, name);
3382 }
3383
3384 if (success) {
3385 fc_snprintf(filename, sizeof(filename), "%s/cities.ruleset", path);
3386 success = save_cities_ruleset(filename, name);
3387 }
3388
3389 if (success) {
3390 fc_snprintf(filename, sizeof(filename), "%s/effects.ruleset", path);
3391 success = save_effects_ruleset(filename, name);
3392 }
3393
3394 if (success) {
3395 fc_snprintf(filename, sizeof(filename), "%s/game.ruleset", path);
3396 success = save_game_ruleset(filename, name);
3397 }
3398
3399 if (success) {
3400 fc_snprintf(filename, sizeof(filename), "%s/governments.ruleset", path);
3401 success = save_governments_ruleset(filename, name);
3402 }
3403
3404 if (success) {
3405 fc_snprintf(filename, sizeof(filename), "%s/nations.ruleset", path);
3406 success = save_nations_ruleset(filename, name, data);
3407 }
3408
3409 if (success) {
3410 fc_snprintf(filename, sizeof(filename), "%s/techs.ruleset", path);
3411 success = save_techs_ruleset(filename, name);
3412 }
3413
3414 if (success) {
3415 fc_snprintf(filename, sizeof(filename), "%s/terrain.ruleset", path);
3416 success = save_terrain_ruleset(filename, name);
3417 }
3418
3419 if (success) {
3420 fc_snprintf(filename, sizeof(filename), "%s/units.ruleset", path);
3421 success = save_units_ruleset(filename, name);
3422 }
3423
3424 if (success) {
3425 fc_snprintf(filename,sizeof(filename), "%s/actions.ruleset",path);
3426 success = save_actions_ruleset(filename, name);
3427 }
3428
3429 if (success) {
3430 fc_snprintf(filename, sizeof(filename), "%s/script.lua", path);
3431 success = save_script_lua(filename, name, get_script_buffer());
3432 }
3433
3434 if (success) {
3435 fc_snprintf(filename, sizeof(filename), "%s/parser.lua", path);
3436 success = save_script_lua(filename, name, get_parser_buffer());
3437 }
3438
3439 if (success) {
3440 fc_snprintf(filename, sizeof(filename), "%s/luadata.txt", path);
3441 success = save_luadata(filename);
3442 }
3443
3444 return success;
3445 } else {
3446 log_error(_("Failed to create directory %s"), path);
3447 return FALSE;
3448 }
3449
3450 return TRUE;
3451}
achievements.h
achievements_iterate_end
#define achievements_iterate_end
Definition achievements.h:70
achievements_iterate
#define achievements_iterate(_ach_)
Definition achievements.h:64
action_min_range_ruleset_var_name
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:7113
action_blocked_by_ruleset_var_name
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7749
action_array_end
void action_array_end(action_id *act_array, int size)
Definition actions.c:6471
action_is_in_use
bool action_is_in_use(struct action *paction)
Definition actions.c:6400
action_post_success_forced_ruleset_var_name
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7923
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1968
action_actor_consuming_always_ruleset_var_name
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:7593
action_max_range_ruleset_var_name
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:7272
action_target_kind_ruleset_var_name
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:7439
action_ui_name_default
const char * action_ui_name_default(int act)
Definition actions.c:6773
action_auto_perf_by_number
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:6439
action_ui_name_ruleset_var_name
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:6508
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:517
enabler_get_action
#define enabler_get_action(_enabler_)
Definition actions.h:431
ACTION_AUTO_MOVED_ADJ
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:609
ACTION_AUTO_UPKEEP_GOLD
#define ACTION_AUTO_UPKEEP_GOLD
Definition actions.h:607
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
NUM_ACTIONS
#define NUM_ACTIONS
Definition actions.h:313
ACTION_AUTO_ESCAPE_STACK
#define ACTION_AUTO_ESCAPE_STACK
Definition actions.h:615
ACTION_AUTO_ESCAPE_CITY
#define ACTION_AUTO_ESCAPE_CITY
Definition actions.h:614
ACTION_DISTANCE_UNLIMITED
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:355
ACTION_AUTO_POST_WIPE_UNITS
#define ACTION_AUTO_POST_WIPE_UNITS
Definition actions.h:616
ACTION_AUTO_UPKEEP_SHIELD
#define ACTION_AUTO_UPKEEP_SHIELD
Definition actions.h:608
ACTION_AUTO_POST_BRIBE
#define ACTION_AUTO_POST_BRIBE
Definition actions.h:610
action_iterate_end
#define action_iterate_end
Definition actions.h:463
MAX_NUM_ACTIONS
#define MAX_NUM_ACTIONS
Definition actions.h:312
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:511
action_iterate
#define action_iterate(_act_)
Definition actions.h:459
ACTION_AUTO_UPKEEP_FOOD
#define ACTION_AUTO_UPKEEP_FOOD
Definition actions.h:606
ACTION_AUTO_POST_ATTACK
#define ACTION_AUTO_POST_ATTACK
Definition actions.h:611
ACTION_NONE
#define ACTION_NONE
Definition actions.h:309
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
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astring.h
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
get_output_identifier
const char * get_output_identifier(Output_type_id output)
Definition city.c:618
city_styles
static const struct city struct citystyle * city_styles
Definition city.c:83
output_type_iterate
#define output_type_iterate(output)
Definition city.h:833
output_type_iterate_end
#define output_type_iterate_end
Definition city.h:839
comment_borders_radius_permanent
void comment_borders_radius_permanent(struct section_file *sfile)
Definition comments.c:808
uflags_building
char * uflags_building
Definition comments.c:52
comment_uflags_utype
void comment_uflags_utype(struct section_file *sfile)
Definition comments.c:465
comment_combat_rules_nuke_defender_survival
void comment_combat_rules_nuke_defender_survival(struct section_file *sfile)
Definition comments.c:764
comment_roads
void comment_roads(struct section_file *sfile)
Definition comments.c:401
comment_civstyle_granary
void comment_civstyle_granary(struct section_file *sfile)
Definition comments.c:594
comment_research_tech_leakage
void comment_research_tech_leakage(struct section_file *sfile)
Definition comments.c:844
comment_actions_ui_names
void comment_actions_ui_names(struct section_file *sfile)
Definition comments.c:782
comment_uclasses
void comment_uclasses(struct section_file *sfile)
Definition comments.c:353
comment_calendar_fragments
void comment_calendar_fragments(struct section_file *sfile)
Definition comments.c:888
comment_actions_quiet_actions
void comment_actions_quiet_actions(struct section_file *sfile)
Definition comments.c:799
comment_uflags_terrain
void comment_uflags_terrain(struct section_file *sfile)
Definition comments.c:481
comment_citystyles
void comment_citystyles(struct section_file *sfile)
Definition comments.c:417
comment_govs
void comment_govs(struct section_file *sfile)
Definition comments.c:337
comment_combat_rules_low_fp_pearl_harbour
void comment_combat_rules_low_fp_pearl_harbour(struct section_file *sfile)
Definition comments.c:725
comment_research_base_tech_cost
void comment_research_base_tech_cost(struct section_file *sfile)
Definition comments.c:826
comment_research_tech_cost_style
void comment_research_tech_cost_style(struct section_file *sfile)
Definition comments.c:817
comment_combat_rules_only_killing_veteran
void comment_combat_rules_only_killing_veteran(struct section_file *sfile)
Definition comments.c:675
comment_bases
void comment_bases(struct section_file *sfile)
Definition comments.c:393
comment_terrains
void comment_terrains(struct section_file *sfile)
Definition comments.c:369
comment_uflags_tech
void comment_uflags_tech(struct section_file *sfile)
Definition comments.c:497
comment_file_header
void comment_file_header(struct section_file *sfile)
Definition comments.c:305
comment_effects
void comment_effects(struct section_file *sfile)
Definition comments.c:433
comment_actions_dc_initial_odds
void comment_actions_dc_initial_odds(struct section_file *sfile)
Definition comments.c:790
comment_combat_rules_scaled_veterancy
void comment_combat_rules_scaled_veterancy(struct section_file *sfile)
Definition comments.c:695
comment_research_upkeep_style
void comment_research_upkeep_style(struct section_file *sfile)
Definition comments.c:853
comment_disasters
void comment_disasters(struct section_file *sfile)
Definition comments.c:449
comment_clauses
void comment_clauses(struct section_file *sfile)
Definition comments.c:569
comment_goods
void comment_goods(struct section_file *sfile)
Definition comments.c:521
uflags_tech
char * uflags_tech
Definition comments.c:51
comment_civstyle_gameloss_style
void comment_civstyle_gameloss_style(struct section_file *sfile)
Definition comments.c:612
uflags_extra
char * uflags_extra
Definition comments.c:50
comment_civstyle_gold_upkeep_style
void comment_civstyle_gold_upkeep_style(struct section_file *sfile)
Definition comments.c:621
comment_extras
void comment_extras(struct section_file *sfile)
Definition comments.c:385
comment_combat_rules_low_fp_nonnat_bombard
void comment_combat_rules_low_fp_nonnat_bombard(struct section_file *sfile)
Definition comments.c:745
comment_ueffs
void comment_ueffs(struct section_file *sfile)
Definition comments.c:441
comment_techs
void comment_techs(struct section_file *sfile)
Definition comments.c:329
comment_nations
void comment_nations(struct section_file *sfile)
Definition comments.c:545
comment_trade_settings
void comment_trade_settings(struct section_file *sfile)
Definition comments.c:513
comment_combat_rules_low_fp_combat_bonus
void comment_combat_rules_low_fp_combat_bonus(struct section_file *sfile)
Definition comments.c:735
comment_nations_ruledit
void comment_nations_ruledit(struct section_file *sfile)
Definition comments.c:586
comment_civstyle_homeless_gold_upkeep
void comment_civstyle_homeless_gold_upkeep(struct section_file *sfile)
Definition comments.c:630
comment_nationgroups
void comment_nationgroups(struct section_file *sfile)
Definition comments.c:553
comment_specialists
void comment_specialists(struct section_file *sfile)
Definition comments.c:537
comment_musicstyles
void comment_musicstyles(struct section_file *sfile)
Definition comments.c:425
comment_civstyle_airlift_always
void comment_civstyle_airlift_always(struct section_file *sfile)
Definition comments.c:639
comment_resources
void comment_resources(struct section_file *sfile)
Definition comments.c:377
comment_civstyle_ransom_gold
void comment_civstyle_ransom_gold(struct section_file *sfile)
Definition comments.c:603
comment_tech_classes
void comment_tech_classes(struct section_file *sfile)
Definition comments.c:321
comment_culture_migration_pml
void comment_culture_migration_pml(struct section_file *sfile)
Definition comments.c:879
comment_combat_rules_only_real_fight_veteran
void comment_combat_rules_only_real_fight_veteran(struct section_file *sfile)
Definition comments.c:685
uflags_uclass
char * uflags_uclass
Definition comments.c:48
comment_research_free_tech_method
void comment_research_free_tech_method(struct section_file *sfile)
Definition comments.c:862
comment_combat_rules_nuke_pop_loss
void comment_combat_rules_nuke_pop_loss(struct section_file *sfile)
Definition comments.c:755
comment_utypes
void comment_utypes(struct section_file *sfile)
Definition comments.c:361
uflags_utype
char * uflags_utype
Definition comments.c:47
comment_research_min_tech_cost
void comment_research_min_tech_cost(struct section_file *sfile)
Definition comments.c:835
comment_culture_history_interest
void comment_culture_history_interest(struct section_file *sfile)
Definition comments.c:871
comment_policies
void comment_policies(struct section_file *sfile)
Definition comments.c:345
comment_combat_rules_low_fp_badwallattacker
void comment_combat_rules_low_fp_badwallattacker(struct section_file *sfile)
Definition comments.c:715
comment_achievements
void comment_achievements(struct section_file *sfile)
Definition comments.c:457
comment_combat_rules_damage_reduces_bombard_rate
void comment_combat_rules_damage_reduces_bombard_rate(struct section_file *sfile)
Definition comments.c:705
comment_counters
void comment_counters(struct section_file *sfile)
Definition comments.c:577
comment_styles
void comment_styles(struct section_file *sfile)
Definition comments.c:409
comment_combat_rules_tired_attack
void comment_combat_rules_tired_attack(struct section_file *sfile)
Definition comments.c:666
comment_uflags_building
void comment_uflags_building(struct section_file *sfile)
Definition comments.c:505
comment_buildings
void comment_buildings(struct section_file *sfile)
Definition comments.c:313
comment_enablers
void comment_enablers(struct section_file *sfile)
Definition comments.c:529
comment_nationsets
void comment_nationsets(struct section_file *sfile)
Definition comments.c:561
comment_wonder_visibility_small_wonders
void comment_wonder_visibility_small_wonders(struct section_file *sfile)
Definition comments.c:648
comment_incite_cost
void comment_incite_cost(struct section_file *sfile)
Definition comments.c:657
comment_auto_attack
void comment_auto_attack(struct section_file *sfile)
Definition comments.c:774
incite_cost
char * incite_cost
Definition comments.c:74
comments.h
counters.h
counters_re_iterate_end
#define counters_re_iterate_end
Definition counters.h:75
counters_re_iterate
#define counters_re_iterate(pcount)
Definition counters.h:67
clause_info_get
struct clause_info * clause_info_get(enum clause_type type)
Definition diptreaty.c:276
disaster_type_iterate
#define disaster_type_iterate(_p)
Definition disaster.h:80
disaster_type_iterate_end
#define disaster_type_iterate_end
Definition disaster.h:86
reqs
struct @21::@22 reqs
iterate_effect_cache
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1323
user_effect_ai_valued_as
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1359
EFT_USER_EFFECT_LAST
#define EFT_USER_EFFECT_LAST
Definition effects.h:358
extra_flag_helptxt
const char * extra_flag_helptxt(enum extra_flag_id id)
Definition extras.c:974
is_extra_caused_by_worker_action
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1032
extra_has_flag
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:861
extra_flag_id_name_cb
const char * extra_flag_id_name_cb(enum extra_flag_id flag)
Definition extras.c:962
can_extras_coexist
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1003
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_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
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_type_re_active_iterate_end
#define extra_type_re_active_iterate_end
Definition extras.h:329
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_re_active_iterate
#define extra_type_re_active_iterate(_p)
Definition extras.h:325
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
MAX_NUM_USER_BUILDING_FLAGS
#define MAX_NUM_USER_BUILDING_FLAGS
Definition fc_types.h:681
ROCO_RAILROAD
@ ROCO_RAILROAD
Definition fc_types.h:1254
ROCO_NONE
@ ROCO_NONE
Definition fc_types.h:1254
ROCO_RIVER
@ ROCO_RIVER
Definition fc_types.h:1254
ROCO_ROAD
@ ROCO_ROAD
Definition fc_types.h:1254
MAX_NUM_NATION_SETS
#define MAX_NUM_NATION_SETS
Definition fc_types.h:57
MAX_NUM_BUILDING_LIST
#define MAX_NUM_BUILDING_LIST
Definition fc_types.h:46
action_id
int action_id
Definition fc_types.h:392
MAX_CALENDAR_FRAGMENTS
#define MAX_CALENDAR_FRAGMENTS
Definition fc_types.h:62
MAX_NUM_NATION_GROUPS
#define MAX_NUM_NATION_GROUPS
Definition fc_types.h:58
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
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
UCL_LAST
#define UCL_LAST
Definition fc_types.h:420
skip_intl_qualifier_prefix
const char * skip_intl_qualifier_prefix(const char *str)
Definition fcintl.c:48
_
#define _(String)
Definition fcintl.h:67
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game.h
RS_DEFAULT_RANSOM_GOLD
#define RS_DEFAULT_RANSOM_GOLD
Definition game.h:864
RS_DEFAULT_CIVIL_WAR_UNHAPPY
#define RS_DEFAULT_CIVIL_WAR_UNHAPPY
Definition game.h:850
RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:856
RS_DEFAULT_NUKE_POP_LOSS_PCT
#define RS_DEFAULT_NUKE_POP_LOSS_PCT
Definition game.h:853
RS_DEFAULT_BASE_POLLUTION
#define RS_DEFAULT_BASE_POLLUTION
Definition game.h:836
RS_DEFAULT_INCITE_TOTAL_FCT
#define RS_DEFAULT_INCITE_TOTAL_FCT
Definition game.h:809
RS_DEFAULT_ILLNESS_BASE_FACTOR
#define RS_DEFAULT_ILLNESS_BASE_FACTOR
Definition game.h:767
RS_DEFAULT_NEG_YEAR_LABEL
#define RS_DEFAULT_NEG_YEAR_LABEL
Definition game.h:763
RS_DEFAULT_INCITE_IMPROVEMENT_FCT
#define RS_DEFAULT_INCITE_IMPROVEMENT_FCT
Definition game.h:801
RS_ACTION_NO_MAX_DISTANCE
#define RS_ACTION_NO_MAX_DISTANCE
Definition game.h:888
RS_DEFAULT_BASE_BRIBE_COST
#define RS_DEFAULT_BASE_BRIBE_COST
Definition game.h:860
RS_DEFAULT_TECH_UPKEEP_DIVIDER
#define RS_DEFAULT_TECH_UPKEEP_DIVIDER
Definition game.h:874
RS_DEFAULT_HAPPY_COST
#define RS_DEFAULT_HAPPY_COST
Definition game.h:841
RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
#define RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
Definition game.h:878
RS_DEFAULT_GRANARY_FOOD_INC
#define RS_DEFAULT_GRANARY_FOOD_INC
Definition game.h:815
RS_DEFAULT_ILLNESS_ON
#define RS_DEFAULT_ILLNESS_ON
Definition game.h:765
GAME_DEFAULT_CELEBRATESIZE
#define GAME_DEFAULT_CELEBRATESIZE
Definition game.h:498
RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
#define RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
Definition game.h:879
RS_DEFAULT_CIVIL_WAR_CELEB
#define RS_DEFAULT_CIVIL_WAR_CELEB
Definition game.h:849
RS_DEFAULT_UPGRADE_VETERAN_LOSS
#define RS_DEFAULT_UPGRADE_VETERAN_LOSS
Definition game.h:870
RS_DEFAULT_CALENDAR_SKIP_0
#define RS_DEFAULT_CALENDAR_SKIP_0
Definition game.h:783
RS_DEFAULT_CITY_RADIUS_SQ
#define RS_DEFAULT_CITY_RADIUS_SQ
Definition game.h:828
GAME_DEFAULT_START_YEAR
#define GAME_DEFAULT_START_YEAR
Definition game.h:739
RS_DEFAULT_BORDER_SIZE_EFFECT
#define RS_DEFAULT_BORDER_SIZE_EFFECT
Definition game.h:789
RS_DEFAULT_PILLAGE_SELECT
#define RS_DEFAULT_PILLAGE_SELECT
Definition game.h:868
RS_DEFAULT_POS_YEAR_LABEL
#define RS_DEFAULT_POS_YEAR_LABEL
Definition game.h:761
RS_DEFAULT_VIS_RADIUS_SQ
#define RS_DEFAULT_VIS_RADIUS_SQ
Definition game.h:832
RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:793
RS_DEFAULT_TIRED_ATTACK
#define RS_DEFAULT_TIRED_ATTACK
Definition game.h:852
RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
#define RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
Definition game.h:880
RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
#define RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:775
RS_DEFAULT_FOOD_COST
#define RS_DEFAULT_FOOD_COST
Definition game.h:845
RS_DEFAULT_INCITE_UNIT_FCT
#define RS_DEFAULT_INCITE_UNIT_FCT
Definition game.h:805
RS_DEFAULT_INCITE_BASE_COST
#define RS_DEFAULT_INCITE_BASE_COST
Definition game.h:797
GAME_DEFAULT_ANGRYCITIZEN
#define GAME_DEFAULT_ANGRYCITIZEN
Definition game.h:389
RS_DEFAULT_CITY_CENTER_OUTPUT
#define RS_DEFAULT_CITY_CENTER_OUTPUT
Definition game.h:819
RS_DEFAULT_ILLNESS_POLLUTION_PCT
#define RS_DEFAULT_ILLNESS_POLLUTION_PCT
Definition game.h:779
RS_DEFAULT_ILLNESS_MIN_SIZE
#define RS_DEFAULT_ILLNESS_MIN_SIZE
Definition game.h:771
RS_DEFAULT_BORDER_RADIUS_SQ_CITY
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY
Definition game.h:785
ruler_title_female_untranslated_name
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:383
ruler_title_male_untranslated_name
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:374
government_rule_name
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
government.h
governments_iterate
#define governments_iterate(NAME_pgov)
Definition government.h:120
governments_re_active_iterate
#define governments_re_active_iterate(_p)
Definition government.h:125
governments_re_active_iterate_end
#define governments_re_active_iterate_end
Definition government.h:129
governments_iterate_end
#define governments_iterate_end
Definition government.h:123
title
const char * title
Definition repodlgs.c:1314
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
impr_flag_id_name_cb
const char * impr_flag_id_name_cb(enum impr_flag_id flag)
Definition improvement.c:1213
improvement_rule_name
const char * improvement_rule_name(const struct impr_type *pimprove)
Definition improvement.c:252
improvement_has_flag
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Definition improvement.c:383
impr_flag_helptxt
const char * impr_flag_helptxt(enum impr_flag_id id)
Definition improvement.c:1225
improvement_re_active_iterate_end
#define improvement_re_active_iterate_end
Definition improvement.h:214
improvement_re_active_iterate
#define improvement_re_active_iterate(_p)
Definition improvement.h:210
B_LAST
#define B_LAST
Definition improvement.h:42
name
const char * name
Definition inputfile.c:127
FZ_PLAIN
@ FZ_PLAIN
Definition ioz.h:37
fc_assert
#define fc_assert(condition)
Definition log.h:176
log_error
#define log_error(message,...)
Definition log.h:103
terrain_control
struct terrain_misc terrain_control
Definition map.c:69
map.h
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
movement.h
SINGLE_MOVE
#define SINGLE_MOVE
Definition movement.h:26
multipliers.h
multipliers_iterate
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
multipliers_iterate_end
#define multipliers_iterate_end
Definition multipliers.h:67
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
nation_city_name
const char * nation_city_name(const struct nation_city *pncity)
Definition nation.c:412
nation_rule_name
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
nation_leader_is_male
bool nation_leader_is_male(const struct nation_leader *pleader)
Definition nation.c:290
nation_city_terrain_preference
enum nation_city_preference nation_city_terrain_preference(const struct nation_city *pncity, const struct terrain *pterrain)
Definition nation.c:422
nation_group_rule_name
const char * nation_group_rule_name(const struct nation_group *pgroup)
Definition nation.c:1079
nation_set_untranslated_name
const char * nation_set_untranslated_name(const struct nation_set *pset)
Definition nation.c:797
nation_is_in_group
bool nation_is_in_group(const struct nation_type *pnation, const struct nation_group *pgroup)
Definition nation.c:1099
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_city_river_preference
enum nation_city_preference nation_city_river_preference(const struct nation_city *pncity)
Definition nation.c:434
nation_by_rule_name
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:121
nation_leader_name
const char * nation_leader_name(const struct nation_leader *pleader)
Definition nation.c:281
nation_set_rule_name
const char * nation_set_rule_name(const struct nation_set *pset)
Definition nation.c:807
nation.h
nation_leader_list_iterate
#define nation_leader_list_iterate(leaderlist, pleader)
Definition nation.h:57
nation_list_iterate
#define nation_list_iterate(nationlist, pnation)
Definition nation.h:84
nation_sets_iterate_end
#define nation_sets_iterate_end
Definition nation.h:305
nation_sets_iterate
#define nation_sets_iterate(NAME_pset)
Definition nation.h:301
nations_iterate_end
#define nations_iterate_end
Definition nation.h:336
NCP_NONE
@ NCP_NONE
Definition nation.h:41
NCP_DISLIKE
@ NCP_DISLIKE
Definition nation.h:40
NCP_LIKE
@ NCP_LIKE
Definition nation.h:42
nation_city_list_iterate
#define nation_city_list_iterate(citylist, pncity)
Definition nation.h:48
nation_list_iterate_end
#define nation_list_iterate_end
Definition nation.h:86
nation_city_list_iterate_end
#define nation_city_list_iterate_end
Definition nation.h:50
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_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
len
int len
Definition packhand.c:127
registry.h
secfile_new
struct section_file * secfile_new(bool allow_duplicates)
Definition section_file.c:73
entry_name
const char * entry_name(const struct entry *pentry)
Definition registry_ini.c:3357
entry_str_set_gt_marking
bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking)
Definition registry_ini.c:3614
secfile_save
bool secfile_save(const struct section_file *secfile, const char *filename, int compression_level, enum fz_method compression_method)
Definition registry_ini.c:644
secfile_insert_include
struct section * secfile_insert_include(struct section_file *secfile, const char *filename)
Definition registry_ini.c:1212
secfile_insert_filereference
struct entry * secfile_insert_filereference(struct section_file *secfile, const char *filename, const char *path,...)
Definition registry_ini.c:1396
secfile_insert_int
#define secfile_insert_int(secfile, value, path,...)
Definition registry_ini.h:116
secfile_insert_enum_vec
#define secfile_insert_enum_vec(secfile, enumerators, dim, specenum_type, path,...)
Definition registry_ini.h:320
secfile_insert_enum
#define secfile_insert_enum(secfile, enumerator, specenum_type, path,...)
Definition registry_ini.h:266
secfile_insert_int_vec
#define secfile_insert_int_vec(secfile, values, dim, path,...)
Definition registry_ini.h:133
secfile_insert_str_vec
#define secfile_insert_str_vec(secfile, strings, dim, path,...)
Definition registry_ini.h:201
secfile_insert_str
#define secfile_insert_str(secfile, string, path,...)
Definition registry_ini.h:170
secfile_insert_bool
#define secfile_insert_bool(secfile, value, path,...)
Definition registry_ini.h:79
secfile_insert_enum_vec_comment
#define secfile_insert_enum_vec_comment(secfile, enumerators, dim, specenum_type, comment, path,...)
Definition registry_ini.h:324
secfile_insert_enum_data
#define secfile_insert_enum_data(secfile, value, bitwise, name_fn, data, path,...)
Definition registry_ini.h:345
req_to_fstring
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
Definition requirements.c:1015
universal_rule_name
const char * universal_rule_name(const struct universal *psource)
Definition requirements.c:6597
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_save
void rgbcolor_save(struct section_file *file, const struct rgbcolor *prgbcolor, char *path,...)
Definition rgbcolor.c:121
rgbcolor.h
rgbcolor_list_iterate_end
#define rgbcolor_list_iterate_end
Definition rgbcolor.h:45
rgbcolor_list_iterate
#define rgbcolor_list_iterate(rgbcolorlist, prgbcolor)
Definition rgbcolor.h:43
road_has_flag
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
save_reqs_vector
static bool save_reqs_vector(struct section_file *sfile, const struct requirement_vector *reqs, const char *path, const char *entry)
Definition rulesave.c:149
save_tech_list
static bool save_tech_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:209
save_name_translation
static bool save_name_translation(struct section_file *sfile, struct name_translation *name, const char *path)
Definition rulesave.c:126
save_terrain_ref
static bool save_terrain_ref(struct section_file *sfile, const struct terrain *save, const struct terrain *pthis, const char *path, const char *entry)
Definition rulesave.c:249
save_unit_list
static bool save_unit_list(struct section_file *sfile, struct unit_type **input, const char *path, const char *entry)
Definition rulesave.c:306
save_nations_ruleset
static bool save_nations_ruleset(const char *filename, const char *name, struct rule_data *data)
Definition rulesave.c:2201
save_action_kind
static bool save_action_kind(struct section_file *sfile, action_id act)
Definition rulesave.c:939
save_action_actor_consuming_always
static bool save_action_actor_consuming_always(struct section_file *sfile, action_id act)
Definition rulesave.c:963
save_action_max_range
static bool save_action_max_range(struct section_file *sfile, action_id act)
Definition rulesave.c:893
save_traits
static bool save_traits(struct trait_limits *traits, struct trait_limits *default_traits, struct section_file *sfile, const char *secname, const char *field_prefix)
Definition rulesave.c:1967
FORMAT_VERSION
#define FORMAT_VERSION
Definition rulesave.c:55
save_ruleset
bool save_ruleset(const char *path, const char *name, struct rule_data *data)
Definition rulesave.c:3368
save_cities_ruleset
static bool save_cities_ruleset(const char *filename, const char *name)
Definition rulesave.c:670
save_techs_ruleset
static bool save_techs_ruleset(const char *filename, const char *name)
Definition rulesave.c:2326
save_uclass_vec
static bool save_uclass_vec(struct section_file *sfile, bv_unit_classes *bits, const char *path, const char *entry, bool unreachable_only)
Definition rulesave.c:329
save_action_post_success_force
static bool save_action_post_success_force(struct section_file *sfile, int performer_slot, struct action *paction)
Definition rulesave.c:1041
save_ruleset_file
static bool save_ruleset_file(struct section_file *sfile, const char *filename)
Definition rulesave.c:378
save_veteran_system
static bool save_veteran_system(struct section_file *sfile, const char *path, struct veteran_system *vsystem)
Definition rulesave.c:3022
save_bv_actions
static bool save_bv_actions(struct section_file *sfile, bv_actions content, const char *path)
Definition rulesave.c:1070
save_default_bool
static bool save_default_bool(struct section_file *sfile, bool value, bool default_value, const char *path, const char *entry)
Definition rulesave.c:105
effect_save
static bool effect_save(struct effect *peffect, void *data)
Definition rulesave.c:797
save_game_ruleset
static bool save_game_ruleset(const char *filename, const char *name)
Definition rulesave.c:1238
save_buildings_ruleset
static bool save_buildings_ruleset(const char *filename, const char *name)
Definition rulesave.c:386
save_action_auto_uflag_block
static bool save_action_auto_uflag_block(struct section_file *sfile, const int aap, const char *uflags_path, bool(*unexpected_req)(const struct requirement *preq))
Definition rulesave.c:546
unexpected_non_otype
static bool unexpected_non_otype(const struct requirement *req)
Definition rulesave.c:640
save_building_list
static bool save_building_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:282
save_luadata
static bool save_luadata(const char *filename)
Definition rulesave.c:3356
save_governments_ruleset
static bool save_governments_ruleset(const char *filename, const char *name)
Definition rulesave.c:1880
save_action_blocked_by
static bool save_action_blocked_by(struct section_file *sfile, struct action *paction)
Definition rulesave.c:988
save_strvec
static bool save_strvec(struct section_file *sfile, struct strvec *to_save, const char *path, const char *entry)
Definition rulesave.c:356
save_actions_ruleset
static bool save_actions_ruleset(const char *filename, const char *name)
Definition rulesave.c:1103
save_units_ruleset
static bool save_units_ruleset(const char *filename, const char *name)
Definition rulesave.c:3094
save_terrain_ruleset
static bool save_terrain_ruleset(const char *filename, const char *name)
Definition rulesave.c:2432
save_muuk_action_auto
static bool save_muuk_action_auto(struct section_file *sfile, const int aap, const char *item)
Definition rulesave.c:650
save_action_range
static bool save_action_range(struct section_file *sfile, action_id act)
Definition rulesave.c:913
save_gov_ref
static bool save_gov_ref(struct section_file *sfile, const struct government *gov, const char *path, const char *entry)
Definition rulesave.c:269
save_styles_ruleset
static bool save_styles_ruleset(const char *filename, const char *name)
Definition rulesave.c:482
create_ruleset_file
static struct section_file * create_ruleset_file(const char *rsname, const char *rstype)
Definition rulesave.c:60
save_combat_bonuses
static bool save_combat_bonuses(struct section_file *sfile, struct unit_type *put, char *path)
Definition rulesave.c:3057
save_effects_ruleset
static bool save_effects_ruleset(const char *filename, const char *name)
Definition rulesave.c:827
save_default_int
static bool save_default_int(struct section_file *sfile, int value, int default_value, const char *path, const char *entry)
Definition rulesave.c:85
save_nation
static bool save_nation(struct section_file *sfile, struct nation_type *pnat, int sect_idx)
Definition rulesave.c:2013
save_script_lua
static bool save_script_lua(const char *filename, const char *name, const char *buffer)
Definition rulesave.c:3329
save_action_auto_actions
static bool save_action_auto_actions(struct section_file *sfile, const int aap, const char *actions_path)
Definition rulesave.c:597
save_tech_ref
static bool save_tech_ref(struct section_file *sfile, const struct advance *padv, const char *path, const char *entry)
Definition rulesave.c:232
save_action_ui_name
static bool save_action_ui_name(struct section_file *sfile, int act, const char *entry_name)
Definition rulesave.c:871
rulesave.h
get_parser_buffer
char * get_parser_buffer(void)
Definition ruleset.c:562
get_script_buffer
char * get_script_buffer(void)
Definition ruleset.c:554
ruleset.h
RS_DEFAULT_CONVERT_SPEED
#define RS_DEFAULT_CONVERT_SPEED
Definition ruleset.h:119
RS_DEFAULT_UBUILD_NAT
#define RS_DEFAULT_UBUILD_NAT
Definition ruleset.h:118
RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
#define RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
Definition ruleset.h:105
RS_DEFAULT_TECH_TRADE_LOSS_HOLES
#define RS_DEFAULT_TECH_TRADE_LOSS_HOLES
Definition ruleset.h:82
RS_DEFAULT_EXTRA_APPEARANCE
#define RS_DEFAULT_EXTRA_APPEARANCE
Definition ruleset.h:99
RS_DEFAULT_TECH_PARASITE_HOLES
#define RS_DEFAULT_TECH_PARASITE_HOLES
Definition ruleset.h:83
GAME_DEFAULT_ACH_VALUE
#define GAME_DEFAULT_ACH_VALUE
Definition ruleset.h:76
RS_DEFAULT_TECH_TRADE_HOLES
#define RS_DEFAULT_TECH_TRADE_HOLES
Definition ruleset.h:81
RS_DEFAULT_CULTURE_VIC_POINTS
#define RS_DEFAULT_CULTURE_VIC_POINTS
Definition ruleset.h:92
RS_DEFAULT_CULTURE_MIGRATION_PML
#define RS_DEFAULT_CULTURE_MIGRATION_PML
Definition ruleset.h:94
RS_DEFAULT_SMALL_WONDER_VISIBILITY
#define RS_DEFAULT_SMALL_WONDER_VISIBILITY
Definition ruleset.h:107
RS_DEFAULT_ONLY_KILLING_VETERAN
#define RS_DEFAULT_ONLY_KILLING_VETERAN
Definition ruleset.h:102
RS_DEFAULT_TECH_LOSS_HOLES
#define RS_DEFAULT_TECH_LOSS_HOLES
Definition ruleset.h:84
RS_DEFAULT_HISTORY_INTEREST_PML
#define RS_DEFAULT_HISTORY_INTEREST_PML
Definition ruleset.h:95
RS_DEFAULT_GOODS_SELECTION
#define RS_DEFAULT_GOODS_SELECTION
Definition ruleset.h:97
RS_DEFAULT_PYTHAGOREAN_DIAGONAL
#define RS_DEFAULT_PYTHAGOREAN_DIAGONAL
Definition ruleset.h:85
RS_DEFAULT_TECH_STEAL_HOLES
#define RS_DEFAULT_TECH_STEAL_HOLES
Definition ruleset.h:80
GAME_DEFAULT_ACH_UNIQUE
#define GAME_DEFAULT_ACH_UNIQUE
Definition ruleset.h:75
RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
#define RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
Definition ruleset.h:104
RS_DEFAULT_MUUK_FOOD_WIPE
#define RS_DEFAULT_MUUK_FOOD_WIPE
Definition ruleset.h:77
RS_DEFAULT_MUUK_GOLD_WIPE
#define RS_DEFAULT_MUUK_GOLD_WIPE
Definition ruleset.h:78
RS_DEFAULT_BASE_TECH_COST
#define RS_DEFAULT_BASE_TECH_COST
Definition ruleset.h:109
RULESET_CAPABILITIES
#define RULESET_CAPABILITIES
Definition ruleset.h:24
RS_DEFAULT_NATIONALITY
#define RS_DEFAULT_NATIONALITY
Definition ruleset.h:117
GAME_DEFAULT_CHANGABLE_TAX
#define GAME_DEFAULT_CHANGABLE_TAX
Definition ruleset.h:72
RS_DEFAULT_MUUK_SHIELD_WIPE
#define RS_DEFAULT_MUUK_SHIELD_WIPE
Definition ruleset.h:79
RS_DEFAULT_GOLD_UPKEEP_STYLE
#define RS_DEFAULT_GOLD_UPKEEP_STYLE
Definition ruleset.h:87
GAME_DEFAULT_ADDTOSIZE
#define GAME_DEFAULT_ADDTOSIZE
Definition ruleset.h:71
RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
#define RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
Definition ruleset.h:103
RS_DEFAULT_EXTRA_DISAPPEARANCE
#define RS_DEFAULT_EXTRA_DISAPPEARANCE
Definition ruleset.h:100
RS_DEFAULT_MIN_TECH_COST
#define RS_DEFAULT_MIN_TECH_COST
Definition ruleset.h:113
GAME_DEFAULT_VISION_REVEAL_TILES
#define GAME_DEFAULT_VISION_REVEAL_TILES
Definition ruleset.h:73
RS_DEFAULT_CULTURE_VIC_LEAD
#define RS_DEFAULT_CULTURE_VIC_LEAD
Definition ruleset.h:93
GAME_DEFAULT_DISASTER_FREQ
#define GAME_DEFAULT_DISASTER_FREQ
Definition ruleset.h:74
setting_ruleset_locked
bool setting_ruleset_locked(const struct setting *pset)
Definition settings.c:4674
setting_int_get
int setting_int_get(struct setting *pset)
Definition settings.c:3778
setting_type
enum sset_type setting_type(const struct setting *pset)
Definition settings.c:3352
setting_enum_secfile_str
const char * setting_enum_secfile_str(secfile_data_t data, int val)
Definition settings.c:3860
setting_get_setdef
enum setting_default_level setting_get_setdef(const struct setting *pset)
Definition settings.c:5638
setting_name
const char * setting_name(const struct setting *pset)
Definition settings.c:3323
setting_bitwise_get
int setting_bitwise_get(struct setting *pset)
Definition settings.c:4247
setting_str_get
char * setting_str_get(struct setting *pset)
Definition settings.c:3849
setting_bool_get
bool setting_bool_get(struct setting *pset)
Definition settings.c:3666
setting_bitwise_secfile_str
const char * setting_bitwise_secfile_str(secfile_data_t data, int bit)
Definition settings.c:4055
read_enum_value
int read_enum_value(const struct setting *pset)
Definition settings.c:3985
settings.h
settings_iterate
#define settings_iterate(_level, _pset)
Definition settings.h:188
settings_iterate_end
#define settings_iterate_end
Definition settings.h:194
sex_rule_name
const char * sex_rule_name(sex_t kind)
Definition sex.c:43
sex.h
SEX_FEMALE
@ SEX_FEMALE
Definition sex.h:22
SEX_MALE
@ SEX_MALE
Definition sex.h:23
make_dir
bool make_dir(const char *pathname)
Definition shared.c:1779
MAX
#define MAX(x, y)
Definition shared.h:54
specialist_by_number
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:100
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
strvec_get
const char * strvec_get(const struct strvec *psv, size_t svindex)
Definition string_vector.c:388
strvec_size
size_t strvec_size(const struct strvec *psv)
Definition string_vector.c:343
string_vector.h
action_auto_perf
Definition actions.h:559
action
Definition actions.h:360
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:393
action::max_distance
int max_distance
Definition actions.h:376
action::quiet
bool quiet
Definition actions.h:383
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:379
action::target_kind
enum action_target_kind target_kind
Definition actions.h:367
advance
Definition tech.h:124
astring
Definition astring.h:36
base_type
Definition base.h:41
civ_game::named_teams
int named_teams
Definition game.h:293
civ_game::as_count
size_t as_count
Definition game.h:292
civ_game::plr_colors
struct rgbcolor_list * plr_colors
Definition game.h:244
civ_game::allowed_govs
const char ** allowed_govs
Definition game.h:284
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:280
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::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::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:246
civ_game::embedded_nations
char ** embedded_nations
Definition game.h:282
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:273
civ_game::allowed_terrains
const char ** allowed_terrains
Definition game.h:287
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:286
civ_game::allowed_styles
const char ** allowed_styles
Definition game.h:290
civ_game::server
struct civ_game::@31::@35 server
civ_game::embedded_nations_count
size_t embedded_nations_count
Definition game.h:283
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:289
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:106
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::type
enum clause_type type
Definition diptreaty.h:56
clause_info::enabled
bool enabled
Definition diptreaty.h:57
effect_cb_data
Definition rulesave.c:789
effect_cb_data::idx
int idx
Definition rulesave.c:790
effect_cb_data::sfile
struct section_file * sfile
Definition rulesave.c:791
effect
Definition effects.h:365
entry
Definition registry_ini.c:193
government
Definition government.h:52
item
Definition climisc.h:80
name_translation
Definition name_translation.h:35
nation_type
Definition nation.h:98
packet_calendar_info::positive_year_label
char positive_year_label[MAX_LEN_NAME]
Definition packets_gen.h:255
packet_calendar_info::calendar_skip_0
bool calendar_skip_0
Definition packets_gen.h:259
packet_calendar_info::negative_year_label
char negative_year_label[MAX_LEN_NAME]
Definition packets_gen.h:256
packet_calendar_info::calendar_fragments
int calendar_fragments
Definition packets_gen.h:257
packet_calendar_info::calendar_fragment_name
char calendar_fragment_name[MAX_CALENDAR_FRAGMENTS][MAX_LEN_NAME]
Definition packets_gen.h:258
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:211
packet_game_info::min_trade_route_val
int min_trade_route_val
Definition packets_gen.h:158
packet_game_info::illness_trade_infection
int illness_trade_infection
Definition packets_gen.h:183
packet_game_info::gameloss_style
enum gameloss_style gameloss_style
Definition packets_gen.h:232
packet_game_info::history_interest_pml
int history_interest_pml
Definition packets_gen.h:136
packet_game_info::citizen_partisans_pct
int citizen_partisans_pct
Definition packets_gen.h:144
packet_game_info::celebratesize
int celebratesize
Definition packets_gen.h:137
packet_game_info::goods_selection
enum goods_selection_method goods_selection
Definition packets_gen.h:160
packet_game_info::illness_base_factor
int illness_base_factor
Definition packets_gen.h:179
packet_game_info::illness_min_size
int illness_min_size
Definition packets_gen.h:180
packet_game_info::add_to_size_limit
int add_to_size_limit
Definition packets_gen.h:116
packet_game_info::forced_science
int forced_science
Definition packets_gen.h:155
packet_game_info::granary_num_inis
int granary_num_inis
Definition packets_gen.h:174
packet_game_info::gold_upkeep_style
enum gold_upkeep_style gold_upkeep_style
Definition packets_gen.h:166
packet_game_info::pop_report_zeroes
int pop_report_zeroes
Definition packets_gen.h:139
packet_game_info::damage_reduces_bombard_rate
bool damage_reduces_bombard_rate
Definition packets_gen.h:192
packet_game_info::citizen_nationality
bool citizen_nationality
Definition packets_gen.h:140
packet_game_info::nuke_pop_loss_pct
int nuke_pop_loss_pct
Definition packets_gen.h:197
packet_game_info::nuke_defender_survival_chance_pct
int nuke_defender_survival_chance_pct
Definition packets_gen.h:198
packet_game_info::angrycitizen
int angrycitizen
Definition packets_gen.h:122
packet_game_info::granary_food_inc
int granary_food_inc
Definition packets_gen.h:172
packet_game_info::tech_upkeep_style
enum tech_upkeep_style tech_upkeep_style
Definition packets_gen.h:229
packet_game_info::tech_trade_loss_allow_holes
bool tech_trade_loss_allow_holes
Definition packets_gen.h:213
packet_game_info::granary_food_ini
int granary_food_ini[MAX_GRANARY_INIS]
Definition packets_gen.h:173
packet_game_info::culture_vic_lead
int culture_vic_lead
Definition packets_gen.h:134
packet_game_info::free_tech_method
enum free_tech_method free_tech_method
Definition packets_gen.h:231
packet_game_info::changable_tax
bool changable_tax
Definition packets_gen.h:138
packet_game_info::steal_maps_reveals_all_cities
bool steal_maps_reveals_all_cities
Definition packets_gen.h:209
packet_game_info::init_city_radius_sq
int init_city_radius_sq
Definition packets_gen.h:184
packet_game_info::granularity
int granularity
Definition packets_gen.h:250
packet_game_info::conquest_convert_pct
int conquest_convert_pct
Definition packets_gen.h:143
packet_game_info::muuk_food_wipe
bool muuk_food_wipe
Definition packets_gen.h:200
packet_game_info::homeless_gold_upkeep
bool homeless_gold_upkeep
Definition packets_gen.h:167
packet_game_info::tired_attack
bool tired_attack
Definition packets_gen.h:235
packet_game_info::only_real_fight_makes_veteran
bool only_real_fight_makes_veteran
Definition packets_gen.h:190
packet_game_info::low_firepower_pearl_harbour
int low_firepower_pearl_harbour
Definition packets_gen.h:194
packet_game_info::base_pollution
int base_pollution
Definition packets_gen.h:123
packet_game_info::citizen_convert_speed
int citizen_convert_speed
Definition packets_gen.h:142
packet_game_info::forced_gold
int forced_gold
Definition packets_gen.h:153
packet_game_info::illness_pollution_factor
int illness_pollution_factor
Definition packets_gen.h:182
packet_game_info::base_tech_cost
int base_tech_cost
Definition packets_gen.h:124
packet_game_info::happy_cost
int happy_cost
Definition packets_gen.h:176
packet_game_info::civil_war_enabled
bool civil_war_enabled
Definition packets_gen.h:247
packet_game_info::muuk_gold_wipe
bool muuk_gold_wipe
Definition packets_gen.h:201
packet_game_info::food_cost
int food_cost
Definition packets_gen.h:151
packet_game_info::tech_leakage
enum tech_leakage_style tech_leakage
Definition packets_gen.h:227
packet_game_info::reveal_trade_partner
bool reveal_trade_partner
Definition packets_gen.h:159
packet_game_info::airlift_from_always_enabled
bool airlift_from_always_enabled
Definition packets_gen.h:120
packet_game_info::min_tech_cost
int min_tech_cost
Definition packets_gen.h:125
packet_game_info::illness_on
bool illness_on
Definition packets_gen.h:181
packet_game_info::civil_war_bonus_unhappy
int civil_war_bonus_unhappy
Definition packets_gen.h:249
packet_game_info::only_killing_makes_veteran
bool only_killing_makes_veteran
Definition packets_gen.h:189
packet_game_info::poison_empties_food_stock
bool poison_empties_food_stock
Definition packets_gen.h:210
packet_game_info::tech_loss_allow_holes
bool tech_loss_allow_holes
Definition packets_gen.h:215
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:148
packet_game_info::tech_trade_allow_holes
bool tech_trade_allow_holes
Definition packets_gen.h:212
packet_game_info::low_firepower_nonnat_bombard
int low_firepower_nonnat_bombard
Definition packets_gen.h:196
packet_game_info::border_size_effect
int border_size_effect
Definition packets_gen.h:128
packet_game_info::tech_upkeep_divider
int tech_upkeep_divider
Definition packets_gen.h:228
packet_game_info::pillage_select
bool pillage_select
Definition packets_gen.h:208
packet_game_info::tech_parasite_allow_holes
bool tech_parasite_allow_holes
Definition packets_gen.h:214
packet_game_info::muuk_shield_wipe
bool muuk_shield_wipe
Definition packets_gen.h:202
packet_game_info::base_bribe_cost
int base_bribe_cost
Definition packets_gen.h:131
packet_game_info::low_firepower_combat_bonus
int low_firepower_combat_bonus
Definition packets_gen.h:195
packet_game_info::culture_migration_pml
int culture_migration_pml
Definition packets_gen.h:135
packet_game_info::border_city_permanent_radius_sq
int border_city_permanent_radius_sq
Definition packets_gen.h:129
packet_game_info::culture_vic_points
int culture_vic_points
Definition packets_gen.h:133
packet_game_info::low_firepower_badwallattacker
int low_firepower_badwallattacker
Definition packets_gen.h:193
packet_game_info::airlift_to_always_enabled
bool airlift_to_always_enabled
Definition packets_gen.h:121
packet_game_info::small_wonder_visibility
enum wonder_visib_type small_wonder_visibility
Definition packets_gen.h:251
packet_game_info::tech_cost_style
enum tech_cost_style tech_cost_style
Definition packets_gen.h:226
packet_game_info::combat_odds_scaled_veterancy
bool combat_odds_scaled_veterancy
Definition packets_gen.h:191
packet_game_info::unit_builders_nationality
bool unit_builders_nationality
Definition packets_gen.h:141
packet_game_info::civil_war_bonus_celebrating
int civil_war_bonus_celebrating
Definition packets_gen.h:248
packet_game_info::border_city_radius_sq
int border_city_radius_sq
Definition packets_gen.h:127
packet_game_info::forced_luxury
int forced_luxury
Definition packets_gen.h:154
packet_game_info::min_city_center_output
int min_city_center_output[O_LAST]
Definition packets_gen.h:199
packet_ruleset_control::preferred_soundset
char preferred_soundset[MAX_LEN_NAME]
Definition packets_gen.h:1472
packet_ruleset_control::version
char version[MAX_LEN_NAME]
Definition packets_gen.h:1476
packet_ruleset_control::nation_count
int nation_count
Definition packets_gen.h:1465
packet_ruleset_control::preferred_tileset
char preferred_tileset[MAX_LEN_NAME]
Definition packets_gen.h:1471
packet_ruleset_control::popup_tech_help
bool popup_tech_help
Definition packets_gen.h:1474
packet_ruleset_control::alt_dir
char alt_dir[MAX_LEN_NAME]
Definition packets_gen.h:1477
packet_ruleset_control::preferred_musicset
char preferred_musicset[MAX_LEN_NAME]
Definition packets_gen.h:1473
packet_ruleset_control::num_tech_classes
int num_tech_classes
Definition packets_gen.h:1452
packet_ruleset_control::num_city_styles
int num_city_styles
Definition packets_gen.h:1466
packet_ruleset_control::name
char name[MAX_LEN_NAME]
Definition packets_gen.h:1475
requirement
Definition requirements.h:81
requirement::present
bool present
Definition requirements.h:85
requirement::source
struct universal source
Definition requirements.h:82
road_type
Definition road.h:71
rule_data
Definition rulesave.h:21
rule_data::nationlist
char * nationlist
Definition rulesave.h:22
ruler_title
Definition government.c:188
section_file
Definition section_file.h:36
sf_cb_data
Definition settings.h:81
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
terrain
Definition terrain.h:182
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::min
int min
Definition traits.h:44
trait_limits::max
int max
Definition traits.h:45
unit_type
Definition unittype.h:500
universal::kind
enum universals_n kind
Definition fc_types.h:903
veteran_system
Definition unittype.h:494
world::map
struct civ_map map
Definition world_object.h:38
style_rule_name
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:108
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_re_active_iterate_end
#define styles_re_active_iterate_end
Definition style.h:60
styles_re_active_iterate
#define styles_re_active_iterate(_p)
Definition style.h:56
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc_fopen
FILE * fc_fopen(const char *filename, const char *opentype)
Definition support.c:507
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_rule_name
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:233
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:423
tech_class_rule_name
const char * tech_class_rule_name(const struct tech_class *ptclass)
Definition tech.c:342
advance_has_flag
bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag)
Definition tech.c:216
advance_rule_name
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
advance_index
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
tech_flag_helptxt
const char * tech_flag_helptxt(enum tech_flag_id id)
Definition tech.c:435
advance_re_active_iterate
#define advance_re_active_iterate(_p)
Definition tech.h:281
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
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_re_active_iterate_end
#define advance_re_active_iterate_end
Definition tech.h:285
A_NONE
#define A_NONE
Definition tech.h:43
tech_class_iterate
#define tech_class_iterate(_p)
Definition tech.h:198
A_LAST
#define A_LAST
Definition tech.h:45
terrain_flag_id_name_cb
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:817
terrain_rule_name
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
terrain_flag_helptxt
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Definition terrain.c:829
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:373
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:379
MAX_NUM_TERRAINS
#define MAX_NUM_TERRAINS
Definition terrain.h:64
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
MAX_NUM_USER_TER_FLAGS
#define MAX_NUM_USER_TER_FLAGS
Definition terrain.h:152
terrain_resources_iterate_end
#define terrain_resources_iterate_end
Definition terrain.h:401
terrain_resources_iterate
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:392
RESOURCE_FREQUENCY_DEFAULT
#define RESOURCE_FREQUENCY_DEFAULT
Definition terrain.h:208
goods_has_flag
bool goods_has_flag(const struct goods_type *pgood, enum goods_flag_id flag)
Definition traderoutes.c:668
trade_route_type_name
const char * trade_route_type_name(enum trade_route_type type)
Definition traderoutes.c:148
trade_route_settings_by_type
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Definition traderoutes.c:201
trade_route_cancelling_type_name
const char * trade_route_cancelling_type_name(enum trade_route_illegal_cancelling type)
Definition traderoutes.c:174
goods_type_re_active_iterate_end
#define goods_type_re_active_iterate_end
Definition traderoutes.h:235
goods_type_re_active_iterate
#define goods_type_re_active_iterate(_p)
Definition traderoutes.h:231
trade_route_type
trade_route_type
Definition traderoutes.h:37
TRT_LAST
@ TRT_LAST
Definition traderoutes.h:48
TRAIT_DEFAULT_VALUE
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
unit_class_flag_helptxt
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1854
utype_has_role
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:199
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
uclass_rule_name
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1641
unit_class_flag_id_name_cb
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1842
unit_type_flag_id_name_cb
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1905
unit_type_flag_helptxt
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1917
unittype.h
uclass_has_flag
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
unit_type_re_active_iterate
#define unit_type_re_active_iterate(_p)
Definition unittype.h:864
combat_bonus_list_iterate_end
#define combat_bonus_list_iterate_end
Definition unittype.h:482
L_FIRST
#define L_FIRST
Definition unittype.h:349
combat_bonus_list_iterate
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:480
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:905
unit_class_re_active_iterate_end
#define unit_class_re_active_iterate_end
Definition unittype.h:921
MAX_NUM_USER_UNIT_FLAGS
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:332
utype_has_flag
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
UTYF_LAST_USER_FLAG
#define UTYF_LAST_USER_FLAG
Definition unittype.h:331
L_LAST
#define L_LAST
Definition unittype.h:439
unit_class_re_active_iterate
#define unit_class_re_active_iterate(_p)
Definition unittype.h:917
uclass_index
#define uclass_index(_c_)
Definition unittype.h:742
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:912
MAX_NUM_USER_UCLASS_FLAGS
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:128
unit_type_re_active_iterate_end
#define unit_type_re_active_iterate_end
Definition unittype.h:868
freeciv_datafile_version
const char * freeciv_datafile_version(void)
Definition version.c:186
version.h