Freeciv-3.3
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 "ruleload.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 * 40 - Freeciv-3.3
55 */
56#define FORMAT_VERSION RSFORMAT_CURRENT
57
58/**********************************************************************/
61static struct section_file *create_ruleset_file(const char *rsname,
62 const char *rstype)
63{
64 struct section_file *sfile = secfile_new(TRUE);
65 char buf[500];
66
68
69 if (rsname != nullptr && rsname[0] != '\0') {
70 fc_snprintf(buf, sizeof(buf), "%s %s data for Freeciv", rsname, rstype);
71 } else {
72 fc_snprintf(buf, sizeof(buf), "Template %s data for Freeciv", rstype);
73 }
74
75 secfile_insert_str(sfile, buf, "datafile.description");
76 secfile_insert_str(sfile, freeciv_datafile_version(), "datafile.ruledit");
77 secfile_insert_str(sfile, RULESET_CAPABILITIES, "datafile.options");
78 secfile_insert_int(sfile, FORMAT_VERSION, "datafile.format_version");
79
80 return sfile;
81}
82
83/**********************************************************************/
86static bool save_default_int(struct section_file *sfile, int value,
87 int default_value, const char *path,
88 const char *entry)
89{
90 if (value != default_value) {
91 if (entry != nullptr) {
92 secfile_insert_int(sfile, value,
93 "%s.%s", path, entry);
94 } else {
95 secfile_insert_int(sfile, value,
96 "%s", path);
97 }
98 }
99
100 return TRUE;
101}
102
103/**********************************************************************/
106static bool save_default_bool(struct section_file *sfile, bool value,
107 bool default_value, const char *path,
108 const char *entry)
109{
110 if ((value && !default_value)
111 || (!value && default_value)) {
112 if (entry != nullptr) {
113 secfile_insert_bool(sfile, value,
114 "%s.%s", path, entry);
115 } else {
116 secfile_insert_bool(sfile, value,
117 "%s", path);
118 }
119 }
120
121 return TRUE;
122}
123
124/**********************************************************************/
127static bool save_name_translation(struct section_file *sfile,
128 struct name_translation *name,
129 const char *path)
130{
131 struct entry *mod_entry;
132
135 "%s.name", path);
139 secfile_insert_str(sfile,
141 "%s.rule_name", path);
142 }
143
144 return TRUE;
145}
146
147/**********************************************************************/
150static bool save_reqs_vector(struct section_file *sfile,
151 const struct requirement_vector *reqs,
152 const char *path, const char *entry)
153{
154 int i;
155 bool includes_negated = FALSE;
157 bool includes_quiet = FALSE;
158
160 if (!preq->present) {
162 }
163 if (preq->survives) {
165 }
166 if (preq->quiet) {
168 }
170
171 i = 0;
173 secfile_insert_str(sfile,
174 universals_n_name(preq->source.kind),
175 "%s.%s%d.type", path, entry, i);
176 secfile_insert_str(sfile,
177 universal_rule_name(&(preq->source)),
178 "%s.%s%d.name", path, entry, i);
179 secfile_insert_str(sfile,
180 req_range_name(preq->range),
181 "%s.%s%d.range", path, entry, i);
182
183 if (includes_surviving) {
185 preq->survives,
186 "%s.%s%d.survives", path, entry, i);
187 }
188
189 if (includes_negated) {
191 preq->present,
192 "%s.%s%d.present", path, entry, i);
193 }
194
195 if (includes_quiet) {
197 preq->quiet,
198 "%s.%s%d.quiet", path, entry, i);
199 }
200
201 i++;
203
204 return TRUE;
205}
206
207/**********************************************************************/
210static bool save_tech_list(struct section_file *sfile, int *input,
211 const char *path, const char *entry)
212{
213 const char *tech_names[MAX_NUM_TECH_LIST];
214 int set_count;
215 int i;
216
217 set_count = 0;
218 for (i = 0; input[i] != A_LAST && i < MAX_NUM_TECH_LIST; i++) {
220 }
221
222 if (set_count > 0) {
224 "%s.%s", path, entry);
225 }
226
227 return TRUE;
228}
229
230/**********************************************************************/
233static bool save_tech_ref(struct section_file *sfile,
234 const struct advance *padv,
235 const char *path, const char *entry)
236{
237 if (padv == A_NEVER) {
238 secfile_insert_str(sfile, "Never", "%s.%s", path, entry);
239 } else {
241 "%s.%s", path, entry);
242 }
243
244 return TRUE;
245}
246
247/**********************************************************************/
250static bool save_terrain_ref(struct section_file *sfile,
251 const struct terrain *save,
252 const struct terrain *pthis,
253 const char *path, const char *entry)
254{
255 if (save == nullptr) {
256 secfile_insert_str(sfile, "none", "%s.%s", path, entry);
257 } else if (save == pthis) {
258 secfile_insert_str(sfile, "yes", "%s.%s", path, entry);
259 } else {
261 "%s.%s", path, entry);
262 }
263
264 return TRUE;
265}
266
267/**********************************************************************/
270static bool save_gov_ref(struct section_file *sfile,
271 const struct government *gov,
272 const char *path, const char *entry)
273{
274 secfile_insert_str(sfile, government_rule_name(gov), "%s.%s", path, entry);
275
276 return TRUE;
277}
278
279/**********************************************************************/
283static bool save_building_list(struct section_file *sfile, int *input,
284 const char *path, const char *entry)
285{
287 int set_count;
288 int i;
289
290 set_count = 0;
291 for (i = 0; input[i] != B_LAST && i < MAX_NUM_BUILDING_LIST; i++) {
293 }
294
295 if (set_count > 0) {
297 "%s.%s", path, entry);
298 }
299
300 return TRUE;
301}
302
303/**********************************************************************/
307static bool save_unit_list(struct section_file *sfile, struct unit_type **input,
308 const char *path, const char *entry)
309{
310 const char *unit_names[MAX_NUM_UNIT_LIST];
311 int set_count;
312 int i;
313
314 set_count = 0;
315 for (i = 0; input[i] != nullptr && i < MAX_NUM_UNIT_LIST; i++) {
317 }
318
319 if (set_count > 0) {
321 "%s.%s", path, entry);
322 }
323
324 return TRUE;
325}
326
327/**********************************************************************/
330static bool save_uclass_vec(struct section_file *sfile,
331 bv_unit_classes *bits,
332 const char *path, const char *entry,
333 bool unreachable_only)
334{
335 const char *class_names[UCL_LAST];
336 int classes = 0;
337
339 if (BV_ISSET(*(bits), uclass_index(pcargo))
341 || !unreachable_only)) {
343 }
345
346 if (classes > 0) {
348 "%s.%s", path, entry);
349 }
350
351 return TRUE;
352}
353
354/**********************************************************************/
357static bool save_helptext(struct section_file *sfile,
358 struct strvec *to_save,
359 const char *path, const char *entry)
360{
361 if (to_save != nullptr) {
363 const char *sections[sect_count];
364 int i;
365
366 for (i = 0; i < sect_count; i++) {
367 sections[i] = strvec_get(to_save, i);
368 }
369
371 "%s.%s", path, entry);
372 }
373
374 return TRUE;
375}
376
377/**********************************************************************/
380static bool save_ruleset_file(struct section_file *sfile, const char *filename)
381{
382 return secfile_save(sfile, filename, 0, FZ_PLAIN);
383}
384
385/**********************************************************************/
388static bool save_buildings_ruleset(const char *filename, const char *name)
389{
390 struct section_file *sfile = create_ruleset_file(name, "building");
391 int sect_idx;
392 int i;
393 bool uflags_building = FALSE;
394
395 if (sfile == nullptr) {
396 return FALSE;
397 }
398
399 for (i = 0; i < MAX_NUM_USER_BUILDING_FLAGS; i++) {
401 const char *helptxt = impr_flag_helptxt(i + IF_USER_FLAG_1);
402
403 if (flagname != nullptr) {
404 if (!uflags_building) {
407 }
408
409 secfile_insert_str(sfile, flagname, "control.building_flags%d.name", i);
410
411 /* Save the user flag help text even when it is undefined. That makes
412 * the formatting code happy. The resulting "" is ignored when the
413 * ruleset is loaded. */
414 secfile_insert_str(sfile, helptxt,
415 "control.building_flags%d.helptxt", i);
416 }
417 }
418
419 comment_buildings(sfile);
420
421 sect_idx = 0;
423 if (!pb->ruledit_disabled) {
424 char path[512];
425 const char *flag_names[IF_COUNT];
426 int set_count;
427 int flagi;
428
429 fc_snprintf(path, sizeof(path), "building_%d", sect_idx++);
430
431 save_name_translation(sfile, &(pb->name), path);
432
434 "%s.genus", path);
435
436 if (strcmp(pb->graphic_str, "-")) {
437 secfile_insert_str(sfile, pb->graphic_str, "%s.graphic", path);
438 }
439 if (strcmp(pb->graphic_alt, "-")) {
440 secfile_insert_str(sfile, pb->graphic_alt, "%s.graphic_alt", path);
441 }
442 if (strcmp(pb->graphic_alt2, "-")) {
443 secfile_insert_str(sfile, pb->graphic_alt2, "%s.graphic_alt2", path);
444 }
445 if (strcmp(pb->soundtag, "-")) {
446 secfile_insert_str(sfile, pb->soundtag, "%s.sound", path);
447 }
448 if (strcmp(pb->soundtag_alt, "-")) {
449 secfile_insert_str(sfile, pb->soundtag_alt, "%s.sound_alt", path);
450 }
451 if (strcmp(pb->soundtag_alt2, "-")) {
452 secfile_insert_str(sfile, pb->soundtag_alt2, "%s.sound_alt2", path);
453 }
454
455 save_reqs_vector(sfile, &(pb->reqs), path, "reqs");
456 save_reqs_vector(sfile, &(pb->obsolete_by), path, "obsolete_by");
457
458 secfile_insert_int(sfile, pb->build_cost, "%s.build_cost", path);
459 secfile_insert_int(sfile, pb->upkeep, "%s.upkeep", path);
460 secfile_insert_int(sfile, pb->sabotage, "%s.sabotage", path);
461
462 set_count = 0;
463 for (flagi = 0; flagi < IF_COUNT; flagi++) {
466 }
467 }
468
469 if (set_count > 0) {
471 "%s.flags", path);
472 }
473
474 save_helptext(sfile, pb->helptext, path, "helptext");
475 }
477
478 return save_ruleset_file(sfile, filename);
479}
480
481/**********************************************************************/
484static bool save_styles_ruleset(const char *filename, const char *name)
485{
486 struct section_file *sfile = create_ruleset_file(name, "styles");
487 int sect_idx;
488 int i;
489
490 if (sfile == nullptr) {
491 return FALSE;
492 }
493
494 comment_styles(sfile);
495
496 sect_idx = 0;
498 char path[512];
499
500 fc_snprintf(path, sizeof(path), "style_%d", sect_idx++);
501
502 save_name_translation(sfile, &(pstyle->name), path);
504
505 comment_citystyles(sfile);
506
507 sect_idx = 0;
508 for (i = 0; i < game.control.num_city_styles; i++) {
509 char path[512];
510
511 fc_snprintf(path, sizeof(path), "citystyle_%d", sect_idx++);
512
513 save_name_translation(sfile, &(city_styles[i].name), path);
514
515 secfile_insert_str(sfile, city_styles[i].graphic, "%s.graphic", path);
516 secfile_insert_str(sfile, city_styles[i].graphic_alt, "%s.graphic_alt", path);
517 if (strcmp(city_styles[i].citizens_graphic, "-")) {
518 secfile_insert_str(sfile, city_styles[i].citizens_graphic,
519 "%s.citizens_graphic", path);
520 }
521
522 save_reqs_vector(sfile, &(city_styles[i].reqs), path, "reqs");
523 }
524
525 comment_musicstyles(sfile);
526
527 sect_idx = 0;
529 char path[512];
530
531 fc_snprintf(path, sizeof(path), "musicstyle_%d", sect_idx++);
532
533 secfile_insert_str(sfile, pmus->music_peaceful, "%s.music_peaceful", path);
534 secfile_insert_str(sfile, pmus->music_combat, "%s.music_combat", path);
535
536 save_reqs_vector(sfile, &(pmus->reqs), path, "reqs");
538
539 return save_ruleset_file(sfile, filename);
540}
541
542/**********************************************************************/
549 const int aap,
550 const char *uflags_path,
551 bool (*unexpected_req)(
552 const struct requirement *preq))
553{
555 size_t i;
556 size_t ret;
557
558 const struct action_auto_perf *auto_perf =
560
561 i = 0;
563 fc_assert(req->range == REQ_RANGE_LOCAL);
564
565 if (req->source.kind == VUT_UTFLAG) {
566 fc_assert(!req->present);
567
568 protecor_flag[i++] = req->source.value.unitflag;
569 } else if (unexpected_req(req)) {
570 struct astring astr;
571
572 log_error("Can't handle action auto performer requirement %s",
573 req_to_fstring(req, &astr));
574 astr_free(&astr);
575
576 return FALSE;
577 }
579
582 "%s", uflags_path);
583
584 if (ret != i) {
585 log_error("%s: didn't save all unit type flags.", uflags_path);
586
587 return FALSE;
588 }
589
590 return TRUE;
591}
592
593/**********************************************************************/
599static bool save_action_auto_actions(struct section_file *sfile,
600 const int aap,
601 const char *actions_path)
602{
604 size_t i, j;
605 size_t ret;
606
607 const struct action_auto_perf *auto_perf
609
610 for (i = 0, j = 0;
611 i < NUM_ACTIONS && auto_perf->alternatives[i] != ACTION_NONE;
612 i++) {
613 struct action *paction = action_by_number(auto_perf->alternatives[i]);
614
616 /* Don't mention non enabled actions. */
617 continue;
618 }
619
620 /* This action is included in the output. */
621 unit_acts[j] = auto_perf->alternatives[i];
622 j++;
623 }
624
627 "%s", actions_path);
628
629 if (ret != j) {
630 log_error("%s: didn't save all actions.", actions_path);
631
632 return FALSE;
633 }
634
635 return TRUE;
636}
637
638/**********************************************************************/
642static bool unexpected_non_otype(const struct requirement *req)
643{
644 return !(req->source.kind == VUT_OTYPE && req->present);
645}
646
647/**********************************************************************/
652static bool save_muuk_action_auto(struct section_file *sfile,
653 const int aap,
654 const char *item)
655{
656 char uflags_path[100];
657 char action_path[100];
658
660 "missing_unit_upkeep.%s_protected", item);
662 "missing_unit_upkeep.%s_unit_act", item);
663
667}
668
669/**********************************************************************/
672static bool save_cities_ruleset(const char *filename, const char *name)
673{
674 struct section_file *sfile = create_ruleset_file(name, "cities");
675 int sect_idx;
676
677 if (sfile == nullptr) {
678 return FALSE;
679 }
680
681 comment_specialists(sfile);
682
683 sect_idx = 0;
686 char path[512];
687
688 fc_snprintf(path, sizeof(path), "specialist_%d", sect_idx++);
689
690 save_name_translation(sfile, &(s->name), path);
691
693 struct entry *pentry =
695 "%s.short_name", path);
697 }
698
699 save_reqs_vector(sfile, &(s->reqs), path, "reqs");
700
701 secfile_insert_str(sfile, s->graphic_str, "%s.graphic", path);
702 if (strcmp(s->graphic_alt, "-")) {
703 secfile_insert_str(sfile, s->graphic_alt, "%s.graphic_alt", path);
704 }
705
706 save_helptext(sfile, s->helptext, path, "helptext");
707
709
712 "parameters.celebrate_size_limit");
713 }
716 "parameters.add_to_size_limit");
717 }
720 "parameters.angry_citizens");
721 }
724 "parameters.changable_tax");
725 }
726 if (game.info.forced_science != 0) {
728 "parameters.forced_science");
729 }
730 if (game.info.forced_luxury != 100) {
732 "parameters.forced_luxury");
733 }
734 if (game.info.forced_gold != 0) {
736 "parameters.forced_gold");
737 }
740 "parameters.vision_reveal_tiles");
741 }
742 if (game.info.pop_report_zeroes != 1) {
744 "parameters.pop_report_zeroes");
745 }
746
749 "citizen.nationality", nullptr);
752 "citizen.ubuilder_nationality", nullptr);
755 "citizen.convert_speed", nullptr);
756 if (game.info.conquest_convert_pct != 0) {
758 "citizen.conquest_convert_pct");
759 }
760
763 "citizen.partisans_pct");
764 }
765
767 "food");
770 "missing_unit_upkeep.food_wipe");
771 }
772
774 "gold");
777 "missing_unit_upkeep.gold_wipe");
778 }
779
781 "shield");
784 "missing_unit_upkeep.shield_wipe");
785 }
786
787 return save_ruleset_file(sfile, filename);
788}
789
790/**************************************************************************
791 Effect saving callback data structure.
792**************************************************************************/
793typedef struct {
794 int idx;
797
798/**********************************************************************/
801static bool effect_save(struct effect *peffect, void *data)
802{
804 char path[512];
805
806 if (peffect->rulesave.do_not_save) {
807 /* Is supposed to be skipped. */
808 return TRUE;
809 }
810
811 fc_snprintf(path, sizeof(path), "effect_%d", cbdata->idx++);
812
815 "%s.type", path);
816 secfile_insert_int(cbdata->sfile, peffect->value, "%s.value", path);
817
818 save_reqs_vector(cbdata->sfile, &peffect->reqs, path, "reqs");
819
820 if (peffect->rulesave.comment != nullptr) {
821 secfile_insert_str(cbdata->sfile, peffect->rulesave.comment,
822 "%s.comment", path);
823 }
824
825 return TRUE;
826}
827
828/**********************************************************************/
831static bool save_effects_ruleset(const char *filename, const char *name)
832{
833 struct section_file *sfile = create_ruleset_file(name, "effect");
834 effect_cb_data data;
835 int i;
836 int sidx;
837
838 if (sfile == nullptr) {
839 return FALSE;
840 }
841
842 data.idx = 0;
843 data.sfile = sfile;
844
845 comment_ueffs(sfile);
846
847 sidx = 0;
848 for (i = EFT_USER_EFFECT_1 ; i <= EFT_USER_EFFECT_LAST; i++) {
849 enum effect_type val = user_effect_ai_valued_as(i);
850
851 if (val != i) {
852 char path[512];
853
854 fc_snprintf(path, sizeof(path), "ueff_%d", sidx++);
855
857 "%s.type", path);
859 "%s.ai_valued_as", path);
860 }
861 }
862
863 comment_effects(sfile);
864
865 if (!iterate_effect_cache(effect_save, &data)) {
866 return FALSE;
867 }
868
869 return save_ruleset_file(sfile, filename);
870}
871
872/**********************************************************************/
875static bool save_action_max_range(struct section_file *sfile,
876 action_id act)
877{
878 struct action *paction = action_by_number(act);
879
880 if (paction->max_distance == ACTION_DISTANCE_UNLIMITED) {
882 "actions.%s",
883 action_max_range_ruleset_var_name(act)) != nullptr;
884 } else {
887 "actions",
889 }
890}
891
892/**********************************************************************/
895static bool save_action_range(struct section_file *sfile, action_id act)
896{
897 struct action *paction = action_by_number(act);
898
899 if (action_min_range_ruleset_var_name(act) != nullptr) {
900 /* Min range can be loaded from the ruleset. */
901 save_default_int(sfile,
902 paction->min_distance,
904 "actions",
906 }
907
908 if (action_max_range_ruleset_var_name(act) != nullptr) {
909 /* Max range can be loaded from the ruleset. */
910 if (!save_action_max_range(sfile, act)) {
911 return FALSE;
912 }
913 }
914
915 return TRUE;
916}
917
918/**********************************************************************/
921static bool save_action_kind(struct section_file *sfile, action_id act)
922{
923 if (action_target_kind_ruleset_var_name(act) != nullptr) {
924 struct action *paction = action_by_number(act);
925
926 /* Target kind can be loaded from the ruleset. */
928 /* Don't save the default for actions that aren't enabled. */
929 return TRUE;
930 }
931
935 "actions.%s",
937 }
938
939 return TRUE;
940}
941
942/**********************************************************************/
946 action_id act)
947{
949 struct action *paction = action_by_number(act);
950
951 /* Actor consumption can be loaded from the ruleset. */
953 /* Don't save value for actions that aren't enabled. */
954 return TRUE;
955 }
956
957 save_default_bool(sfile,
960 "actions",
962 }
963
964 return TRUE;
965}
966
967/**********************************************************************/
970static bool save_action_blocked_by(struct section_file *sfile,
971 struct action *paction)
972{
974 char comment[1024];
975 int i = 0;
976
978 /* Action blocked by shouldn't be written to the ruleset for this
979 * action. */
980 return TRUE;
981 }
982
984 /* Don't save value for actions that aren't enabled. */
985 return TRUE;
986 }
987
988 fc_snprintf(comment, sizeof(comment),
989 "Forbid \"%s\" if any one of the listed actions are legal.",
991
994
996 /* Don't save value for actions that aren't enabled. */
997 continue;
998 }
999
1000 if (BV_ISSET(paction->blocked_by, blocker_id)) {
1002 i++;
1003 }
1005
1007 sfile, &action_vec, i, gen_action, comment, "actions.%s",
1009 != i) {
1010 log_error("Didn't save all %s blocking actions.",
1012
1013 return FALSE;
1014 }
1015
1016 return TRUE;
1017}
1018
1019/**********************************************************************/
1024 int performer_slot,
1025 struct action *paction)
1026{
1027 char action_list_path[100];
1028
1030 /* Not relevant. */
1031 return TRUE;
1032 }
1033
1034 if (!action_is_in_use(paction)) {
1035 /* Don't save value for actions that aren't enabled. */
1036 return TRUE;
1037 }
1038
1040 "actions.%s",
1043 return FALSE;
1044 }
1045
1046 return TRUE;
1047}
1048
1049/**********************************************************************/
1052static bool save_bv_actions(struct section_file *sfile,
1053 bv_actions content,
1054 const char *path)
1055{
1057 int i = 0;
1058
1059 action_iterate(act_id) {
1060 struct action *paction = action_by_number(act_id);
1061
1062 if (!action_is_in_use(paction)) {
1063 /* Don't save value for actions that aren't enabled. */
1064 continue;
1065 }
1066
1067 if (BV_ISSET(content, act_id)) {
1068 action_vec[i] = act_id;
1069 i++;
1070 }
1072
1074 "%s", path) != i) {
1075 log_error("Didn't save all of %s.", path);
1076
1077 return FALSE;
1078 }
1079
1080 return TRUE;
1081}
1082/**********************************************************************/
1085static bool save_actions_ruleset(const char *filename, const char *name)
1086{
1087 struct section_file *sfile = create_ruleset_file(name, "actions");
1089 int i = 0;
1090 int sect_idx = 0;
1091
1092 /* TODO: move action logic from save_game_ruleset to here */
1093 if (sfile == nullptr) {
1094 return FALSE;
1095 }
1096 {
1097 /* Action auto performers aren't ready to be exposed in the ruleset
1098 * yet. The behavior when two action auto performers for the same
1099 * cause can fire isn't set in stone yet. How is one of them chosen?
1100 * What if all the actions of the chosen action auto performer turned
1101 * out to be illegal but one of the other action auto performers that
1102 * fired has legal actions? These issues can decide what other action
1103 * rules action auto performers can represent in the future. Deciding
1104 * should therefore wait until a rule needs action auto performers to
1105 * work a certain way. */
1106 /* Only one action auto performer, ACTION_AUTO_MOVED_ADJ, is caused
1107 * by AAPC_UNIT_MOVED_ADJ. It is therefore safe to expose the full
1108 * requirement vector to the ruleset. */
1109 const struct action_auto_perf *auto_perf =
1111
1112 comment_auto_attack(sfile);
1113
1114 save_reqs_vector(sfile, &auto_perf->reqs,
1115 "auto_attack", "if_attacker");
1116
1118 "auto_attack.attack_actions");
1119 }
1120
1123 "actions.diplchance_initial_odds")) {
1124 return FALSE;
1125 }
1126
1130 log_error("Didn't save all post success forced actions.");
1131 return FALSE;
1132 }
1133
1137 log_error("Didn't save all post success forced actions.");
1138 return FALSE;
1139 }
1140
1143 log_error("Didn't save all post success forced actions.");
1144 return FALSE;
1145 }
1146
1149 log_error("Didn't save all post success forced actions.");
1150 return FALSE;
1151 }
1152
1154 "actions.escape_city")) {
1155 log_error("Didn't save all escape city forced actions.");
1156 return FALSE;
1157 }
1158
1160 "actions.unit_stack_death")) {
1161 log_error("Didn't save all escape unit stack death forced actions.");
1162 return FALSE;
1163 }
1164
1167 "actions.poison_empties_food_stock", nullptr);
1168
1171 "actions.steal_maps_reveals_all_cities", nullptr);
1172
1173 action_iterate(act_id) {
1174 struct action *act = action_by_number(act_id);
1175
1176 save_action_kind(sfile, act_id);
1177 save_action_range(sfile, act_id);
1179 save_action_blocked_by(sfile, act);
1181
1183
1184 i = 0;
1185 action_iterate(act) {
1186 if (action_by_number(act)->quiet) {
1187 action_vec[i] = act;
1188 i++;
1189 }
1191
1193 "actions.quiet_actions") != i) {
1194 log_error("Didn't save all quiet actions.");
1195
1196 return FALSE;
1197 }
1198
1199 comment_actions(sfile);
1200 for (i = 0; i < MAX_NUM_ACTIONS; i++) {
1201 struct action *paction = action_by_number(i);
1202
1203 if (!action_is_in_use(paction)) {
1204 /* Don't mention non enabled actions. */
1205 continue;
1206 }
1207
1208 if (paction->configured) {
1209 char path[512];
1210 const char *ui_name;
1211
1212 fc_snprintf(path, sizeof(path), "action_%d", i);
1213
1215 "%s.action", path);
1216
1217 if (!action_id_is_internal(i)) {
1218 ui_name = paction->ui_name;
1219
1220 if (ui_name == nullptr) {
1221 fc_assert(ui_name != nullptr);
1222
1223 return FALSE;
1224 }
1225
1227 struct entry *pentry =
1228 secfile_insert_str(sfile, ui_name,
1229 "%s.ui_name", path);
1231 }
1232 }
1233 }
1234 }
1235
1236 comment_enablers(sfile);
1237 sect_idx = 0;
1239 char path[512];
1240
1241 if (pae->rulesave.ruledit_disabled) {
1242 continue;
1243 }
1244
1245 fc_snprintf(path, sizeof(path), "enabler_%d", sect_idx++);
1246
1248 "%s.action", path);
1249
1250 save_reqs_vector(sfile, &(pae->actor_reqs), path, "actor_reqs");
1251 save_reqs_vector(sfile, &(pae->target_reqs), path, "target_reqs");
1252
1253 if (pae->rulesave.comment != nullptr) {
1254 secfile_insert_str(sfile, pae->rulesave.comment, "%s.comment", path);
1255 }
1257
1258 return save_ruleset_file(sfile, filename);
1259}
1260
1261/**********************************************************************/
1264static bool save_game_ruleset(const char *filename, const char *name)
1265{
1266 struct section_file *sfile = create_ruleset_file(name, "game");
1267 int sect_idx;
1268 int col_idx;
1269 int set_count;
1270 enum gameloss_style gs;
1271 const char *style_names[32]; /* FIXME: Should determine max length automatically.
1272 * currently it's 3 (bits 0,1, and 2) so there's plenty of
1273 * safety margin here. */
1274 const char *tnames[game.server.ruledit.named_teams];
1275 enum trade_route_type trt;
1276 int i;
1277 bool locks;
1278
1279 if (sfile == nullptr) {
1280 return FALSE;
1281 }
1282
1283 if (game.server.ruledit.description_file != nullptr) {
1285 "ruledit.description_file");
1286 }
1287
1291 "ruledit.std_tileset_compat");
1292 }
1293
1294 if (game.control.preferred_tileset[0] != '\0') {
1296 "tileset.preferred");
1297 }
1298 if (game.control.preferred_soundset[0] != '\0') {
1300 "soundset.preferred");
1301 }
1302 if (game.control.preferred_musicset[0] != '\0') {
1304 "musicset.preferred");
1305 }
1306
1307 secfile_insert_str(sfile, game.control.name, "about.name");
1308 secfile_insert_str(sfile, game.control.version, "about.version");
1309
1310 if (game.control.alt_dir[0] != '\0') {
1311 secfile_insert_str(sfile, game.control.alt_dir, "about.alt_dir");
1312 }
1313
1314 if (game.ruleset_summary != nullptr) {
1315 struct entry *pentry =
1316 secfile_insert_str(sfile, game.ruleset_summary, "about.summary");
1318 }
1319
1320 if (game.ruleset_description != nullptr) {
1321 if (game.server.ruledit.description_file == nullptr) {
1323 "about.description");
1324 } else {
1326 "about.description");
1327 }
1328 }
1329
1330 if (game.ruleset_capabilities != nullptr) {
1332 "about.capabilities");
1333 } else {
1334 secfile_insert_str(sfile, "", "about.capabilities");
1335 }
1336
1338 "options", "global_init_techs");
1340 "options", "global_init_buildings");
1341
1343 FALSE,
1344 "options.popup_tech_help", nullptr);
1347 "civstyle.base_pollution", nullptr);
1348
1349 set_count = 0;
1351 if (game.info.gameloss_style & gs) {
1353 }
1354 }
1355
1356 if (set_count > 0) {
1358
1360 "civstyle.gameloss_style");
1361 }
1362
1365 "civstyle.happy_cost", nullptr);
1368 "civstyle.food_cost", nullptr);
1369 save_default_bool(sfile,
1372 FALSE,
1373 "civstyle.paradrop_to_transport", nullptr);
1376 "civstyle.base_bribe_cost", nullptr);
1379 }
1382 "civstyle.ransom_gold", nullptr);
1385 "civstyle.pillage_select", nullptr);
1388 "civstyle.tech_steal_allow_holes", nullptr);
1391 "civstyle.tech_trade_allow_holes", nullptr);
1394 "civstyle.tech_trade_loss_allow_holes", nullptr);
1397 "civstyle.tech_parasite_allow_holes", nullptr);
1400 "civstyle.tech_loss_allow_holes", nullptr);
1403 "civstyle.upgrade_veteran_loss", nullptr);
1406 "civstyle.autoupgrade_veteran_loss", nullptr);
1407
1409
1412 "civstyle.granary_food_ini");
1413
1416 "civstyle.granary_food_inc", nullptr);
1417
1419 char buffer[256];
1420
1421 fc_snprintf(buffer, sizeof(buffer),
1422 "civstyle.min_city_center_%s",
1424
1427 buffer, nullptr);
1429
1432 "civstyle.init_vis_radius_sq", nullptr);
1435 "civstyle.init_city_radius_sq", nullptr);
1436
1438
1441 secfile_insert_str(sfile,
1443 "civstyle.gold_upkeep_style");
1444 }
1447 }
1449 "civstyle.homeless_gold_upkeep", nullptr);
1451 1, "civstyle.output_granularity", nullptr);
1452
1455 }
1457 FALSE, "civstyle.airlift_from_always_enabled", nullptr);
1459 TRUE, "civstyle.airlift_to_always_enabled", nullptr);
1460
1464 secfile_insert_str(sfile,
1466 "wonder_visibility.small_wonders");
1467 }
1468
1471 "illness.illness_on", nullptr);
1474 "illness.illness_base_factor", nullptr);
1477 "illness.illness_min_size", nullptr);
1480 "illness.illness_trade_infection", nullptr);
1483 "illness.illness_pollution_factor", nullptr);
1484 comment_incite_cost(sfile);
1487 "incite_cost.base_incite_cost", nullptr);
1490 "incite_cost.improvement_factor", nullptr);
1493 "incite_cost.unit_factor", nullptr);
1496 "incite_cost.total_factor", nullptr);
1497
1500 }
1503 "combat_rules.tired_attack", nullptr);
1506 }
1509 "combat_rules.only_killing_makes_veteran", nullptr);
1512 }
1515 "combat_rules.only_real_fight_makes_veteran", nullptr);
1518 }
1521 "combat_rules.combat_odds_scaled_veterancy", nullptr);
1524 }
1527 "combat_rules.damage_reduces_bombard_rate", nullptr);
1530 }
1532 "combat_rules.low_firepower_badwallattacker", nullptr);
1535 }
1537 "combat_rules.low_firepower_pearl_harbor", nullptr);
1540 }
1542 "combat_rules.low_firepower_combat_bonus", nullptr);
1545 }
1547 "combat_rules.low_firepower_nonnat_bombard", nullptr);
1550 }
1553 "combat_rules.nuke_pop_loss_pct", nullptr);
1557 }
1560 "combat_rules.nuke_defender_survival_chance_pct", nullptr);
1563 "borders.radius_sq_city", nullptr);
1566 "borders.size_effect", nullptr);
1570 }
1573 "borders.radius_sq_city_permanent", nullptr);
1574
1577 "research.tech_cost_style");
1580 }
1583 "research.base_tech_cost", nullptr);
1586 }
1589 "research.min_tech_cost", nullptr);
1592 "research.tech_leakage");
1595 "research.tech_upkeep_style");
1598 "research.tech_upkeep_divider", nullptr);
1601 "research.free_tech_method");
1602
1605 "culture.victory_min_points", nullptr);
1608 "culture.victory_lead_pct", nullptr);
1611 }
1614 "culture.migration_pml", nullptr);
1617 }
1620 "culture.history_interest_pml", nullptr);
1623 }
1626 "world_peace.victory_turns", nullptr);
1627
1630 "calendar.skip_year_0", nullptr);
1633 "calendar.start_year", nullptr);
1634 if (game.calendar.calendar_fragments != 0) {
1636 }
1638 0, "calendar.fragments", nullptr);
1639
1640 for (i = 0; i < MAX_CALENDAR_FRAGMENTS; i++) {
1641 if (game.calendar.calendar_fragment_name[i][0] != '\0') {
1643 "calendar.fragment_name%d", i);
1644 }
1645 }
1646
1648 struct entry *pentry =
1650 "calendar.positive_label");
1652 }
1654 struct entry *pentry =
1656 "calendar.negative_label");
1658 }
1659
1660 if (game.plr_bg_color != nullptr) {
1661 rgbcolor_save(sfile, game.plr_bg_color, "playercolors.background");
1662 }
1663
1664 col_idx = 0;
1666 rgbcolor_save(sfile, pcol, "playercolors.colorlist%d", col_idx++);
1668
1669
1670 if (game.server.ruledit.named_teams > 0) {
1671 for (i = 0; i < game.server.ruledit.named_teams; i++) {
1673 }
1674
1677 "teams.names");
1678 }
1679
1680 comment_disasters(sfile);
1681
1682 sect_idx = 0;
1684 char path[512];
1686 const char *effect_names[DE_COUNT];
1687
1688 fc_snprintf(path, sizeof(path), "disaster_%d", sect_idx++);
1689
1690 save_name_translation(sfile, &(pd->name), path);
1691 save_reqs_vector(sfile, &(pd->reqs), path, "reqs");
1692 if (pd->frequency != GAME_DEFAULT_DISASTER_FREQ) {
1693 secfile_insert_int(sfile, pd->frequency,
1694 "%s.frequency", path);
1695 }
1696
1697 set_count = 0;
1701 if (BV_ISSET(pd->effects, de)) {
1703 }
1704 }
1705
1706 if (set_count > 0) {
1708 "%s.effects", path);
1709 }
1711
1712 comment_achievements(sfile);
1713
1714 sect_idx = 0;
1716 char path[512];
1717 struct entry *pentry;
1718
1719 fc_snprintf(path, sizeof(path), "achievement_%d", sect_idx++);
1720
1721 save_name_translation(sfile, &(pach->name), path);
1722
1724 "%s.type", path);
1725
1726 save_default_bool(sfile, pach->unique,
1728 path, "unique");
1729 save_default_int(sfile, pach->value,
1731 path, "value");
1732 save_default_int(sfile, pach->culture,
1733 0, path, "culture");
1734
1735 pentry = secfile_insert_str(sfile, pach->first_msg,
1736 "%s.first_msg", path);
1738 if (pach->cons_msg != nullptr) {
1739 pentry = secfile_insert_str(sfile, pach->cons_msg,
1740 "%s.cons_msg", path);
1742 }
1743
1745
1747
1748 set_count = 0;
1749 for (trt = 0; trt < TRT_LAST; trt++) {
1752
1753 if (set->trade_pct != 100 || strcmp(cancelling, "Active")) {
1754 char path[256];
1755
1756 fc_snprintf(path, sizeof(path),
1757 "trade.settings%d", set_count++);
1758
1760 "%s.type", path);
1761 secfile_insert_int(sfile, set->trade_pct,
1762 "%s.pct", path);
1764 "%s.cancelling", path);
1766 "%s.bonus", path);
1767 }
1768 }
1769
1771 0, "trade.min_trade_route_val", nullptr);
1772
1774 FALSE, "trade.reveal_trade_partner", nullptr);
1775
1778 "trade.goods_selection");
1779 }
1780
1781 /* Goods */
1782 comment_goods(sfile);
1783
1784 sect_idx = 0;
1786 char path[512];
1787 const char *flag_names[GF_COUNT];
1788 int flagi;
1789
1790 fc_snprintf(path, sizeof(path), "goods_%d", sect_idx++);
1791
1792 save_name_translation(sfile, &(pgood->name), path);
1793
1794 save_reqs_vector(sfile, &(pgood->reqs), path, "reqs");
1795
1796 save_default_int(sfile, pgood->from_pct, 100, path, "from_pct");
1797 save_default_int(sfile, pgood->to_pct, 100, path, "to_pct");
1798 save_default_int(sfile, pgood->onetime_pct, 100, path, "onetime_pct");
1799 save_default_int(sfile, pgood->select_priority, 1, path, "select_priority");
1800 save_default_int(sfile, pgood->replace_priority, 1, path, "replace_priority");
1801
1802 set_count = 0;
1803 for (flagi = 0; flagi < GF_COUNT; flagi++) {
1804 if (goods_has_flag(pgood, flagi)) {
1806 }
1807 }
1808
1809 if (set_count > 0) {
1811 "%s.flags", path);
1812 }
1813
1814 save_helptext(sfile, pgood->helptext, path, "helptext");
1816
1817 /* Clauses */
1818 comment_clauses(sfile);
1819
1820 sect_idx = 0;
1821 for (i = 0; i < CLAUSE_COUNT; i++) {
1822 struct clause_info *info = clause_info_get(i);
1823
1824 if (info->enabled) {
1825 char path[512];
1826
1827 fc_snprintf(path, sizeof(path), "clause_%d", sect_idx++);
1828
1830 "%s.type", path);
1831 save_reqs_vector(sfile, &(info->giver_reqs), path, "giver_reqs");
1832 save_reqs_vector(sfile, &(info->receiver_reqs), path, "receiver_reqs");
1833 save_reqs_vector(sfile, &(info->either_reqs), path, "either_reqs");
1834 }
1835 }
1836
1837 /* Counters */
1838 comment_counters(sfile);
1839
1840 sect_idx = 0;
1842 char path[512];
1843
1844 fc_snprintf(path, sizeof(path), "counter_%d", sect_idx++);
1845
1846 save_name_translation(sfile, &(pcounter->name), path);
1847
1848 save_default_int(sfile, pcounter->def, 0, path, "def");
1849 save_default_int(sfile, pcounter->checkpoint, 0, path, "checkpoint");
1850
1851 secfile_insert_str(sfile, counter_behavior_name(pcounter->type), "%s.type", path);
1852
1853 if (pcounter->helptext != nullptr
1854 && strvec_size(pcounter->helptext) > 0) {
1855 save_helptext(sfile, pcounter->helptext, path, "helptext");
1856 }
1858
1859 locks = FALSE;
1862 locks = TRUE;
1863 break;
1864 }
1866
1867 set_count = 0;
1869 struct sf_cb_data info = { pset, FALSE };
1870
1873 "settings.set%d.name", set_count);
1874 switch (setting_type(pset)) {
1875 case SST_BOOL:
1877 "settings.set%d.value", set_count);
1878 break;
1879 case SST_INT:
1881 "settings.set%d.value", set_count);
1882 break;
1883 case SST_STRING:
1885 "settings.set%d.value", set_count);
1886 break;
1887 case SST_ENUM:
1890 "settings.set%d.value", set_count);
1891 break;
1892 case SST_BITWISE:
1895 "settings.set%d.value", set_count);
1896 break;
1897 case SST_COUNT:
1899 secfile_insert_str(sfile, "Unknown setting type",
1900 "settings.set%d.value", set_count);
1901 break;
1902 }
1903
1904 if (locks) {
1906 "settings.set%d.lock", set_count);
1907 }
1908
1909 set_count++;
1910 }
1912
1913 return save_ruleset_file(sfile, filename);
1914}
1915
1916/**********************************************************************/
1919static bool save_governments_ruleset(const char *filename, const char *name)
1920{
1921 struct section_file *sfile = create_ruleset_file(name, "government");
1922 int sect_idx;
1923
1924 if (sfile == nullptr) {
1925 return FALSE;
1926 }
1927
1928 save_gov_ref(sfile, game.government_during_revolution, "governments",
1929 "during_revolution");
1930
1931 comment_govs(sfile);
1932
1933 sect_idx = 0;
1935 char path[512];
1936 struct ruler_title *prtitle;
1937
1938 fc_snprintf(path, sizeof(path), "government_%d", sect_idx++);
1939
1940 save_name_translation(sfile, &(pg->name), path);
1941
1942 secfile_insert_str(sfile, pg->graphic_str, "%s.graphic", path);
1943 secfile_insert_str(sfile, pg->graphic_alt, "%s.graphic_alt", path);
1944 secfile_insert_str(sfile, pg->sound_str, "%s.sound", path);
1945 secfile_insert_str(sfile, pg->sound_alt, "%s.sound_alt", path);
1946
1947 save_reqs_vector(sfile, &(pg->reqs), path, "reqs");
1948
1949 if (pg->ai.better != nullptr) {
1950 save_gov_ref(sfile, pg->ai.better, path,
1951 "ai_better");
1952 }
1953
1954 ruler_title_hash_lookup(pg->ruler_titles, nullptr,
1955 &prtitle);
1956 if (prtitle != nullptr) {
1957 const char *title;
1958
1960 if (title != nullptr) {
1961 struct entry *pentry =
1962 secfile_insert_str(sfile, title, "%s.ruler_male_title", path);
1964 }
1965
1967 if (title != nullptr) {
1968 struct entry *pentry =
1969 secfile_insert_str(sfile, title, "%s.ruler_female_title", path);
1971 }
1972 }
1973
1974 save_helptext(sfile, pg->helptext, path, "helptext");
1975
1977
1978 comment_policies(sfile);
1979
1980 sect_idx = 0;
1981 multipliers_iterate(pmul) {
1982 if (!pmul->ruledit_disabled) {
1983 char path[512];
1984
1985 fc_snprintf(path, sizeof(path), "multiplier_%d", sect_idx++);
1986
1987 save_name_translation(sfile, &(pmul->name), path);
1988
1989 secfile_insert_int(sfile, pmul->start, "%s.start", path);
1990 secfile_insert_int(sfile, pmul->stop, "%s.stop", path);
1991 secfile_insert_int(sfile, pmul->step, "%s.step", path);
1992 secfile_insert_int(sfile, pmul->def, "%s.default", path);
1993
1994 save_default_int(sfile, pmul->offset, 0, path, "offset");
1995 save_default_int(sfile, pmul->factor, 100, path, "factor");
1996 save_default_int(sfile, pmul->minimum_turns, 0, path, "minimum_turns");
1997
1998 save_reqs_vector(sfile, &(pmul->reqs), path, "reqs");
1999
2000 save_helptext(sfile, pmul->helptext, path, "helptext");
2001 }
2003
2004 return save_ruleset_file(sfile, filename);
2005}
2006
2007/**********************************************************************/
2010static bool save_traits(struct trait_limits *traits,
2011 struct trait_limits *default_traits,
2012 struct section_file *sfile,
2013 const char *secname, const char *field_prefix)
2014{
2015 enum trait tr;
2016
2017 /* FIXME: Use specenum trait names without duplicating them here.
2018 * Just needs to take care of case.
2019 * This list is also duplicated in ruleset.c:ruleset_load_traits() */
2020 const char *trait_names[] = {
2021 "expansionist",
2022 "trader",
2023 "aggressive",
2024 "builder",
2025 nullptr
2026 };
2027
2028 for (tr = trait_begin(); tr != trait_end() && trait_names[tr] != nullptr;
2029 tr = trait_next(tr)) {
2030 int default_default;
2031
2032 default_default = (traits[tr].min + traits[tr].max) / 2;
2033
2034 if ((default_traits == nullptr && traits[tr].min != TRAIT_DEFAULT_VALUE)
2035 || (default_traits != nullptr && traits[tr].min != default_traits[tr].min)) {
2036 secfile_insert_int(sfile, traits[tr].min, "%s.%s%s_min", secname, field_prefix,
2037 trait_names[tr]);
2038 }
2039 if ((default_traits == nullptr && traits[tr].max != TRAIT_DEFAULT_VALUE)
2040 || (default_traits != nullptr && traits[tr].max != default_traits[tr].max)) {
2041 secfile_insert_int(sfile, traits[tr].max, "%s.%s%s_max", secname, field_prefix,
2042 trait_names[tr]);
2043 }
2044 if (default_default != traits[tr].fixed) {
2045 secfile_insert_int(sfile, traits[tr].fixed, "%s.%s%s_default", secname, field_prefix,
2046 trait_names[tr]);
2047 }
2048 }
2049
2050 return TRUE;
2051}
2052
2053/**********************************************************************/
2056static bool save_nation(struct section_file *sfile, struct nation_type *pnat,
2057 int sect_idx)
2058{
2059 char path[512];
2060 int max_items = nation_city_list_size(pnat->server.default_cities);
2061 char *city_str[max_items];
2064 const char *list_items[max_items];
2065 int set_count;
2066 int subsect_idx;
2067
2068 fc_snprintf(path, sizeof(path), "nation_%d", sect_idx++);
2069
2070 if (pnat->translation_domain == nullptr) {
2071 secfile_insert_str(sfile, "freeciv-core", "%s.translation_domain", path);
2072 } else {
2073 secfile_insert_str(sfile, pnat->translation_domain, "%s.translation_domain", path);
2074 }
2075
2076 save_name_translation(sfile, &(pnat->adjective), path);
2077 secfile_insert_str(sfile, untranslated_name(&(pnat->noun_plural)), "%s.plural", path);
2078
2079 set_count = 0;
2081 if (nation_is_in_set(pnat, pset)) {
2083 }
2088 }
2090
2091 if (set_count > 0) {
2092 secfile_insert_str_vec(sfile, list_items, set_count, "%s.groups", path);
2093 }
2094
2095 set_count = 0;
2096 nation_list_iterate(pnat->server.conflicts_with, pconfl) {
2099 if (set_count > 0) {
2100 secfile_insert_str_vec(sfile, list_items, set_count, "%s.conflicts_with", path);
2101 }
2102
2103 subsect_idx = 0;
2105 secfile_insert_str(sfile, nation_leader_name(pleader), "%s.leaders%d.name",
2106 path, subsect_idx);
2107 secfile_insert_str(sfile,
2110 "%s.leaders%d.sex", path, subsect_idx++);
2112
2113 if (pnat->server.rgb != nullptr) {
2114 rgbcolor_save(sfile, pnat->server.rgb, "%s.color", path);
2115 }
2116
2117 save_traits(pnat->server.traits, game.server.default_traits,
2118 sfile, path, "trait_");
2119
2120 if (!pnat->is_playable) {
2121 secfile_insert_bool(sfile, pnat->is_playable, "%s.is_playable", path);
2122 }
2123
2124 if (pnat->barb_type != NOT_A_BARBARIAN) {
2125 secfile_insert_str(sfile, barbarian_type_name(pnat->barb_type),
2126 "%s.barbarian_type", path);
2127 }
2128
2129 if (strcmp(pnat->flag_graphic_str, "-")) {
2130 secfile_insert_str(sfile, pnat->flag_graphic_str, "%s.flag", path);
2131 }
2132 if (strcmp(pnat->flag_graphic_alt, "-")) {
2133 secfile_insert_str(sfile, pnat->flag_graphic_alt, "%s.flag_alt", path);
2134 }
2135
2136 subsect_idx = 0;
2138 struct ruler_title *prtitle;
2139
2140 if (ruler_title_hash_lookup(pgov->ruler_titles, pnat, &prtitle)) {
2142 "%s.ruler_titles%d.government", path, subsect_idx);
2144 "%s.ruler_titles%d.male_title", path, subsect_idx);
2146 "%s.ruler_titles%d.female_title", path, subsect_idx++);
2147 }
2149
2150 secfile_insert_str(sfile, style_rule_name(pnat->style), "%s.style", path);
2151
2152 set_count = 0;
2153 nation_list_iterate(pnat->server.civilwar_nations, pconfl) {
2156 if (set_count > 0) {
2157 secfile_insert_str_vec(sfile, list_items, set_count, "%s.civilwar_nations", path);
2158 }
2159
2160 save_tech_list(sfile, pnat->init_techs, path, "init_techs");
2161 save_building_list(sfile, pnat->init_buildings, path, "init_buildings");
2162 save_unit_list(sfile, pnat->init_units, path, "init_units");
2163
2164 if (pnat->init_government) {
2165 secfile_insert_str(sfile, government_rule_name(pnat->init_government),
2166 "%s.init_government", path);
2167 }
2168
2169 set_count = 0;
2170 nation_city_list_iterate(pnat->server.default_cities, pncity) {
2171 bool list_started = FALSE;
2172
2174 + strlen(")")
2175 + MAX_NUM_TERRAINS * (strlen(", ") + MAX_LEN_NAME));
2176
2179 case NCP_DISLIKE:
2180 strcat(city_str[set_count], " (!river");
2182 break;
2183 case NCP_LIKE:
2184 strcat(city_str[set_count], " (river");
2186 break;
2187 case NCP_NONE:
2188 break;
2189 }
2190
2192 const char *pref = nullptr;
2193
2195 case NCP_DISLIKE:
2196 pref = "!";
2197 break;
2198 case NCP_LIKE:
2199 pref = "";
2200 break;
2201 case NCP_NONE:
2202 pref = nullptr;
2203 break;
2204 }
2205
2206 if (pref != nullptr) {
2207 if (list_started) {
2208 strcat(city_str[set_count], ", ");
2209 } else {
2210 strcat(city_str[set_count], " (");
2212 }
2215 }
2216
2218
2219 if (list_started) {
2220 strcat(city_str[set_count], ")");
2221 }
2222
2224 set_count++;
2226 if (set_count > 0) {
2227 int i;
2228
2229 secfile_insert_str_vec(sfile, list_items, set_count, "%s.cities", path);
2230
2231 for (i = 0; i < set_count; i++) {
2232 FC_FREE(city_str[i]);
2233 }
2234 }
2235
2236 secfile_insert_str(sfile, pnat->legend, "%s.legend", path);
2237
2238 return TRUE;
2239}
2240
2241/**********************************************************************/
2244static bool save_nations_ruleset(const char *filename, const char *name,
2245 struct rule_data *data)
2246{
2247 struct section_file *sfile = create_ruleset_file(name, "nation");
2248
2249 if (sfile == nullptr) {
2250 return FALSE;
2251 }
2252
2253 if (data->nationlist != nullptr || game.server.ruledit.embedded_nations != nullptr) {
2255 if (data->nationlist != nullptr) {
2256 secfile_insert_str(sfile, data->nationlist, "ruledit.nationlist");
2257 }
2258 if (game.server.ruledit.embedded_nations != nullptr) {
2259 int i;
2260 const char **tmp = fc_malloc(game.server.ruledit.embedded_nations_count * sizeof(char *));
2261
2262 /* Dance around the secfile_insert_str_vec() parameter type (requires extra const)
2263 * resrictions */
2264 for (i = 0; i < game.server.ruledit.embedded_nations_count; i++) {
2266 }
2267
2270 "ruledit.embedded_nations");
2271 free(tmp);
2272 }
2273 }
2274
2275 save_traits(game.server.default_traits, nullptr, sfile,
2276 "default_traits", "");
2277
2278 if (data->nationlist == nullptr) {
2279 if (game.server.ruledit.allowed_govs != nullptr) {
2282 "compatibility.allowed_govs");
2283 }
2284 if (game.server.ruledit.allowed_terrains != nullptr) {
2287 "compatibility.allowed_terrains");
2288 }
2289 if (game.server.ruledit.allowed_styles != nullptr) {
2292 "compatibility.allowed_styles");
2293 }
2294 }
2295
2296 if (game.default_government != nullptr) {
2298 "compatibility.default_government");
2299 }
2300
2301 if (data->nationlist != nullptr) {
2302 secfile_insert_include(sfile, data->nationlist);
2303
2304 if (game.server.ruledit.embedded_nations != nullptr) {
2305 int sect_idx;
2306
2307 comment_nations(sfile);
2308
2310 sect_idx++) {
2311 struct nation_type *pnat
2313
2314 if (pnat == nullptr) {
2315 log_error("Embedded nation \"%s\" not found!",
2317 } else {
2318 save_nation(sfile, pnat, sect_idx);
2319 }
2320 }
2321 }
2322 } else {
2323 int sect_idx = 0;
2324
2325 comment_nationsets(sfile);
2326
2328 char path[512];
2329
2330 fc_snprintf(path, sizeof(path), "nset_%d", sect_idx++);
2331
2332 /* We don't use save_name_translation() for this as name and rule_name must
2333 * always be saved separately */
2334 secfile_insert_str(sfile, nation_set_untranslated_name(pset), "%s.name", path);
2335 secfile_insert_str(sfile, nation_set_rule_name(pset), "%s.rule_name", path);
2336 secfile_insert_str(sfile, nation_set_description(pset), "%s.description", path);
2338
2339 comment_nationgroups(sfile);
2340
2341 sect_idx = 0;
2343 char path[512];
2344
2345 fc_snprintf(path, sizeof(path), "ngroup_%d", sect_idx++);
2346
2347 save_name_translation(sfile, &(pgroup->name), path);
2348
2349 secfile_insert_int(sfile, pgroup->server.match, "%s.match", path);
2350 if (pgroup->hidden) {
2351 secfile_insert_bool(sfile, pgroup->hidden, "%s.hidden", path);
2352 }
2354
2355 comment_nations(sfile);
2356
2357 sect_idx = 0;
2359 save_nation(sfile, pnat, sect_idx++);
2361 }
2362
2363 return save_ruleset_file(sfile, filename);
2364}
2365
2366/**********************************************************************/
2369static bool save_techs_ruleset(const char *filename, const char *name)
2370{
2371 struct section_file *sfile = create_ruleset_file(name, "tech");
2372 int i;
2373 int sect_idx;
2375 bool uflags_tech = FALSE;
2376
2377 if (sfile == nullptr) {
2378 return FALSE;
2379 }
2380
2381 for (i = 0; i < MAX_NUM_USER_TECH_FLAGS; i++) {
2382 const char *flagname = tech_flag_id_name_cb(i + TECH_USER_1);
2383 const char *helptxt = tech_flag_helptxt(i + TECH_USER_1);
2384 struct entry *pentry;
2385
2386 if (flagname != nullptr) {
2387 if (!uflags_tech) {
2388 comment_uflags_tech(sfile);
2389 uflags_tech = TRUE;
2390 }
2391
2393 "control.flags%d.name", i);
2395
2396 /* Save the user flag help text even when it is undefined. That makes
2397 * the formatting code happy. The resulting "" is ignored when the
2398 * ruleset is loaded. */
2399 pentry = secfile_insert_str(sfile, helptxt,
2400 "control.flags%d.helptxt", i);
2402 }
2403 }
2404
2405 comment_tech_classes(sfile);
2406
2407 sect_idx = 0;
2409 char path[512];
2410
2411 fc_snprintf(path, sizeof(path), "techclass_%d", sect_idx++);
2412
2413 save_name_translation(sfile, &(ptclass->name), path);
2415
2416 comment_techs(sfile);
2417
2418 sect_idx = 0;
2420 if (pa->require[AR_ONE] != A_NEVER) {
2421 char path[512];
2422 const char *flag_names[TF_COUNT];
2423 int set_count;
2424 int flagi;
2425
2426 fc_snprintf(path, sizeof(path), "advance_%d", sect_idx++);
2427
2428 save_name_translation(sfile, &(pa->name), path);
2429
2430 if (game.control.num_tech_classes > 0) {
2431 if (pa->tclass != nullptr) {
2433 "%s.class", path);
2434 }
2435 }
2436
2437 save_tech_ref(sfile, pa->require[AR_ONE], path, "req1");
2438 save_tech_ref(sfile, pa->require[AR_TWO], path, "req2");
2439 if (pa->require[AR_ROOT] != a_none && !pa->inherited_root_req) {
2440 save_tech_ref(sfile, pa->require[AR_ROOT], path, "root_req");
2441 }
2442
2443 save_reqs_vector(sfile, &(pa->research_reqs), path,
2444 "research_reqs");
2445
2446 secfile_insert_str(sfile, pa->graphic_str, "%s.graphic", path);
2447 if (strcmp("-", pa->graphic_alt)) {
2448 secfile_insert_str(sfile, pa->graphic_alt, "%s.graphic_alt", path);
2449 }
2450 if (pa->bonus_message != nullptr) {
2451 struct entry *pentry =
2452 secfile_insert_str(sfile, pa->bonus_message,
2453 "%s.bonus_message", path);
2455 }
2456
2457 set_count = 0;
2458 for (flagi = 0; flagi < TF_COUNT; flagi++) {
2461 }
2462 }
2463
2464 if (set_count > 0) {
2466 "%s.flags", path);
2467 }
2468 if (pa->cost >= 0) {
2469 secfile_insert_int(sfile, pa->cost, "%s.cost", path);
2470 }
2471
2472 save_helptext(sfile, pa->helptext, path, "helptext");
2473 }
2474
2476
2477 return save_ruleset_file(sfile, filename);
2478}
2479
2480/**********************************************************************/
2483static bool save_terrain_ruleset(const char *filename, const char *name)
2484{
2485 struct section_file *sfile = create_ruleset_file(name, "terrain");
2486 int sect_idx;
2487 int i;
2488 bool uflags_terr = FALSE;
2489 bool uflags_extra = FALSE;
2490
2491 if (sfile == nullptr) {
2492 return FALSE;
2493 }
2494
2495 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
2497 const char *helptxt = terrain_flag_helptxt(i + TER_USER_1);
2498 struct entry *pentry;
2499
2500 if (flagname != nullptr) {
2501 if (!uflags_terr) {
2503 uflags_terr = TRUE;
2504 }
2505
2507 "control.flags%d.name", i);
2509
2510 /* Save the user flag help text even when it is undefined. That makes
2511 * the formatting code happy. The resulting "" is ignored when the
2512 * ruleset is loaded. */
2513 pentry = secfile_insert_str(sfile, helptxt,
2514 "control.flags%d.helptxt", i);
2516 }
2517 }
2518
2519 for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
2521 const char *helptxt = extra_flag_helptxt(i + EF_USER_FLAG_1);
2522 struct entry *pentry;
2523
2524 if (flagname != nullptr) {
2525 if (!uflags_extra) {
2526 /* TODO: Uncomment this, once there's a way to stop
2527 * the comment getting written inside preceding
2528 * terrain flags table. */
2529 /* comment_uflags_extra(sfile); */
2531 }
2532
2534 "control.extra_flags%d.name", i);
2536
2537 /* Save the user flag help text even when it is undefined. That makes
2538 * the formatting code happy. The resulting "" is ignored when the
2539 * ruleset is loaded. */
2540 pentry = secfile_insert_str(sfile, helptxt,
2541 "control.extra_flags%d.helptxt", i);
2543 }
2544 }
2545
2546 if (terrain_control.ocean_reclaim_requirement_pct <= 100) {
2547 secfile_insert_int(sfile, terrain_control.ocean_reclaim_requirement_pct,
2548 "parameters.ocean_reclaim_requirement");
2549 }
2550 if (terrain_control.land_channel_requirement_pct <= 100) {
2551 secfile_insert_int(sfile, terrain_control.land_channel_requirement_pct,
2552 "parameters.land_channel_requirement");
2553 }
2554 if (terrain_control.terrain_thaw_requirement_pct <= 100) {
2555 secfile_insert_int(sfile, terrain_control.terrain_thaw_requirement_pct,
2556 "parameters.thaw_requirement");
2557 }
2558 if (terrain_control.terrain_freeze_requirement_pct <= 100) {
2559 secfile_insert_int(sfile, terrain_control.terrain_freeze_requirement_pct,
2560 "parameters.freeze_requirement");
2561 }
2562 if (terrain_control.lake_max_size != 0) {
2563 secfile_insert_int(sfile, terrain_control.lake_max_size,
2564 "parameters.lake_max_size");
2565 }
2566 if (terrain_control.min_start_native_area != 0) {
2567 secfile_insert_int(sfile, terrain_control.min_start_native_area,
2568 "parameters.min_start_native_area");
2569 }
2570 if (terrain_control.move_fragments != 3) {
2571 secfile_insert_int(sfile, terrain_control.move_fragments,
2572 "parameters.move_fragments");
2573 }
2574 if (terrain_control.igter_cost != 1) {
2575 secfile_insert_int(sfile, terrain_control.igter_cost,
2576 "parameters.igter_cost");
2577 }
2578 if (terrain_control.pythagorean_diagonal != RS_DEFAULT_PYTHAGOREAN_DIAGONAL) {
2579 secfile_insert_bool(sfile, terrain_control.pythagorean_diagonal,
2580 "parameters.pythagorean_diagonal");
2581 }
2584 "parameters.ocean_resources");
2585 }
2586
2587 comment_terrains(sfile);
2588
2589 sect_idx = 0;
2591 char path[512];
2592 char identifier[2];
2593 int r;
2594 const char *flag_names[TER_USER_LAST];
2595 const char *puc_names[UCL_LAST];
2596 int flagi;
2597 int set_count;
2598
2599 fc_snprintf(path, sizeof(path), "terrain_%d", sect_idx++);
2600
2601 save_name_translation(sfile, &(pterr->name), path);
2602
2603 secfile_insert_str(sfile, pterr->graphic_str, "%s.graphic", path);
2604 secfile_insert_str(sfile, pterr->graphic_alt, "%s.graphic_alt", path);
2605 secfile_insert_str(sfile, pterr->graphic_alt2, "%s.graphic_alt2", path);
2606 identifier[0] = pterr->identifier;
2607 identifier[1] = '\0';
2608 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2609
2611 "%s.class", path);
2612
2613 secfile_insert_int(sfile, pterr->movement_cost, "%s.movement_cost", path);
2614 secfile_insert_int(sfile, pterr->defense_bonus, "%s.defense_bonus", path);
2615
2617 if (pterr->output[o] != 0) {
2618 secfile_insert_int(sfile, pterr->output[o], "%s.%s", path,
2620 }
2622
2623 /* Check resource count */
2624 for (r = 0; pterr->resources[r] != nullptr; r++) {
2625 /* Just increasing r as long as there are resources */
2626 }
2627
2628 {
2629 const char *resource_names[r];
2630 bool save_frequencies = FALSE;
2631
2632 r = 0;
2637 }
2639
2641 "%s.resources", path);
2642
2643 if (save_frequencies) {
2644 secfile_insert_int_vec(sfile, pterr->resource_freq, r,
2645 "%s.resource_freq", path);
2646 }
2647 }
2648
2650 if (pterr->road_output_incr_pct[o] != 0) {
2651 secfile_insert_int(sfile, pterr->road_output_incr_pct[o],
2652 "%s.road_%s_incr_pct", path,
2654 }
2656
2657 secfile_insert_int(sfile, pterr->base_time, "%s.base_time", path);
2658 secfile_insert_int(sfile, pterr->road_time, "%s.road_time", path);
2659
2660 save_terrain_ref(sfile, pterr->cultivate_result, pterr, path,
2661 "cultivate_result");
2662 secfile_insert_int(sfile, pterr->cultivate_time,
2663 "%s.cultivate_time", path);
2664
2665 save_terrain_ref(sfile, pterr->plant_result, pterr, path,
2666 "plant_result");
2667 secfile_insert_int(sfile, pterr->plant_time,
2668 "%s.plant_time", path);
2669
2670 secfile_insert_int(sfile, pterr->irrigation_food_incr,
2671 "%s.irrigation_food_incr", path);
2672 secfile_insert_int(sfile, pterr->irrigation_time,
2673 "%s.irrigation_time", path);
2674
2675 secfile_insert_int(sfile, pterr->mining_shield_incr,
2676 "%s.mining_shield_incr", path);
2677 secfile_insert_int(sfile, pterr->mining_time,
2678 "%s.mining_time", path);
2679
2680 save_terrain_ref(sfile, pterr->transform_result, pterr, path,
2681 "transform_result");
2682 secfile_insert_int(sfile, pterr->transform_time,
2683 "%s.transform_time", path);
2684
2685 if (pterr->num_animals > 0) {
2686 const char *animal_names[pterr->num_animals];
2687 int count = 0;
2688
2693 "%s.animals", path);
2694 }
2695
2696 secfile_insert_int(sfile, pterr->placing_time,
2697 "%s.placing_time", path);
2698 secfile_insert_int(sfile, pterr->pillage_time,
2699 "%s.pillage_time", path);
2700
2701 i = 0;
2702 extra_type_iterate(pextra) {
2703 int rmtime = pterr->extra_removal_times[extra_index(pextra)];
2704
2705 if (rmtime != 0) {
2706 secfile_insert_str(sfile, extra_rule_name(pextra),
2707 "%s.extra_settings%d.extra",
2708 path, i);
2710 "%s.extra_settings%d.removal_time",
2711 path, i++);
2712 }
2714
2715 save_terrain_ref(sfile, pterr->warmer_wetter_result, pterr, path,
2716 "warmer_wetter_result");
2717 save_terrain_ref(sfile, pterr->warmer_drier_result, pterr, path,
2718 "warmer_drier_result");
2719 save_terrain_ref(sfile, pterr->cooler_wetter_result, pterr, path,
2720 "cooler_wetter_result");
2721 save_terrain_ref(sfile, pterr->cooler_drier_result, pterr, path,
2722 "cooler_drier_result");
2723
2724 set_count = 0;
2725 for (flagi = 0; flagi < TER_USER_LAST; flagi++) {
2728 }
2729 }
2730
2731 if (set_count > 0) {
2733 "%s.flags", path);
2734 }
2735
2736 {
2738
2742 if (pterr->property[mtp] != 0) {
2743 secfile_insert_int(sfile, pterr->property[mtp],
2744 "%s.property_%s", path,
2746 }
2747 }
2748 }
2749
2750 set_count = 0;
2752 if (BV_ISSET(pterr->native_to, uclass_index(puc))) {
2754 }
2756
2757 if (set_count > 0) {
2759 "%s.native_to", path);
2760 }
2761
2762 rgbcolor_save(sfile, pterr->rgb, "%s.color", path);
2763
2764 save_helptext(sfile, pterr->helptext, path, "helptext");
2765
2767
2768 comment_resources(sfile);
2769
2770 sect_idx = 0;
2772 if (!pres->ruledit_disabled) {
2773 char path[512];
2774 char identifier[2];
2775
2776 fc_snprintf(path, sizeof(path), "resource_%d", sect_idx++);
2777
2779 "%s.extra", path);
2780
2782 if (pres->data.resource->output[o] != 0) {
2783 secfile_insert_int(sfile, pres->data.resource->output[o], "%s.%s",
2784 path, get_output_identifier(o));
2785 }
2787
2788 if (pres->data.resource->id_old_save != '\0') {
2789 identifier[0] = pres->data.resource->id_old_save;
2790 identifier[1] = '\0';
2791 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2792 }
2793 }
2795
2796 {
2797 struct entry *pentry =
2798 secfile_insert_str(sfile, terrain_control.gui_type_base0,
2799 "extraui.ui_name_base_fortress");
2801 pentry = secfile_insert_str(sfile, terrain_control.gui_type_base1,
2802 "extraui.ui_name_base_airbase");
2804 }
2805
2806 comment_extras(sfile);
2807
2808 sect_idx = 0;
2810 char path[512];
2811 const char *flag_names[EF_COUNT];
2812 const char *cause_names[EC_COUNT];
2813 const char *puc_names[UCL_LAST];
2814 const char *extra_names[MAX_EXTRA_TYPES];
2815 int flagi;
2816 int causei;
2817 int set_count;
2818 bool worker_cause;
2819
2820 fc_snprintf(path, sizeof(path), "extra_%d", sect_idx++);
2821
2822 save_name_translation(sfile, &(pextra->name), path);
2823
2824 secfile_insert_str(sfile, extra_category_name(pextra->category),
2825 "%s.category", path);
2826
2827 set_count = 0;
2828 for (causei = 0; causei < EC_COUNT; causei++) {
2829 if (is_extra_caused_by(pextra, causei)) {
2831 }
2832 }
2833
2834 if (set_count > 0) {
2836 "%s.causes", path);
2837 }
2838
2839 set_count = 0;
2840 for (causei = 0; causei < ERM_COUNT; causei++) {
2841 if (is_extra_removed_by(pextra, causei)) {
2843 }
2844 }
2845
2846 if (set_count > 0) {
2848 "%s.rmcauses", path);
2849 }
2850
2851 if (strcmp(pextra->graphic_str, "-")) {
2852 secfile_insert_str(sfile, pextra->graphic_str, "%s.graphic", path);
2853 }
2854 if (strcmp(pextra->graphic_alt, "-")) {
2855 secfile_insert_str(sfile, pextra->graphic_alt, "%s.graphic_alt", path);
2856 }
2857 if (strcmp(pextra->activity_gfx, "-")) {
2858 secfile_insert_str(sfile, pextra->activity_gfx, "%s.activity_gfx", path);
2859 }
2860 if (strcmp(pextra->act_gfx_alt, "-")) {
2861 secfile_insert_str(sfile, pextra->act_gfx_alt, "%s.act_gfx_alt", path);
2862 }
2863 if (strcmp(pextra->act_gfx_alt2, "-")) {
2864 secfile_insert_str(sfile, pextra->act_gfx_alt2, "%s.act_gfx_alt2", path);
2865 }
2866 if (strcmp(pextra->rmact_gfx, "-")) {
2867 secfile_insert_str(sfile, pextra->rmact_gfx, "%s.rmact_gfx", path);
2868 }
2869 if (strcmp(pextra->rmact_gfx_alt, "-")) {
2870 secfile_insert_str(sfile, pextra->rmact_gfx_alt, "%s.rmact_gfx_alt", path);
2871 }
2872
2873 save_reqs_vector(sfile, &(pextra->reqs), path, "reqs");
2874 save_reqs_vector(sfile, &(pextra->rmreqs), path, "rmreqs");
2875 save_reqs_vector(sfile, &(pextra->appearance_reqs), path, "appearance_reqs");
2876 save_reqs_vector(sfile, &(pextra->disappearance_reqs), path, "disappearance_reqs");
2877
2879 if ((!pextra->buildable && worker_cause)
2880 || (pextra->buildable && !worker_cause)) {
2881 secfile_insert_bool(sfile, pextra->buildable, "%s.buildable", path);
2882 }
2883 if (!pextra->generated) {
2884 secfile_insert_bool(sfile, pextra->generated, "%s.generated", path);
2885 }
2886 secfile_insert_int(sfile, pextra->build_time, "%s.build_time", path);
2887 secfile_insert_int(sfile, pextra->removal_time, "%s.removal_time", path);
2888 if (pextra->build_time_factor != 1) {
2889 secfile_insert_int(sfile, pextra->build_time_factor, "%s.build_time_factor", path);
2890 }
2891 if (pextra->removal_time_factor != 1) {
2892 secfile_insert_int(sfile, pextra->removal_time_factor, "%s.removal_time_factor", path);
2893 }
2894 if (pextra->infracost != 0) {
2895 secfile_insert_int(sfile, pextra->infracost, "%s.infracost", path);
2896 }
2897 if (pextra->defense_bonus != 0) {
2898 secfile_insert_int(sfile, pextra->defense_bonus, "%s.defense_bonus", path);
2899 }
2900 if (pextra->eus != EUS_NORMAL) {
2902 "%s.unit_seen", path);
2903 }
2905 && pextra->appearance_chance != RS_DEFAULT_EXTRA_APPEARANCE) {
2906 secfile_insert_int(sfile, pextra->appearance_chance, "%s.appearance_chance", path);
2907 }
2909 && pextra->disappearance_chance != RS_DEFAULT_EXTRA_DISAPPEARANCE) {
2910 secfile_insert_int(sfile, pextra->disappearance_chance, "%s.disappearance_chance",
2911 path);
2912 }
2913
2914 set_count = 0;
2916 if (BV_ISSET(pextra->native_to, uclass_index(puc))) {
2918 }
2920
2921 if (set_count > 0) {
2923 "%s.native_to", path);
2924 }
2925
2926 if (pextra->no_aggr_near_city >= 0) {
2927 secfile_insert_int(sfile, pextra->no_aggr_near_city,
2928 "%s.no_aggr_near_city", path);
2929 }
2930
2931 set_count = 0;
2932 for (flagi = 0; flagi < EF_COUNT; flagi++) {
2933 if (extra_has_flag(pextra, flagi)) {
2935 }
2936 }
2937
2938 if (set_count > 0) {
2940 "%s.flags", path);
2941 }
2942
2943 set_count = 0;
2945 if (!can_extras_coexist(pextra, confl)) {
2947 }
2949
2950 if (set_count > 0) {
2952 "%s.conflicts", path);
2953 }
2954
2955 set_count = 0;
2956 extra_type_iterate(top) {
2957 if (BV_ISSET(pextra->hidden_by, extra_index(top))) {
2959 }
2961
2962 if (set_count > 0) {
2964 "%s.hidden_by", path);
2965 }
2966
2967 set_count = 0;
2968 extra_type_iterate(top) {
2969 if (BV_ISSET(pextra->bridged_over, extra_index(top))) {
2971 }
2973
2974 if (set_count > 0) {
2976 "%s.bridged_over", path);
2977 }
2978
2979 save_helptext(sfile, pextra->helptext, path, "helptext");
2980
2982
2983 comment_bases(sfile);
2984
2985 sect_idx = 0;
2987 if (!pextra->ruledit_disabled) {
2988 char path[512];
2989 struct base_type *pbase = extra_base_get(pextra);
2990
2991 fc_snprintf(path, sizeof(path), "base_%d", sect_idx++);
2992
2993 secfile_insert_str(sfile, extra_rule_name(pextra),
2994 "%s.extra", path);
2995
2997 "%s.gui_type", path);
2998
2999 if (pbase->border_sq >= 0) {
3000 secfile_insert_int(sfile, pbase->border_sq, "%s.border_sq", path);
3001 }
3002 if (pbase->vision_main_sq >= 0) {
3003 secfile_insert_int(sfile, pbase->vision_main_sq, "%s.vision_main_sq", path);
3004 }
3005 if (pbase->vision_invis_sq >= 0) {
3006 secfile_insert_int(sfile, pbase->vision_invis_sq, "%s.vision_invis_sq", path);
3007 }
3008 if (pbase->vision_subs_sq >= 0) {
3009 secfile_insert_int(sfile, pbase->vision_subs_sq, "%s.vision_subs_sq", path);
3010 }
3011 }
3013
3014 comment_roads(sfile);
3015
3016 sect_idx = 0;
3018 if (!pextra->ruledit_disabled) {
3019 struct road_type *proad = extra_road_get(pextra);
3020 char path[512];
3021 const char *flag_names[RF_COUNT];
3022 int flagi;
3023 int set_count;
3024
3025 fc_snprintf(path, sizeof(path), "road_%d", sect_idx++);
3026
3027 secfile_insert_str(sfile, extra_rule_name(pextra),
3028 "%s.extra", path);
3029
3030 save_reqs_vector(sfile, &(proad->first_reqs), path, "first_reqs");
3031
3032 secfile_insert_int(sfile, proad->move_cost, "%s.move_cost", path);
3033
3034 if (proad->move_mode != RMM_FAST_ALWAYS) {
3035 secfile_insert_str(sfile, road_move_mode_name(proad->move_mode),
3036 "%s.move_mode", path);
3037 }
3038
3040 if (proad->tile_incr_const[o] != 0) {
3041 secfile_insert_int(sfile, proad->tile_incr_const[o],
3042 "%s.%s_incr_const", path, get_output_identifier(o));
3043 }
3044 if (proad->tile_incr[o] != 0) {
3045 secfile_insert_int(sfile, proad->tile_incr[o],
3046 "%s.%s_incr", path, get_output_identifier(o));
3047 }
3048 if (proad->tile_bonus[o] != 0) {
3049 secfile_insert_int(sfile, proad->tile_bonus[o],
3050 "%s.%s_bonus", path, get_output_identifier(o));
3051 }
3053
3054 switch (proad->compat) {
3055 case ROCO_ROAD:
3056 secfile_insert_str(sfile, "Road", "%s.compat_special", path);
3057 break;
3058 case ROCO_RAILROAD:
3059 secfile_insert_str(sfile, "Railroad", "%s.compat_special", path);
3060 break;
3061 case ROCO_RIVER:
3062 secfile_insert_str(sfile, "River", "%s.compat_special", path);
3063 break;
3064 case ROCO_NONE:
3065 secfile_insert_str(sfile, "None", "%s.compat_special", path);
3066 break;
3067 }
3068
3070 "%s.gui_type", path);
3071
3072 set_count = 0;
3073 for (flagi = 0; flagi < RF_COUNT; flagi++) {
3074 if (road_has_flag(proad, flagi)) {
3076 }
3077 }
3078
3079 if (set_count > 0) {
3081 "%s.flags", path);
3082 }
3083
3084 if (extra_type_list_size(proad->integrators) > 0) {
3085 const char *integrate_names[extra_type_list_size(proad->integrators)];
3086
3087 set_count = 0;
3088 extra_type_list_iterate(proad->integrators, iextra) {
3089 if (iextra != pextra) {
3091 }
3093
3094 if (set_count > 0) {
3096 "%s.integrates", path);
3097 }
3098 }
3099 }
3101
3102 return save_ruleset_file(sfile, filename);
3103}
3104
3105/**********************************************************************/
3108static bool save_veteran_system(struct section_file *sfile, const char *path,
3109 struct veteran_system *vsystem)
3110{
3111 const char *vlist_name[vsystem->levels];
3112 int vlist_power[vsystem->levels];
3113 int vlist_raise[vsystem->levels];
3114 int vlist_wraise[vsystem->levels];
3115 int vlist_move[vsystem->levels];
3116 int i;
3117
3118 for (i = 0; i < vsystem->levels; i++) {
3119 vlist_name[i] = rule_name_get(&(vsystem->definitions[i].name));
3120 vlist_power[i] = vsystem->definitions[i].power_fact;
3121 vlist_raise[i] = vsystem->definitions[i].base_raise_chance;
3122 vlist_wraise[i] = vsystem->definitions[i].work_raise_chance;
3123 vlist_move[i] = vsystem->definitions[i].move_bonus;
3124 }
3125
3127 "%s.veteran_names", path);
3129 "%s.veteran_power_fact", path);
3131 "%s.veteran_base_raise_chance", path);
3133 "%s.veteran_work_raise_chance", path);
3135 "%s.veteran_move_bonus", path);
3136
3137 return TRUE;
3138}
3139
3140/**********************************************************************/
3143static bool save_combat_bonuses(struct section_file *sfile,
3144 struct unit_type *put,
3145 char *path)
3146{
3147 int i;
3148 bool has_quiet = FALSE;
3149
3151 if (pbonus->quiet) {
3152 has_quiet = TRUE;
3153 }
3155
3156 i = 0;
3157
3160 "%s.bonuses%d.flag", path, i);
3162 "%s.bonuses%d.type", path, i);
3163 secfile_insert_int(sfile, pbonus->value,
3164 "%s.bonuses%d.value", path, i);
3165
3166 if (has_quiet) {
3167 secfile_insert_bool(sfile, pbonus->quiet,
3168 "%s.bonuses%d.quiet", path, i);
3169 }
3170
3171 i++;
3173
3174 return TRUE;
3175}
3176
3177/**********************************************************************/
3180static bool save_units_ruleset(const char *filename, const char *name)
3181{
3182 struct section_file *sfile = create_ruleset_file(name, "unit");
3183 int i;
3184 int sect_idx;
3185 bool uflags_utype = FALSE;
3186 bool uflags_uclass = FALSE;
3187
3188 if (sfile == nullptr) {
3189 return FALSE;
3190 }
3191
3192 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
3194 const char *helptxt = unit_type_flag_helptxt(i + UTYF_USER_FLAG_1);
3195 struct entry *pentry;
3196
3197 if (flagname != nullptr) {
3198 if (!uflags_utype) {
3199 comment_uflags_utype(sfile);
3201 }
3202
3204 "control.flags%d.name", i);
3206
3207 /* Save the user flag help text even when it is undefined. That makes
3208 * the formatting code happy. The resulting "" is ignored when the
3209 * ruleset is loaded. */
3210 pentry = secfile_insert_str(sfile, helptxt,
3211 "control.flags%d.helptxt", i);
3213 }
3214 }
3215
3216 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
3218 const char *helptxt = unit_class_flag_helptxt(i + UCF_USER_FLAG_1);
3219 struct entry *pentry;
3220
3221 if (flagname != nullptr) {
3222 if (!uflags_uclass) {
3223 /* TODO: Uncomment this, once there's a way to stop
3224 * the comment getting written inside preceding
3225 * utype flags table. */
3226 /* comment_uflags_uclass(sfile); */
3228 }
3229
3231 "control.class_flags%d.name", i);
3233
3234 /* Save the user flag help text even when it is undefined. That makes
3235 * the formatting code happy. The resulting "" is ignored when the
3236 * ruleset is loaded. */
3237 pentry = secfile_insert_str(sfile, helptxt,
3238 "control.class_flags%d.helptxt", i);
3240 }
3241 }
3242
3243 save_veteran_system(sfile, "veteran_system", game.veteran);
3244
3245 comment_uclasses(sfile);
3246
3247 sect_idx = 0;
3249 char path[512];
3250 const char *flag_names[UCF_COUNT];
3251 int flagi;
3252 int set_count;
3253
3254 fc_snprintf(path, sizeof(path), "unitclass_%d", sect_idx++);
3255
3256 save_name_translation(sfile, &(puc->name), path);
3257
3258 secfile_insert_int(sfile, puc->min_speed / SINGLE_MOVE,
3259 "%s.min_speed", path);
3260 secfile_insert_int(sfile, puc->hp_loss_pct, "%s.hp_loss_pct", path);
3261 if (puc->non_native_def_pct != 100) {
3262 secfile_insert_int(sfile, puc->non_native_def_pct,
3263 "%s.non_native_def_pct", path);
3264 }
3265
3266 set_count = 0;
3267 for (flagi = 0; flagi < UCF_COUNT; flagi++) {
3268 if (uclass_has_flag(puc, flagi)) {
3270 }
3271 }
3272
3273 if (set_count > 0) {
3275 "%s.flags", path);
3276 }
3277
3278 save_helptext(sfile, puc->helptext, path, "helptext");
3279
3281
3282 comment_utypes(sfile);
3283
3284 sect_idx = 0;
3286 if (!put->ruledit_disabled) {
3287 char path[512];
3288 const char *flag_names[UTYF_LAST_USER_FLAG + 1];
3289 int flagi;
3290 int set_count;
3291
3292 fc_snprintf(path, sizeof(path), "unit_%d", sect_idx++);
3293
3294 save_name_translation(sfile, &(put->name), path);
3295
3296 secfile_insert_str(sfile, uclass_rule_name(put->uclass),
3297 "%s.class", path);
3298
3299 save_reqs_vector(sfile, &(put->build_reqs), path, "reqs");
3300
3301 if (put->obsoleted_by != nullptr) {
3302 secfile_insert_str(sfile, utype_rule_name(put->obsoleted_by),
3303 "%s.obsolete_by", path);
3304 }
3305
3306 secfile_insert_str(sfile, put->graphic_str, "%s.graphic", path);
3307 if (strcmp("-", put->graphic_alt)) {
3308 secfile_insert_str(sfile, put->graphic_alt, "%s.graphic_alt", path);
3309 }
3310 if (strcmp("-", put->graphic_alt2)) {
3311 secfile_insert_str(sfile, put->graphic_alt2, "%s.graphic_alt2", path);
3312 }
3313 if (strcmp("-", put->sound_move)) {
3314 secfile_insert_str(sfile, put->sound_move, "%s.sound_move", path);
3315 }
3316 if (strcmp("-", put->sound_move_alt)) {
3317 secfile_insert_str(sfile, put->sound_move_alt, "%s.sound_move_alt", path);
3318 }
3319 if (strcmp("-", put->sound_fight)) {
3320 secfile_insert_str(sfile, put->sound_fight, "%s.sound_fight", path);
3321 }
3322 if (strcmp("-", put->sound_fight_alt)) {
3323 secfile_insert_str(sfile, put->sound_fight_alt, "%s.sound_fight_alt", path);
3324 }
3325
3326 secfile_insert_int(sfile, put->build_cost, "%s.build_cost", path);
3327 secfile_insert_int(sfile, put->pop_cost, "%s.pop_cost", path);
3328 secfile_insert_int(sfile, put->attack_strength, "%s.attack", path);
3329 secfile_insert_int(sfile, put->defense_strength, "%s.defense", path);
3330 secfile_insert_int(sfile, put->move_rate / SINGLE_MOVE, "%s.move_rate", path);
3331 secfile_insert_int(sfile, put->vision_radius_sq, "%s.vision_radius_sq", path);
3332 secfile_insert_int(sfile, put->transport_capacity, "%s.transport_cap", path);
3333
3334 save_uclass_vec(sfile, &(put->cargo), path, "cargo", FALSE);
3335 save_uclass_vec(sfile, &(put->embarks), path, "embarks", TRUE);
3336 save_uclass_vec(sfile, &(put->disembarks), path, "disembarks", TRUE);
3337
3338 if (put->vlayer != V_MAIN) {
3340 "%s.vision_layer", path);
3341 }
3342
3343 secfile_insert_int(sfile, put->hp, "%s.hitpoints", path);
3344 secfile_insert_int(sfile, put->firepower, "%s.firepower", path);
3345 secfile_insert_int(sfile, put->fuel, "%s.fuel", path);
3346 secfile_insert_int(sfile, put->happy_cost, "%s.uk_happy", path);
3347
3349 if (put->upkeep[o] != 0) {
3350 secfile_insert_int(sfile, put->upkeep[o], "%s.uk_%s",
3351 path, get_output_identifier(o));
3352 }
3354
3355 if (put->converted_to != nullptr) {
3356 secfile_insert_str(sfile, utype_rule_name(put->converted_to),
3357 "%s.convert_to", path);
3358 }
3359 if (put->convert_time != 1) {
3360 secfile_insert_int(sfile, put->convert_time, "%s.convert_time", path);
3361 }
3362
3363 save_combat_bonuses(sfile, put, path);
3364 save_uclass_vec(sfile, &(put->targets), path, "targets", TRUE);
3365
3366 if (put->veteran != nullptr) {
3367 save_veteran_system(sfile, path, put->veteran);
3368 }
3369
3370 if (put->paratroopers_range != 0) {
3371 secfile_insert_int(sfile, put->paratroopers_range,
3372 "%s.paratroopers_range", path);
3373 }
3374 if (put->bombard_rate != 0) {
3375 secfile_insert_int(sfile, put->bombard_rate,
3376 "%s.bombard_rate", path);
3377 }
3378 if (put->city_slots != 0) {
3379 secfile_insert_int(sfile, put->city_slots,
3380 "%s.city_slots", path);
3381 }
3382 if (put->city_size != 1) {
3383 secfile_insert_int(sfile, put->city_size,
3384 "%s.city_size", path);
3385 }
3386
3387 secfile_insert_str(sfile, transp_def_type_name(put->tp_defense),
3388 "%s.tp_defense", path);
3389
3390 set_count = 0;
3391 for (flagi = 0; flagi <= UTYF_LAST_USER_FLAG; flagi++) {
3392 if (utype_has_flag(put, flagi)) {
3394 }
3395 }
3396
3397 if (set_count > 0) {
3399 "%s.flags", path);
3400 }
3401
3402 set_count = 0;
3403 for (flagi = L_FIRST; flagi < L_LAST; flagi++) {
3404 if (utype_has_role(put, flagi)) {
3406 }
3407 }
3408
3409 if (set_count > 0) {
3411 "%s.roles", path);
3412 }
3413
3414 save_helptext(sfile, put->helptext, path, "helptext");
3415 }
3417
3418 return save_ruleset_file(sfile, filename);
3419}
3420
3421/**********************************************************************/
3424static bool save_script_lua(const char *filename, const char *name,
3425 const char *buffer)
3426{
3427 if (buffer != nullptr) {
3428 FILE *ffile = fc_fopen(filename, "w");
3429 int full_len = strlen(buffer);
3430 int len;
3431
3432 if (ffile != nullptr) {
3433 len = fwrite(buffer, 1, full_len, ffile);
3434
3435 if (len != full_len) {
3436 return FALSE;
3437 }
3438
3439 fclose(ffile);
3440 } else {
3441 return FALSE;
3442 }
3443 }
3444
3445 return TRUE;
3446}
3447
3448/**********************************************************************/
3451static bool save_luadata(const char *filename)
3452{
3453 if (game.server.luadata != nullptr) {
3454 return secfile_save(game.server.luadata, filename, 0, FZ_PLAIN);
3455 }
3456
3457 return TRUE;
3458}
3459
3460/**********************************************************************/
3463bool save_ruleset(const char *path, const char *name, struct rule_data *data)
3464{
3465 if (make_dir(path, DIRMODE_DEFAULT)) {
3466 bool success = TRUE;
3467 char filename[500];
3468
3469 if (success) {
3470 fc_snprintf(filename, sizeof(filename), "%s/buildings.ruleset", path);
3471 success = save_buildings_ruleset(filename, name);
3472 }
3473
3474 if (success) {
3475 fc_snprintf(filename, sizeof(filename), "%s/styles.ruleset", path);
3476 success = save_styles_ruleset(filename, name);
3477 }
3478
3479 if (success) {
3480 fc_snprintf(filename, sizeof(filename), "%s/cities.ruleset", path);
3481 success = save_cities_ruleset(filename, name);
3482 }
3483
3484 if (success) {
3485 fc_snprintf(filename, sizeof(filename), "%s/effects.ruleset", path);
3486 success = save_effects_ruleset(filename, name);
3487 }
3488
3489 if (success) {
3490 fc_snprintf(filename, sizeof(filename), "%s/game.ruleset", path);
3491 success = save_game_ruleset(filename, name);
3492 }
3493
3494 if (success) {
3495 fc_snprintf(filename, sizeof(filename), "%s/governments.ruleset", path);
3497 }
3498
3499 if (success) {
3500 fc_snprintf(filename, sizeof(filename), "%s/nations.ruleset", path);
3501 success = save_nations_ruleset(filename, name, data);
3502 }
3503
3504 if (success) {
3505 fc_snprintf(filename, sizeof(filename), "%s/techs.ruleset", path);
3506 success = save_techs_ruleset(filename, name);
3507 }
3508
3509 if (success) {
3510 fc_snprintf(filename, sizeof(filename), "%s/terrain.ruleset", path);
3511 success = save_terrain_ruleset(filename, name);
3512 }
3513
3514 if (success) {
3515 fc_snprintf(filename, sizeof(filename), "%s/units.ruleset", path);
3516 success = save_units_ruleset(filename, name);
3517 }
3518
3519 if (success) {
3520 fc_snprintf(filename,sizeof(filename), "%s/actions.ruleset",path);
3521 success = save_actions_ruleset(filename, name);
3522 }
3523
3524 if (success) {
3525 fc_snprintf(filename, sizeof(filename), "%s/script.lua", path);
3527 }
3528
3529 if (success) {
3530 fc_snprintf(filename, sizeof(filename), "%s/parser.lua", path);
3532 }
3533
3534 if (success) {
3535 fc_snprintf(filename, sizeof(filename), "%s/luadata.txt", path);
3536 success = save_luadata(filename);
3537 }
3538
3539 return success;
3540 } else {
3541 log_error(_("Failed to create directory %s"), path);
3542 return FALSE;
3543 }
3544
3545 return TRUE;
3546}
#define achievements_iterate_end
#define achievements_iterate(_ach_)
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:6465
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7175
void action_array_end(action_id *act_array, int size)
Definition actions.c:5766
bool action_is_in_use(struct action *paction)
Definition actions.c:5672
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7369
const char * action_rule_name(const struct action *action)
Definition actions.c:1216
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:7002
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:6643
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:6830
const char * action_ui_name_default(int act)
Definition actions.c:6101
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:5734
bool action_id_is_internal(action_id act)
Definition actions.c:5710
#define action_enablers_iterate_end
Definition actions.h:283
#define enabler_get_action(_enabler_)
Definition actions.h:186
#define ACTION_AUTO_MOVED_ADJ
Definition actions.h:375
#define ACTION_AUTO_POST_BRIBE_UNIT
Definition actions.h:376
#define ACTION_AUTO_UPKEEP_GOLD
Definition actions.h:373
static struct action * action_by_number(action_id act_id)
Definition actions.h:400
#define NUM_ACTIONS
Definition actions.h:63
#define ACTION_AUTO_ESCAPE_STACK
Definition actions.h:382
#define ACTION_AUTO_ESCAPE_CITY
Definition actions.h:381
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:105
#define ACTION_AUTO_POST_WIPE_UNITS
Definition actions.h:383
#define ACTION_AUTO_UPKEEP_SHIELD
Definition actions.h:374
#define action_iterate_end
Definition actions.h:218
#define MAX_NUM_ACTIONS
Definition actions.h:62
#define ACTION_AUTO_POST_BRIBE_STACK
Definition actions.h:377
#define action_enablers_iterate(_enabler_)
Definition actions.h:277
#define action_iterate(_act_)
Definition actions.h:214
#define ACTION_AUTO_UPKEEP_FOOD
Definition actions.h:372
#define ACTION_AUTO_POST_ATTACK
Definition actions.h:378
#define ACTION_NONE
Definition actions.h:59
int actres_min_range_default(enum action_result result)
Definition actres.c:376
int actres_max_range_default(enum action_result result)
Definition actres.c:466
void astr_free(struct astring *astr)
Definition astring.c:148
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
const char * get_output_identifier(Output_type_id output)
Definition city.c:619
static const struct city struct citystyle * city_styles
Definition city.c:84
#define output_type_iterate(output)
Definition city.h:842
#define output_type_iterate_end
Definition city.h:848
void comment_borders_radius_permanent(struct section_file *sfile)
Definition comments.c:815
char * uflags_building
Definition comments.c:53
void comment_uflags_utype(struct section_file *sfile)
Definition comments.c:472
void comment_world_peace_turns(struct section_file *sfile)
Definition comments.c:896
void comment_combat_rules_nuke_defender_survival(struct section_file *sfile)
Definition comments.c:779
void comment_roads(struct section_file *sfile)
Definition comments.c:408
void comment_civstyle_granary(struct section_file *sfile)
Definition comments.c:609
void comment_research_tech_leakage(struct section_file *sfile)
Definition comments.c:851
void comment_uclasses(struct section_file *sfile)
Definition comments.c:360
void comment_calendar_fragments(struct section_file *sfile)
Definition comments.c:905
void comment_actions_quiet_actions(struct section_file *sfile)
Definition comments.c:806
void comment_uflags_terrain(struct section_file *sfile)
Definition comments.c:488
void comment_combat_rules_low_fp_pearl_harbor(struct section_file *sfile)
Definition comments.c:740
void comment_citystyles(struct section_file *sfile)
Definition comments.c:424
void comment_std_tileset_compat(struct section_file *sfile)
Definition comments.c:915
void comment_govs(struct section_file *sfile)
Definition comments.c:344
void comment_research_base_tech_cost(struct section_file *sfile)
Definition comments.c:833
void comment_research_tech_cost_style(struct section_file *sfile)
Definition comments.c:824
void comment_combat_rules_only_killing_veteran(struct section_file *sfile)
Definition comments.c:690
void comment_bases(struct section_file *sfile)
Definition comments.c:400
void comment_terrains(struct section_file *sfile)
Definition comments.c:376
void comment_uflags_tech(struct section_file *sfile)
Definition comments.c:504
void comment_file_header(struct section_file *sfile)
Definition comments.c:312
void comment_effects(struct section_file *sfile)
Definition comments.c:440
void comment_actions_dc_initial_odds(struct section_file *sfile)
Definition comments.c:797
void comment_combat_rules_scaled_veterancy(struct section_file *sfile)
Definition comments.c:710
void comment_research_upkeep_style(struct section_file *sfile)
Definition comments.c:860
void comment_disasters(struct section_file *sfile)
Definition comments.c:456
void comment_clauses(struct section_file *sfile)
Definition comments.c:584
void comment_goods(struct section_file *sfile)
Definition comments.c:528
char * uflags_tech
Definition comments.c:52
void comment_civstyle_gameloss_style(struct section_file *sfile)
Definition comments.c:627
char * uflags_extra
Definition comments.c:51
void comment_civstyle_gold_upkeep_style(struct section_file *sfile)
Definition comments.c:636
void comment_extras(struct section_file *sfile)
Definition comments.c:392
void comment_combat_rules_low_fp_nonnat_bombard(struct section_file *sfile)
Definition comments.c:760
void comment_ueffs(struct section_file *sfile)
Definition comments.c:448
void comment_techs(struct section_file *sfile)
Definition comments.c:336
void comment_nations(struct section_file *sfile)
Definition comments.c:560
void comment_trade_settings(struct section_file *sfile)
Definition comments.c:520
void comment_combat_rules_low_fp_combat_bonus(struct section_file *sfile)
Definition comments.c:750
void comment_nations_ruledit(struct section_file *sfile)
Definition comments.c:601
void comment_civstyle_homeless_gold_upkeep(struct section_file *sfile)
Definition comments.c:645
void comment_nationgroups(struct section_file *sfile)
Definition comments.c:568
void comment_specialists(struct section_file *sfile)
Definition comments.c:552
void comment_musicstyles(struct section_file *sfile)
Definition comments.c:432
void comment_civstyle_airlift_always(struct section_file *sfile)
Definition comments.c:654
void comment_resources(struct section_file *sfile)
Definition comments.c:384
void comment_civstyle_ransom_gold(struct section_file *sfile)
Definition comments.c:618
void comment_tech_classes(struct section_file *sfile)
Definition comments.c:328
void comment_culture_migration_pml(struct section_file *sfile)
Definition comments.c:887
void comment_combat_rules_only_real_fight_veteran(struct section_file *sfile)
Definition comments.c:700
char * uflags_uclass
Definition comments.c:49
void comment_research_free_tech_method(struct section_file *sfile)
Definition comments.c:869
void comment_combat_rules_nuke_pop_loss(struct section_file *sfile)
Definition comments.c:770
void comment_utypes(struct section_file *sfile)
Definition comments.c:368
char * uflags_utype
Definition comments.c:48
void comment_research_min_tech_cost(struct section_file *sfile)
Definition comments.c:842
void comment_culture_history_interest(struct section_file *sfile)
Definition comments.c:878
void comment_policies(struct section_file *sfile)
Definition comments.c:352
void comment_combat_rules_low_fp_badwallattacker(struct section_file *sfile)
Definition comments.c:730
void comment_achievements(struct section_file *sfile)
Definition comments.c:464
void comment_combat_rules_damage_reduces_bombard_rate(struct section_file *sfile)
Definition comments.c:720
void comment_actions(struct section_file *sfile)
Definition comments.c:536
void comment_counters(struct section_file *sfile)
Definition comments.c:592
void comment_styles(struct section_file *sfile)
Definition comments.c:416
void comment_combat_rules_tired_attack(struct section_file *sfile)
Definition comments.c:681
void comment_uflags_building(struct section_file *sfile)
Definition comments.c:512
void comment_buildings(struct section_file *sfile)
Definition comments.c:320
void comment_enablers(struct section_file *sfile)
Definition comments.c:544
void comment_nationsets(struct section_file *sfile)
Definition comments.c:576
void comment_wonder_visibility_small_wonders(struct section_file *sfile)
Definition comments.c:663
void comment_incite_cost(struct section_file *sfile)
Definition comments.c:672
void comment_auto_attack(struct section_file *sfile)
Definition comments.c:789
char * incite_cost
Definition comments.c:76
#define counters_re_iterate_end
Definition counters.h:75
#define counters_re_iterate(pcount)
Definition counters.h:67
struct clause_info * clause_info_get(enum clause_type type)
Definition diptreaty.c:292
#define disaster_type_iterate(_p)
Definition disaster.h:82
#define disaster_type_iterate_end
Definition disaster.h:88
struct @22::@23 reqs
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1321
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1357
#define EFT_USER_EFFECT_LAST
Definition effects.h:33
const char * extra_flag_helptxt(enum extra_flag_id id)
Definition extras.c:988
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1046
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:875
const char * extra_flag_id_name_cb(enum extra_flag_id flag)
Definition extras.c:976
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1017
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:353
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define extra_type_iterate_end
Definition extras.h:321
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define extra_type_re_active_iterate_end
Definition extras.h:329
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_base_get(_e_)
Definition extras.h:190
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_re_active_iterate(_p)
Definition extras.h:325
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define MAX_NUM_USER_EXTRA_FLAGS
Definition extras.h:83
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
#define MAX_NUM_USER_BUILDING_FLAGS
Definition fc_types.h:511
@ ROCO_RAILROAD
Definition fc_types.h:960
@ ROCO_NONE
Definition fc_types.h:960
@ ROCO_RIVER
Definition fc_types.h:960
@ ROCO_ROAD
Definition fc_types.h:960
#define MAX_NUM_NATION_SETS
Definition fc_types.h:57
#define MAX_NUM_BUILDING_LIST
Definition fc_types.h:46
int action_id
Definition fc_types.h:249
#define MAX_CALENDAR_FRAGMENTS
Definition fc_types.h:62
#define MAX_NUM_NATION_GROUPS
Definition fc_types.h:58
#define MAX_NUM_UNIT_LIST
Definition fc_types.h:45
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:67
#define MAX_NUM_TECH_LIST
Definition fc_types.h:44
#define UCL_LAST
Definition fc_types.h:275
const char * skip_intl_qualifier_prefix(const char *str)
Definition fcintl.c:48
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
#define RS_DEFAULT_RANSOM_GOLD
Definition game.h:874
#define RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:866
#define RS_DEFAULT_NUKE_POP_LOSS_PCT
Definition game.h:863
#define RS_DEFAULT_BASE_POLLUTION
Definition game.h:849
#define RS_DEFAULT_INCITE_TOTAL_FCT
Definition game.h:822
#define RS_DEFAULT_ILLNESS_BASE_FACTOR
Definition game.h:780
#define RS_DEFAULT_NEG_YEAR_LABEL
Definition game.h:776
#define RS_DEFAULT_INCITE_IMPROVEMENT_FCT
Definition game.h:814
#define RS_ACTION_NO_MAX_DISTANCE
Definition game.h:902
#define RS_DEFAULT_BASE_BRIBE_COST
Definition game.h:870
#define RS_DEFAULT_TECH_UPKEEP_DIVIDER
Definition game.h:884
#define RS_DEFAULT_HAPPY_COST
Definition game.h:854
#define RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
Definition game.h:892
#define RS_DEFAULT_GRANARY_FOOD_INC
Definition game.h:828
#define RS_DEFAULT_ILLNESS_ON
Definition game.h:778
#define GAME_DEFAULT_CELEBRATESIZE
Definition game.h:507
#define RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
Definition game.h:893
#define RS_DEFAULT_UPGRADE_VETERAN_LOSS
Definition game.h:880
#define RS_DEFAULT_CALENDAR_SKIP_0
Definition game.h:796
#define RS_DEFAULT_CITY_RADIUS_SQ
Definition game.h:841
#define GAME_DEFAULT_START_YEAR
Definition game.h:748
#define RS_DEFAULT_BORDER_SIZE_EFFECT
Definition game.h:802
#define RS_DEFAULT_PILLAGE_SELECT
Definition game.h:878
#define RS_DEFAULT_POS_YEAR_LABEL
Definition game.h:774
#define RS_DEFAULT_VIS_RADIUS_SQ
Definition game.h:845
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:806
#define RS_DEFAULT_TIRED_ATTACK
Definition game.h:862
#define RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
Definition game.h:894
#define RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:788
#define RS_DEFAULT_FOOD_COST
Definition game.h:858
#define RS_DEFAULT_INCITE_UNIT_FCT
Definition game.h:818
#define RS_DEFAULT_INCITE_BASE_COST
Definition game.h:810
#define GAME_DEFAULT_ANGRYCITIZEN
Definition game.h:398
#define RS_DEFAULT_CITY_CENTER_OUTPUT
Definition game.h:832
#define RS_DEFAULT_ILLNESS_POLLUTION_PCT
Definition game.h:792
#define RS_DEFAULT_ILLNESS_MIN_SIZE
Definition game.h:784
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY
Definition game.h:798
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:397
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:388
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
#define governments_iterate(NAME_pgov)
Definition government.h:124
#define governments_re_active_iterate(_p)
Definition government.h:129
#define governments_re_active_iterate_end
Definition government.h:133
#define governments_iterate_end
Definition government.h:127
const char * title
Definition repodlgs.c:1314
struct impr_type * improvement_by_number(const Impr_type_id id)
const char * impr_flag_id_name_cb(enum impr_flag_id flag)
const char * improvement_rule_name(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * impr_flag_helptxt(enum impr_flag_id id)
#define improvement_re_active_iterate_end
#define improvement_re_active_iterate(_p)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
@ FZ_PLAIN
Definition ioz.h:38
#define fc_assert(condition)
Definition log.h:177
#define log_error(message,...)
Definition log.h:104
struct terrain_misc terrain_control
Definition map.c:68
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
#define SINGLE_MOVE
Definition movement.h:26
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
#define multipliers_iterate_end
Definition multipliers.h:67
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * untranslated_name(const struct name_translation *ptrans)
const char * nation_city_name(const struct nation_city *pncity)
Definition nation.c:412
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
bool nation_leader_is_male(const struct nation_leader *pleader)
Definition nation.c:290
enum nation_city_preference nation_city_terrain_preference(const struct nation_city *pncity, const struct terrain *pterrain)
Definition nation.c:422
const char * nation_group_rule_name(const struct nation_group *pgroup)
Definition nation.c:1079
const char * nation_set_untranslated_name(const struct nation_set *pset)
Definition nation.c:797
bool nation_is_in_group(const struct nation_type *pnation, const struct nation_group *pgroup)
Definition nation.c:1099
bool nation_is_in_set(const struct nation_type *pnation, const struct nation_set *pset)
Definition nation.c:837
const char * nation_set_description(const struct nation_set *pset)
Definition nation.c:828
enum nation_city_preference nation_city_river_preference(const struct nation_city *pncity)
Definition nation.c:434
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:121
const char * nation_leader_name(const struct nation_leader *pleader)
Definition nation.c:281
const char * nation_set_rule_name(const struct nation_set *pset)
Definition nation.c:807
#define nation_leader_list_iterate(leaderlist, pleader)
Definition nation.h:57
#define nation_list_iterate(nationlist, pnation)
Definition nation.h:84
#define nation_sets_iterate_end
Definition nation.h:305
#define nation_sets_iterate(NAME_pset)
Definition nation.h:301
#define nations_iterate_end
Definition nation.h:336
@ NCP_NONE
Definition nation.h:41
@ NCP_DISLIKE
Definition nation.h:40
@ NCP_LIKE
Definition nation.h:42
#define nation_city_list_iterate(citylist, pncity)
Definition nation.h:48
#define nation_list_iterate_end
Definition nation.h:86
#define nation_city_list_iterate_end
Definition nation.h:50
#define nations_iterate(NAME_pnation)
Definition nation.h:333
#define nation_leader_list_iterate_end
Definition nation.h:59
#define nation_groups_iterate(NAME_pgroup)
Definition nation.h:311
#define nation_groups_iterate_end
Definition nation.h:315
int len
Definition packhand.c:127
struct section_file * secfile_new(bool allow_duplicates)
bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking)
bool secfile_save(const struct section_file *secfile, const char *filename, int compression_level, enum fz_method compression_method)
struct section * secfile_insert_include(struct section_file *secfile, const char *filename)
struct entry * secfile_insert_filereference(struct section_file *secfile, const char *filename, const char *path,...)
#define secfile_insert_int(secfile, value, path,...)
#define secfile_insert_enum_vec(secfile, enumerators, dim, specenum_type, path,...)
#define secfile_insert_enum(secfile, enumerator, specenum_type, path,...)
#define secfile_insert_int_vec(secfile, values, dim, path,...)
#define secfile_insert_str_vec(secfile, strings, dim, path,...)
#define secfile_insert_str(secfile, string, path,...)
#define secfile_insert_bool(secfile, value, path,...)
#define secfile_insert_str_vec_gt_marking(secfile, strings, dim, path,...)
#define secfile_insert_enum_vec_comment(secfile, enumerators, dim, specenum_type, comment, path,...)
#define secfile_insert_enum_data(secfile, value, bitwise, name_fn, data, path,...)
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
const char * universal_rule_name(const struct universal *psource)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
void rgbcolor_save(struct section_file *file, const struct rgbcolor *prgbcolor, char *path,...)
Definition rgbcolor.c:121
#define rgbcolor_list_iterate_end
Definition rgbcolor.h:45
#define rgbcolor_list_iterate(rgbcolorlist, prgbcolor)
Definition rgbcolor.h:43
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:416
char * get_parser_buffer(void)
Definition ruleload.c:568
char * get_script_buffer(void)
Definition ruleload.c:560
#define RS_DEFAULT_CONVERT_SPEED
Definition ruleload.h:123
#define RS_DEFAULT_UBUILD_NAT
Definition ruleload.h:122
#define RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
Definition ruleload.h:109
#define RS_DEFAULT_WORLD_PEACE_TURNS
Definition ruleload.h:99
#define RS_DEFAULT_TECH_TRADE_LOSS_HOLES
Definition ruleload.h:84
#define RS_DEFAULT_EXTRA_APPEARANCE
Definition ruleload.h:103
#define RS_DEFAULT_TECH_PARASITE_HOLES
Definition ruleload.h:85
#define GAME_DEFAULT_ACH_VALUE
Definition ruleload.h:78
#define RS_DEFAULT_TECH_TRADE_HOLES
Definition ruleload.h:83
#define RS_DEFAULT_CULTURE_VIC_POINTS
Definition ruleload.h:94
#define RS_DEFAULT_CULTURE_MIGRATION_PML
Definition ruleload.h:96
#define RS_DEFAULT_SMALL_WONDER_VISIBILITY
Definition ruleload.h:111
#define RS_DEFAULT_ONLY_KILLING_VETERAN
Definition ruleload.h:106
#define RS_DEFAULT_TECH_LOSS_HOLES
Definition ruleload.h:86
#define RS_DEFAULT_HISTORY_INTEREST_PML
Definition ruleload.h:97
#define RS_DEFAULT_GOODS_SELECTION
Definition ruleload.h:101
#define RS_DEFAULT_PYTHAGOREAN_DIAGONAL
Definition ruleload.h:87
#define RS_DEFAULT_TECH_STEAL_HOLES
Definition ruleload.h:82
#define GAME_DEFAULT_ACH_UNIQUE
Definition ruleload.h:77
#define RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
Definition ruleload.h:108
#define RS_DEFAULT_MUUK_FOOD_WIPE
Definition ruleload.h:79
#define RS_DEFAULT_MUUK_GOLD_WIPE
Definition ruleload.h:80
#define RS_DEFAULT_BASE_TECH_COST
Definition ruleload.h:113
#define RULESET_CAPABILITIES
Definition ruleload.h:24
#define RS_DEFAULT_NATIONALITY
Definition ruleload.h:121
#define GAME_DEFAULT_CHANGABLE_TAX
Definition ruleload.h:74
#define RS_DEFAULT_MUUK_SHIELD_WIPE
Definition ruleload.h:81
#define RS_DEFAULT_GOLD_UPKEEP_STYLE
Definition ruleload.h:89
#define GAME_DEFAULT_ADDTOSIZE
Definition ruleload.h:73
#define RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
Definition ruleload.h:107
#define RS_DEFAULT_EXTRA_DISAPPEARANCE
Definition ruleload.h:104
#define RS_DEFAULT_MIN_TECH_COST
Definition ruleload.h:117
#define GAME_DEFAULT_VISION_REVEAL_TILES
Definition ruleload.h:75
#define RS_DEFAULT_CULTURE_VIC_LEAD
Definition ruleload.h:95
#define GAME_DEFAULT_DISASTER_FREQ
Definition ruleload.h:76
static bool save_reqs_vector(struct section_file *sfile, const struct requirement_vector *reqs, const char *path, const char *entry)
Definition rulesave.c:150
static bool save_tech_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:210
static bool save_name_translation(struct section_file *sfile, struct name_translation *name, const char *path)
Definition rulesave.c:127
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:250
static bool save_unit_list(struct section_file *sfile, struct unit_type **input, const char *path, const char *entry)
Definition rulesave.c:307
static bool save_nations_ruleset(const char *filename, const char *name, struct rule_data *data)
Definition rulesave.c:2244
static bool save_action_kind(struct section_file *sfile, action_id act)
Definition rulesave.c:921
static bool save_action_actor_consuming_always(struct section_file *sfile, action_id act)
Definition rulesave.c:945
static bool save_action_max_range(struct section_file *sfile, action_id act)
Definition rulesave.c:875
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:2010
#define FORMAT_VERSION
Definition rulesave.c:56
bool save_ruleset(const char *path, const char *name, struct rule_data *data)
Definition rulesave.c:3463
static bool save_cities_ruleset(const char *filename, const char *name)
Definition rulesave.c:672
static bool save_techs_ruleset(const char *filename, const char *name)
Definition rulesave.c:2369
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:330
static bool save_action_post_success_force(struct section_file *sfile, int performer_slot, struct action *paction)
Definition rulesave.c:1023
static bool save_ruleset_file(struct section_file *sfile, const char *filename)
Definition rulesave.c:380
static bool save_veteran_system(struct section_file *sfile, const char *path, struct veteran_system *vsystem)
Definition rulesave.c:3108
static bool save_bv_actions(struct section_file *sfile, bv_actions content, const char *path)
Definition rulesave.c:1052
static bool save_default_bool(struct section_file *sfile, bool value, bool default_value, const char *path, const char *entry)
Definition rulesave.c:106
static bool effect_save(struct effect *peffect, void *data)
Definition rulesave.c:801
static bool save_game_ruleset(const char *filename, const char *name)
Definition rulesave.c:1264
static bool save_buildings_ruleset(const char *filename, const char *name)
Definition rulesave.c:388
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:548
static bool unexpected_non_otype(const struct requirement *req)
Definition rulesave.c:642
static bool save_building_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:283
static bool save_luadata(const char *filename)
Definition rulesave.c:3451
static bool save_governments_ruleset(const char *filename, const char *name)
Definition rulesave.c:1919
static bool save_action_blocked_by(struct section_file *sfile, struct action *paction)
Definition rulesave.c:970
static bool save_actions_ruleset(const char *filename, const char *name)
Definition rulesave.c:1085
static bool save_units_ruleset(const char *filename, const char *name)
Definition rulesave.c:3180
static bool save_terrain_ruleset(const char *filename, const char *name)
Definition rulesave.c:2483
static bool save_muuk_action_auto(struct section_file *sfile, const int aap, const char *item)
Definition rulesave.c:652
static bool save_action_range(struct section_file *sfile, action_id act)
Definition rulesave.c:895
static bool save_gov_ref(struct section_file *sfile, const struct government *gov, const char *path, const char *entry)
Definition rulesave.c:270
static bool save_styles_ruleset(const char *filename, const char *name)
Definition rulesave.c:484
static struct section_file * create_ruleset_file(const char *rsname, const char *rstype)
Definition rulesave.c:61
static bool save_combat_bonuses(struct section_file *sfile, struct unit_type *put, char *path)
Definition rulesave.c:3143
static bool save_effects_ruleset(const char *filename, const char *name)
Definition rulesave.c:831
static bool save_default_int(struct section_file *sfile, int value, int default_value, const char *path, const char *entry)
Definition rulesave.c:86
static bool save_helptext(struct section_file *sfile, struct strvec *to_save, const char *path, const char *entry)
Definition rulesave.c:357
static bool save_nation(struct section_file *sfile, struct nation_type *pnat, int sect_idx)
Definition rulesave.c:2056
static bool save_script_lua(const char *filename, const char *name, const char *buffer)
Definition rulesave.c:3424
static bool save_action_auto_actions(struct section_file *sfile, const int aap, const char *actions_path)
Definition rulesave.c:599
static bool save_tech_ref(struct section_file *sfile, const struct advance *padv, const char *path, const char *entry)
Definition rulesave.c:233
bool setting_ruleset_locked(const struct setting *pset)
Definition settings.c:4648
int setting_int_get(struct setting *pset)
Definition settings.c:3788
enum sset_type setting_type(const struct setting *pset)
Definition settings.c:3362
const char * setting_enum_secfile_str(secfile_data_t data, int val)
Definition settings.c:3870
enum setting_default_level setting_get_setdef(const struct setting *pset)
Definition settings.c:5603
const char * setting_name(const struct setting *pset)
Definition settings.c:3333
int setting_bitwise_get(struct setting *pset)
Definition settings.c:4257
char * setting_str_get(struct setting *pset)
Definition settings.c:3859
bool setting_bool_get(struct setting *pset)
Definition settings.c:3676
const char * setting_bitwise_secfile_str(secfile_data_t data, int bit)
Definition settings.c:4065
int read_enum_value(const struct setting *pset)
Definition settings.c:3995
#define settings_iterate(_level, _pset)
Definition settings.h:188
#define settings_iterate_end
Definition settings.h:194
const char * sex_rule_name(sex_t kind)
Definition sex.c:43
@ SEX_FEMALE
Definition sex.h:22
@ SEX_MALE
Definition sex.h:23
bool make_dir(const char *pathname, int mode)
Definition shared.c:1779
#define DIRMODE_DEFAULT
Definition shared.h:258
#define MAX(x, y)
Definition shared.h:54
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:100
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
const char * strvec_get(const struct strvec *psv, size_t svindex)
size_t strvec_size(const struct strvec *psv)
bool actor_consuming_always
Definition actions.h:144
int max_distance
Definition actions.h:127
bool quiet
Definition actions.h:134
char ui_name[MAX_LEN_NAME]
Definition actions.h:130
enum action_target_kind target_kind
Definition actions.h:118
int named_teams
Definition game.h:301
size_t as_count
Definition game.h:300
struct civ_game::@32::@36::@42 ruledit
struct rgbcolor_list * plr_colors
Definition game.h:252
const char ** allowed_govs
Definition game.h:292
int upgrade_veteran_loss
Definition game.h:206
struct rgbcolor * plr_bg_color
Definition game.h:103
int incite_total_factor
Definition game.h:157
int init_vis_radius_sq
Definition game.h:159
bool vision_reveal_tiles
Definition game.h:207
char * description_file
Definition game.h:288
struct packet_ruleset_control control
Definition game.h:83
char * ruleset_summary
Definition game.h:84
int base_incite_cost
Definition game.h:141
int global_init_techs[MAX_NUM_TECH_LIST]
Definition game.h:110
struct packet_game_info info
Definition game.h:89
int autoupgrade_veteran_loss
Definition game.h:139
int start_year
Definition game.h:198
int incite_improvement_factor
Definition game.h:156
struct section_file * luadata
Definition game.h:254
char ** embedded_nations
Definition game.h:290
int global_init_buildings[MAX_NUM_BUILDING_LIST]
Definition game.h:111
struct trait_limits default_traits[TRAIT_COUNT]
Definition game.h:281
const char ** allowed_terrains
Definition game.h:295
char * ruleset_description
Definition game.h:85
size_t ag_count
Definition game.h:294
const char ** allowed_styles
Definition game.h:298
bool std_tileset_compat
Definition game.h:302
struct civ_game::@31 rgame
size_t embedded_nations_count
Definition game.h:291
int incite_unit_factor
Definition game.h:158
char * ruleset_capabilities
Definition game.h:86
int ransom_gold
Definition game.h:182
struct civ_game::@32::@36 server
size_t at_count
Definition game.h:297
struct veteran_system * veteran
Definition game.h:101
struct packet_calendar_info calendar
Definition game.h:90
struct government * default_government
Definition game.h:93
struct government * government_during_revolution
Definition game.h:94
struct civ_map::@44::@46 server
bool ocean_resources
Definition map_types.h:119
struct requirement_vector receiver_reqs
Definition diptreaty.h:61
struct requirement_vector giver_reqs
Definition diptreaty.h:60
enum clause_type type
Definition diptreaty.h:58
struct requirement_vector either_reqs
Definition diptreaty.h:62
bool enabled
Definition diptreaty.h:59
struct section_file * sfile
Definition rulesave.c:795
Definition climisc.h:82
char positive_year_label[MAX_LEN_NAME]
char negative_year_label[MAX_LEN_NAME]
char calendar_fragment_name[MAX_CALENDAR_FRAGMENTS][MAX_LEN_NAME]
bool tech_steal_allow_holes
enum gameloss_style gameloss_style
enum goods_selection_method goods_selection
enum gold_upkeep_style gold_upkeep_style
int low_firepower_pearl_harbor
bool damage_reduces_bombard_rate
int nuke_defender_survival_chance_pct
enum tech_upkeep_style tech_upkeep_style
bool tech_trade_loss_allow_holes
int granary_food_ini[MAX_GRANARY_INIS]
enum free_tech_method free_tech_method
bool steal_maps_reveals_all_cities
bool only_real_fight_makes_veteran
enum tech_leakage_style tech_leakage
bool airlift_from_always_enabled
bool only_killing_makes_veteran
bool poison_empties_food_stock
bv_actions diplchance_initial_odds
bool tech_trade_allow_holes
int low_firepower_nonnat_bombard
bool tech_parasite_allow_holes
int low_firepower_combat_bonus
int border_city_permanent_radius_sq
int low_firepower_badwallattacker
bool airlift_to_always_enabled
enum wonder_visib_type small_wonder_visibility
enum tech_cost_style tech_cost_style
bool combat_odds_scaled_veterancy
bool unit_builders_nationality
int min_city_center_output[O_LAST]
char preferred_soundset[MAX_LEN_NAME]
char version[MAX_LEN_NAME]
char preferred_tileset[MAX_LEN_NAME]
char alt_dir[MAX_LEN_NAME]
char preferred_musicset[MAX_LEN_NAME]
char name[MAX_LEN_NAME]
struct universal source
char * nationlist
Definition rulesave.h:22
struct requirement_vector reqs
Definition specialist.h:38
char graphic_alt[MAX_LEN_NAME]
Definition specialist.h:36
struct strvec * helptext
Definition specialist.h:40
char graphic_str[MAX_LEN_NAME]
Definition specialist.h:35
struct name_translation name
Definition specialist.h:31
struct name_translation abbreviation
Definition specialist.h:32
enum trade_route_bonus_type bonus_type
Definition traderoutes.h:78
enum trade_route_illegal_cancelling cancelling
Definition traderoutes.h:77
enum universals_n kind
Definition fc_types.h:609
struct civ_map map
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:108
#define music_styles_iterate(_p)
Definition style.h:72
#define music_styles_iterate_end
Definition style.h:79
#define styles_re_active_iterate_end
Definition style.h:60
#define styles_re_active_iterate(_p)
Definition style.h:56
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
FILE * fc_fopen(const char *filename, const char *opentype)
Definition support.c:505
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:175
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:233
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
const char * tech_flag_id_name_cb(enum tech_flag_id flag)
Definition tech.c:433
const char * tech_class_rule_name(const struct tech_class *ptclass)
Definition tech.c:352
bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag)
Definition tech.c:216
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:309
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
const char * tech_flag_helptxt(enum tech_flag_id id)
Definition tech.c:445
#define advance_re_active_iterate(_p)
Definition tech.h:277
#define A_NEVER
Definition tech.h:51
#define tech_class_iterate_end
Definition tech.h:199
#define MAX_NUM_USER_TECH_FLAGS
Definition tech.h:103
@ AR_TWO
Definition tech.h:107
@ AR_ROOT
Definition tech.h:108
@ AR_ONE
Definition tech.h:106
#define advance_re_active_iterate_end
Definition tech.h:281
#define A_NONE
Definition tech.h:43
#define tech_class_iterate(_p)
Definition tech.h:193
#define A_LAST
Definition tech.h:45
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:816
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:246
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Definition terrain.c:828
#define terrain_type_iterate(_p)
Definition terrain.h:267
#define terrain_animals_iterate(pterrain, _animal)
Definition terrain.h:299
#define terrain_type_iterate_end
Definition terrain.h:273
#define MAX_NUM_TERRAINS
Definition terrain.h:69
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
#define MAX_NUM_USER_TER_FLAGS
Definition terrain.h:32
#define terrain_resources_iterate_end
Definition terrain.h:295
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:286
#define terrain_animals_iterate_end
Definition terrain.h:307
#define RESOURCE_FREQUENCY_DEFAULT
Definition terrain.h:101
bool goods_has_flag(const struct goods_type *pgood, enum goods_flag_id flag)
const char * trade_route_type_name(enum trade_route_type type)
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
const char * trade_route_cancelling_type_name(enum trade_route_illegal_cancelling type)
#define goods_type_re_active_iterate_end
#define goods_type_re_active_iterate(_p)
trade_route_type
Definition traderoutes.h:37
@ TRT_LAST
Definition traderoutes.h:48
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1858
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:203
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1582
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1645
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1846
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1909
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1921
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:771
#define unit_type_re_active_iterate(_p)
Definition unittype.h:872
#define combat_bonus_list_iterate_end
Definition unittype.h:487
#define L_FIRST
Definition unittype.h:354
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:485
#define unit_class_iterate(_p)
Definition unittype.h:913
#define unit_class_re_active_iterate_end
Definition unittype.h:929
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:336
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:622
#define UTYF_LAST_USER_FLAG
Definition unittype.h:335
#define L_LAST
Definition unittype.h:444
#define unit_class_re_active_iterate(_p)
Definition unittype.h:925
#define uclass_index(_c_)
Definition unittype.h:747
#define unit_class_iterate_end
Definition unittype.h:920
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:128
#define unit_type_re_active_iterate_end
Definition unittype.h:876
const char * freeciv_datafile_version(void)
Definition version.c:186