Freeciv-3.4
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 "accessarea.h"
25#include "achievements.h"
26#include "counters.h"
27#include "game.h"
28#include "government.h"
29#include "map.h"
30#include "movement.h"
31#include "multipliers.h"
32#include "nation.h"
33#include "rgbcolor.h"
34#include "sex.h"
35#include "specialist.h"
36#include "style.h"
37#include "tiledef.h"
38#include "unittype.h"
39#include "version.h"
40
41/* server */
42#include "ruleload.h"
43#include "settings.h"
44
45/* tools/ruleutil */
46#include "comments.h"
47
48#include "rulesave.h"
49
50/* Ruleset format version */
51/*
52 * 1 - Freeciv-2.6
53 * 10 - Freeciv-3.0
54 * 20 - Freeciv-3.1
55 * 30 - Freeciv-3.2
56 * 40 - Freeciv-3.3
57 */
58#define FORMAT_VERSION RSFORMAT_CURRENT
59
60/**********************************************************************/
63static struct section_file *create_ruleset_file(const char *rsname,
64 const char *rstype)
65{
66 struct section_file *sfile = secfile_new(TRUE);
67 char buf[500];
68
70
71 if (rsname != nullptr && rsname[0] != '\0') {
72 fc_snprintf(buf, sizeof(buf), "%s %s data for Freeciv", rsname, rstype);
73 } else {
74 fc_snprintf(buf, sizeof(buf), "Template %s data for Freeciv", rstype);
75 }
76
77 secfile_insert_str(sfile, buf, "datafile.description");
78 secfile_insert_str(sfile, freeciv_datafile_version(), "datafile.ruledit");
79 secfile_insert_str(sfile, RULESET_CAPABILITIES, "datafile.options");
80 secfile_insert_int(sfile, FORMAT_VERSION, "datafile.format_version");
81
82 return sfile;
83}
84
85/**********************************************************************/
88static bool save_default_int(struct section_file *sfile, int value,
89 int default_value, const char *path,
90 const char *entry)
91{
92 if (value != default_value) {
93 if (entry != nullptr) {
94 secfile_insert_int(sfile, value,
95 "%s.%s", path, entry);
96 } else {
97 secfile_insert_int(sfile, value,
98 "%s", path);
99 }
100 }
101
102 return TRUE;
103}
104
105/**********************************************************************/
108static bool save_default_bool(struct section_file *sfile, bool value,
109 bool default_value, const char *path,
110 const char *entry)
111{
112 if ((value && !default_value)
113 || (!value && default_value)) {
114 if (entry != nullptr) {
115 secfile_insert_bool(sfile, value,
116 "%s.%s", path, entry);
117 } else {
118 secfile_insert_bool(sfile, value,
119 "%s", path);
120 }
121 }
122
123 return TRUE;
124}
125
126/**********************************************************************/
129static bool save_name_translation(struct section_file *sfile,
130 struct name_translation *name,
131 const char *path)
132{
133 struct entry *mod_entry;
134
137 "%s.name", path);
141 secfile_insert_str(sfile,
143 "%s.rule_name", path);
144 }
145
146 return TRUE;
147}
148
149/**********************************************************************/
152static bool save_reqs_vector(struct section_file *sfile,
153 const struct requirement_vector *reqs,
154 const char *path, const char *entry)
155{
156 int i;
157 bool includes_negated = FALSE;
159 bool includes_quiet = FALSE;
160
162 if (!preq->present) {
164 }
165 if (preq->survives) {
167 }
168 if (preq->quiet) {
170 }
172
173 i = 0;
175 secfile_insert_str(sfile,
176 universals_n_name(preq->source.kind),
177 "%s.%s%d.type", path, entry, i);
178 secfile_insert_str(sfile,
179 universal_rule_name(&(preq->source)),
180 "%s.%s%d.name", path, entry, i);
181 secfile_insert_str(sfile,
182 req_range_name(preq->range),
183 "%s.%s%d.range", path, entry, i);
184
185 if (includes_surviving) {
187 preq->survives,
188 "%s.%s%d.survives", path, entry, i);
189 }
190
191 if (includes_negated) {
193 preq->present,
194 "%s.%s%d.present", path, entry, i);
195 }
196
197 if (includes_quiet) {
199 preq->quiet,
200 "%s.%s%d.quiet", path, entry, i);
201 }
202
203 i++;
205
206 return TRUE;
207}
208
209/**********************************************************************/
212static bool save_tech_list(struct section_file *sfile, int *input,
213 const char *path, const char *entry)
214{
215 const char *tech_names[MAX_NUM_TECH_LIST];
216 int set_count;
217 int i;
218
219 set_count = 0;
220 for (i = 0; input[i] != A_LAST && i < MAX_NUM_TECH_LIST; i++) {
222 }
223
224 if (set_count > 0) {
226 "%s.%s", path, entry);
227 }
228
229 return TRUE;
230}
231
232/**********************************************************************/
235static bool save_tech_ref(struct section_file *sfile,
236 const struct advance *padv,
237 const char *path, const char *entry)
238{
239 if (padv == A_NEVER) {
240 secfile_insert_str(sfile, "Never", "%s.%s", path, entry);
241 } else {
243 "%s.%s", path, entry);
244 }
245
246 return TRUE;
247}
248
249/**********************************************************************/
252static bool save_terrain_ref(struct section_file *sfile,
253 const struct terrain *save,
254 const struct terrain *pthis,
255 const char *path, const char *entry)
256{
257 if (save == nullptr) {
258 secfile_insert_str(sfile, "none", "%s.%s", path, entry);
259 } else if (save == pthis) {
260 secfile_insert_str(sfile, "yes", "%s.%s", path, entry);
261 } else {
263 "%s.%s", path, entry);
264 }
265
266 return TRUE;
267}
268
269/**********************************************************************/
272static bool save_gov_ref(struct section_file *sfile,
273 const struct government *gov,
274 const char *path, const char *entry)
275{
276 secfile_insert_str(sfile, government_rule_name(gov), "%s.%s", path, entry);
277
278 return TRUE;
279}
280
281/**********************************************************************/
285static bool save_building_list(struct section_file *sfile, int *input,
286 const char *path, const char *entry)
287{
289 int set_count;
290 int i;
291
292 set_count = 0;
293 for (i = 0; input[i] != B_LAST && i < MAX_NUM_BUILDING_LIST; i++) {
295 }
296
297 if (set_count > 0) {
299 "%s.%s", path, entry);
300 }
301
302 return TRUE;
303}
304
305/**********************************************************************/
309static bool save_unit_list(struct section_file *sfile, struct unit_type **input,
310 const char *path, const char *entry)
311{
312 const char *unit_names[MAX_NUM_UNIT_LIST];
313 int set_count;
314 int i;
315
316 set_count = 0;
317 for (i = 0; input[i] != nullptr && i < MAX_NUM_UNIT_LIST; i++) {
319 }
320
321 if (set_count > 0) {
323 "%s.%s", path, entry);
324 }
325
326 return TRUE;
327}
328
329/**********************************************************************/
332static bool save_uclass_vec(struct section_file *sfile,
333 bv_unit_classes *bits,
334 const char *path, const char *entry,
335 bool unreachable_only)
336{
337 const char *class_names[UCL_LAST];
338 int classes = 0;
339
341 if (BV_ISSET(*(bits), uclass_index(pcargo))
343 || !unreachable_only)) {
345 }
347
348 if (classes > 0) {
350 "%s.%s", path, entry);
351 }
352
353 return TRUE;
354}
355
356/**********************************************************************/
359static bool save_helptext(struct section_file *sfile,
360 struct strvec *to_save,
361 const char *path, const char *entry)
362{
363 if (to_save != nullptr) {
365 const char *sections[sect_count];
366 int i;
367
368 for (i = 0; i < sect_count; i++) {
369 sections[i] = strvec_get(to_save, i);
370 }
371
373 "%s.%s", path, entry);
374 }
375
376 return TRUE;
377}
378
379/**********************************************************************/
382static bool save_ruleset_file(struct section_file *sfile, const char *filename)
383{
384 return secfile_save(sfile, filename, 0, FZ_PLAIN, TRUE);
385}
386
387/**********************************************************************/
390static bool save_buildings_ruleset(const char *filename, const char *name)
391{
392 struct section_file *sfile = create_ruleset_file(name, "building");
393 int sect_idx;
394 int i;
395 bool uflags_building = FALSE;
396
397 if (sfile == nullptr) {
398 return FALSE;
399 }
400
401 for (i = 0; i < MAX_NUM_USER_BUILDING_FLAGS; i++) {
403 const char *helptxt = impr_flag_helptxt(i + IF_USER_FLAG_1);
404
405 if (flagname != nullptr) {
406 if (!uflags_building) {
409 }
410
411 secfile_insert_str(sfile, flagname, "control.building_flags%d.name", i);
412
413 /* Save the user flag help text even when it is undefined. That makes
414 * the formatting code happy. The resulting "" is ignored when the
415 * ruleset is loaded. */
416 secfile_insert_str(sfile, helptxt,
417 "control.building_flags%d.helptxt", i);
418 }
419 }
420
421 comment_buildings(sfile);
422
423 sect_idx = 0;
425 if (!pb->ruledit_disabled) {
426 char path[512];
427 const char *flag_names[IF_COUNT];
428 int set_count;
429 int flagi;
430
431 fc_snprintf(path, sizeof(path), "building_%d", sect_idx++);
432
433 save_name_translation(sfile, &(pb->name), path);
434
436 "%s.genus", path);
437
438 if (strcmp(pb->graphic_str, "-")) {
439 secfile_insert_str(sfile, pb->graphic_str, "%s.graphic", path);
440 }
441 if (strcmp(pb->graphic_alt, "-")) {
442 secfile_insert_str(sfile, pb->graphic_alt, "%s.graphic_alt", path);
443 }
444 if (strcmp(pb->graphic_alt2, "-")) {
445 secfile_insert_str(sfile, pb->graphic_alt2, "%s.graphic_alt2", path);
446 }
447 if (strcmp(pb->soundtag, "-")) {
448 secfile_insert_str(sfile, pb->soundtag, "%s.sound", path);
449 }
450 if (strcmp(pb->soundtag_alt, "-")) {
451 secfile_insert_str(sfile, pb->soundtag_alt, "%s.sound_alt", path);
452 }
453 if (strcmp(pb->soundtag_alt2, "-")) {
454 secfile_insert_str(sfile, pb->soundtag_alt2, "%s.sound_alt2", path);
455 }
456
457 save_reqs_vector(sfile, &(pb->reqs), path, "reqs");
458 save_reqs_vector(sfile, &(pb->obsolete_by), path, "obsolete_by");
459
460 secfile_insert_int(sfile, pb->build_cost, "%s.build_cost", path);
461 secfile_insert_int(sfile, pb->upkeep, "%s.upkeep", path);
462 secfile_insert_int(sfile, pb->sabotage, "%s.sabotage", path);
463
464 set_count = 0;
465 for (flagi = 0; flagi < IF_COUNT; flagi++) {
468 }
469 }
470
471 if (set_count > 0) {
473 "%s.flags", path);
474 }
475
476 save_helptext(sfile, pb->helptext, path, "helptext");
477 }
479
480 return save_ruleset_file(sfile, filename);
481}
482
483/**********************************************************************/
486static bool save_styles_ruleset(const char *filename, const char *name)
487{
488 struct section_file *sfile = create_ruleset_file(name, "styles");
489 int sect_idx;
490 int i;
491
492 if (sfile == nullptr) {
493 return FALSE;
494 }
495
496 comment_styles(sfile);
497
498 sect_idx = 0;
500 char path[512];
501
502 fc_snprintf(path, sizeof(path), "style_%d", sect_idx++);
503
504 save_name_translation(sfile, &(pstyle->name), path);
506
507 comment_citystyles(sfile);
508
509 sect_idx = 0;
510 for (i = 0; i < game.control.num_city_styles; i++) {
511 char path[512];
512
513 fc_snprintf(path, sizeof(path), "citystyle_%d", sect_idx++);
514
515 save_name_translation(sfile, &(city_styles[i].name), path);
516
517 secfile_insert_str(sfile, city_styles[i].graphic, "%s.graphic", path);
518 secfile_insert_str(sfile, city_styles[i].graphic_alt, "%s.graphic_alt", path);
519 if (strcmp(city_styles[i].citizens_graphic, "-")) {
520 secfile_insert_str(sfile, city_styles[i].citizens_graphic,
521 "%s.citizens_graphic", path);
522 }
523
524 save_reqs_vector(sfile, &(city_styles[i].reqs), path, "reqs");
525 }
526
527 comment_musicstyles(sfile);
528
529 sect_idx = 0;
531 char path[512];
532
533 fc_snprintf(path, sizeof(path), "musicstyle_%d", sect_idx++);
534
535 secfile_insert_str(sfile, pmus->music_peaceful, "%s.music_peaceful", path);
536 secfile_insert_str(sfile, pmus->music_combat, "%s.music_combat", path);
537
538 save_reqs_vector(sfile, &(pmus->reqs), path, "reqs");
540
541 return save_ruleset_file(sfile, filename);
542}
543
544/**********************************************************************/
551 const int aap,
552 const char *uflags_path,
553 bool (*unexpected_req)(
554 const struct requirement *preq))
555{
557 size_t i;
558 size_t ret;
559
560 const struct action_auto_perf *auto_perf =
562
563 i = 0;
565 fc_assert(req->range == REQ_RANGE_LOCAL);
566
567 if (req->source.kind == VUT_UTFLAG) {
568 fc_assert(!req->present);
569
570 protecor_flag[i++] = req->source.value.unitflag;
571 } else if (unexpected_req(req)) {
572 struct astring astr;
573
574 log_error("Can't handle action auto performer requirement %s",
575 req_to_fstring(req, &astr));
576 astr_free(&astr);
577
578 return FALSE;
579 }
581
584 "%s", uflags_path);
585
586 if (ret != i) {
587 log_error("%s: didn't save all unit type flags.", uflags_path);
588
589 return FALSE;
590 }
591
592 return TRUE;
593}
594
595/**********************************************************************/
601static bool save_action_auto_actions(struct section_file *sfile,
602 const int aap,
603 const char *actions_path)
604{
606 size_t i, j;
607 size_t ret;
608
609 const struct action_auto_perf *auto_perf
611
612 for (i = 0, j = 0;
613 i < NUM_ACTIONS && auto_perf->alternatives[i] != ACTION_NONE;
614 i++) {
615 struct action *paction = action_by_number(auto_perf->alternatives[i]);
616
618 /* Don't mention non enabled actions. */
619 continue;
620 }
621
622 /* This action is included in the output. */
623 unit_acts[j] = auto_perf->alternatives[i];
624 j++;
625 }
626
629 "%s", actions_path);
630
631 if (ret != j) {
632 log_error("%s: didn't save all actions.", actions_path);
633
634 return FALSE;
635 }
636
637 return TRUE;
638}
639
640/**********************************************************************/
644static bool unexpected_non_otype(const struct requirement *req)
645{
646 return !(req->source.kind == VUT_OTYPE && req->present);
647}
648
649/**********************************************************************/
654static bool save_muuk_action_auto(struct section_file *sfile,
655 const int aap,
656 const char *item)
657{
658 char uflags_path[100];
659 char action_path[100];
660
662 "missing_unit_upkeep.%s_protected", item);
664 "missing_unit_upkeep.%s_unit_act", item);
665
669}
670
671/**********************************************************************/
674static bool save_cities_ruleset(const char *filename, const char *name)
675{
676 struct section_file *sfile = create_ruleset_file(name, "cities");
677 int sect_idx;
678
679 if (sfile == nullptr) {
680 return FALSE;
681 }
682
683 comment_specialists(sfile);
684
685 sect_idx = 0;
688 char path[512];
689
690 fc_snprintf(path, sizeof(path),
692 ? "super_specialist_%d" : "specialist_%d", sect_idx++);
693
694 save_name_translation(sfile, &(s->name), path);
695
697 struct entry *pentry =
699 "%s.short_name", path);
701 }
702
703 save_reqs_vector(sfile, &(s->reqs), path, "reqs");
704
705 secfile_insert_str(sfile, s->graphic_str, "%s.graphic", path);
706 if (strcmp(s->graphic_alt, "-")) {
707 secfile_insert_str(sfile, s->graphic_alt, "%s.graphic_alt", path);
708 }
709
710 save_helptext(sfile, s->helptext, path, "helptext");
711
713
716 "parameters.celebrate_size_limit");
717 }
720 "parameters.add_to_size_limit");
721 }
724 "parameters.angry_citizens");
725 }
728 "parameters.changable_tax");
729 }
730 if (game.info.forced_science != 0) {
732 "parameters.forced_science");
733 }
734 if (game.info.forced_luxury != 100) {
736 "parameters.forced_luxury");
737 }
738 if (game.info.forced_gold != 0) {
740 "parameters.forced_gold");
741 }
744 "parameters.vision_reveal_tiles");
745 }
746 if (game.info.pop_report_zeroes != 1) {
748 "parameters.pop_report_zeroes");
749 }
750
753 "citizen.nationality", nullptr);
756 "citizen.ubuilder_nationality", nullptr);
759 "citizen.convert_speed", nullptr);
760 if (game.info.conquest_convert_pct != 0) {
762 "citizen.conquest_convert_pct");
763 }
764
767 "citizen.partisans_pct");
768 }
769
771 "food");
774 "missing_unit_upkeep.food_wipe");
775 }
776
778 "gold");
781 "missing_unit_upkeep.gold_wipe");
782 }
783
785 "shield");
788 "missing_unit_upkeep.shield_wipe");
789 }
790
791 return save_ruleset_file(sfile, filename);
792}
793
794/**************************************************************************
795 Effect saving callback data structure.
796**************************************************************************/
797typedef struct {
798 int idx;
801
802/**********************************************************************/
805static bool effect_save(struct effect *peffect, void *data)
806{
808 char path[512];
809
810 if (peffect->rulesave.do_not_save) {
811 /* Is supposed to be skipped. */
812 return TRUE;
813 }
814
815 fc_snprintf(path, sizeof(path), "effect_%d", cbdata->idx++);
816
819 "%s.type", path);
820 secfile_insert_int(cbdata->sfile, peffect->value, "%s.value", path);
821
822 save_reqs_vector(cbdata->sfile, &peffect->reqs, path, "reqs");
823
824 if (peffect->rulesave.comment != nullptr) {
825 secfile_insert_str(cbdata->sfile, peffect->rulesave.comment,
826 "%s.comment", path);
827 }
828
829 return TRUE;
830}
831
832/**********************************************************************/
835static bool save_effects_ruleset(const char *filename, const char *name)
836{
837 struct section_file *sfile = create_ruleset_file(name, "effect");
838 effect_cb_data data;
839 int i;
840 int sidx;
841
842 if (sfile == nullptr) {
843 return FALSE;
844 }
845
846 data.idx = 0;
847 data.sfile = sfile;
848
849 comment_ueffs(sfile);
850
851 sidx = 0;
852 for (i = EFT_USER_EFFECT_1 ; i <= EFT_USER_EFFECT_LAST; i++) {
853 enum effect_type val = user_effect_ai_valued_as(i);
854
855 if (val != i) {
856 char path[512];
857
858 fc_snprintf(path, sizeof(path), "ueff_%d", sidx++);
859
861 "%s.type", path);
863 "%s.ai_valued_as", path);
864 }
865 }
866
867 comment_effects(sfile);
868
869 if (!iterate_effect_cache(effect_save, &data)) {
870 return FALSE;
871 }
872
873 return save_ruleset_file(sfile, filename);
874}
875
876/**********************************************************************/
879static bool save_action_max_range(struct section_file *sfile,
880 action_id act)
881{
882 struct action *paction = action_by_number(act);
883
884 if (paction->max_distance == ACTION_DISTANCE_UNLIMITED) {
886 "actions.%s",
887 action_max_range_ruleset_var_name(act)) != nullptr;
888 } else {
891 "actions",
893 }
894}
895
896/**********************************************************************/
899static bool save_action_range(struct section_file *sfile, action_id act)
900{
901 struct action *paction = action_by_number(act);
902
903 if (action_min_range_ruleset_var_name(act) != nullptr) {
904 /* Min range can be loaded from the ruleset. */
905 save_default_int(sfile,
906 paction->min_distance,
908 "actions",
910 }
911
912 if (action_max_range_ruleset_var_name(act) != nullptr) {
913 /* Max range can be loaded from the ruleset. */
914 if (!save_action_max_range(sfile, act)) {
915 return FALSE;
916 }
917 }
918
919 return TRUE;
920}
921
922/**********************************************************************/
925static bool save_action_kind(struct section_file *sfile, action_id act)
926{
927 if (action_target_kind_ruleset_var_name(act) != nullptr) {
928 struct action *paction = action_by_number(act);
929
930 /* Target kind can be loaded from the ruleset. */
932 /* Don't save the default for actions that aren't enabled. */
933 return TRUE;
934 }
935
939 "actions.%s",
941 }
942
943 return TRUE;
944}
945
946/**********************************************************************/
950 action_id act)
951{
953 struct action *paction = action_by_number(act);
954
955 /* Actor consumption can be loaded from the ruleset. */
957 /* Don't save value for actions that aren't enabled. */
958 return TRUE;
959 }
960
961 save_default_bool(sfile,
964 "actions",
966 }
967
968 return TRUE;
969}
970
971/**********************************************************************/
974static bool save_action_blocked_by(struct section_file *sfile,
975 struct action *paction)
976{
978 char comment[1024];
979 int i = 0;
980
982 /* Action blocked by shouldn't be written to the ruleset for this
983 * action. */
984 return TRUE;
985 }
986
988 /* Don't save value for actions that aren't enabled. */
989 return TRUE;
990 }
991
992 fc_snprintf(comment, sizeof(comment),
993 "Forbid \"%s\" if any one of the listed actions are legal.",
995
998
1000 /* Don't save value for actions that aren't enabled. */
1001 continue;
1002 }
1003
1004 if (BV_ISSET(paction->blocked_by, blocker_id)) {
1006 i++;
1007 }
1009
1011 sfile, &action_vec, i, gen_action, comment, "actions.%s",
1013 != i) {
1014 log_error("Didn't save all %s blocking actions.",
1016
1017 return FALSE;
1018 }
1019
1020 return TRUE;
1021}
1022
1023/**********************************************************************/
1028 int performer_slot,
1029 struct action *paction)
1030{
1031 char action_list_path[100];
1032
1034 /* Not relevant. */
1035 return TRUE;
1036 }
1037
1038 if (!action_is_in_use(paction)) {
1039 /* Don't save value for actions that aren't enabled. */
1040 return TRUE;
1041 }
1042
1044 "actions.%s",
1047 return FALSE;
1048 }
1049
1050 return TRUE;
1051}
1052
1053/**********************************************************************/
1056static bool save_bv_actions(struct section_file *sfile,
1057 bv_actions content,
1058 const char *path)
1059{
1061 int i = 0;
1062
1063 action_iterate(act_id) {
1064 struct action *paction = action_by_number(act_id);
1065
1066 if (!action_is_in_use(paction)) {
1067 /* Don't save value for actions that aren't enabled. */
1068 continue;
1069 }
1070
1071 if (BV_ISSET(content, act_id)) {
1072 action_vec[i] = act_id;
1073 i++;
1074 }
1076
1078 "%s", path) != i) {
1079 log_error("Didn't save all of %s.", path);
1080
1081 return FALSE;
1082 }
1083
1084 return TRUE;
1085}
1086/**********************************************************************/
1089static bool save_actions_ruleset(const char *filename, const char *name)
1090{
1091 struct section_file *sfile = create_ruleset_file(name, "actions");
1093 int i = 0;
1094 int sect_idx = 0;
1095
1096 /* TODO: move action logic from save_game_ruleset to here */
1097 if (sfile == nullptr) {
1098 return FALSE;
1099 }
1100 {
1101 /* Action auto performers aren't ready to be exposed in the ruleset
1102 * yet. The behavior when two action auto performers for the same
1103 * cause can fire isn't set in stone yet. How is one of them chosen?
1104 * What if all the actions of the chosen action auto performer turned
1105 * out to be illegal but one of the other action auto performers that
1106 * fired has legal actions? These issues can decide what other action
1107 * rules action auto performers can represent in the future. Deciding
1108 * should therefore wait until a rule needs action auto performers to
1109 * work a certain way. */
1110 /* Only one action auto performer, ACTION_AUTO_MOVED_ADJ, is caused
1111 * by AAPC_UNIT_MOVED_ADJ. It is therefore safe to expose the full
1112 * requirement vector to the ruleset. */
1113 const struct action_auto_perf *auto_perf =
1115
1116 comment_auto_attack(sfile);
1117
1118 save_reqs_vector(sfile, &auto_perf->reqs,
1119 "auto_attack", "if_attacker");
1120
1122 "auto_attack.attack_actions");
1123 }
1124
1127 "actions.diplchance_initial_odds")) {
1128 return FALSE;
1129 }
1130
1134 log_error("Didn't save all post success forced actions.");
1135 return FALSE;
1136 }
1137
1141 log_error("Didn't save all post success forced actions.");
1142 return FALSE;
1143 }
1144
1147 log_error("Didn't save all post success forced actions.");
1148 return FALSE;
1149 }
1150
1153 log_error("Didn't save all post success forced actions.");
1154 return FALSE;
1155 }
1156
1158 "actions.escape_city")) {
1159 log_error("Didn't save all escape city forced actions.");
1160 return FALSE;
1161 }
1162
1164 "actions.unit_stack_death")) {
1165 log_error("Didn't save all escape unit stack death forced actions.");
1166 return FALSE;
1167 }
1168
1171 "actions.poison_empties_food_stock", nullptr);
1172
1175 "actions.steal_maps_reveals_all_cities", nullptr);
1176
1177 action_iterate(act_id) {
1178 struct action *act = action_by_number(act_id);
1179
1180 save_action_kind(sfile, act_id);
1181 save_action_range(sfile, act_id);
1183 save_action_blocked_by(sfile, act);
1185
1187
1188 i = 0;
1189 action_iterate(act) {
1190 if (action_by_number(act)->quiet) {
1191 action_vec[i] = act;
1192 i++;
1193 }
1195
1197 "actions.quiet_actions") != i) {
1198 log_error("Didn't save all quiet actions.");
1199
1200 return FALSE;
1201 }
1202
1203 comment_actions(sfile);
1204 for (i = 0; i < MAX_NUM_ACTIONS; i++) {
1205 struct action *paction = action_by_number(i);
1206
1207 if (!action_is_in_use(paction)) {
1208 /* Don't mention non enabled actions. */
1209 continue;
1210 }
1211
1212 if (paction->configured) {
1213 char path[512];
1214 const char *ui_name;
1215
1216 fc_snprintf(path, sizeof(path), "action_%d", i);
1217
1219 "%s.action", path);
1220
1221 if (!action_id_is_internal(i)) {
1222 ui_name = paction->ui_name;
1223
1224 if (ui_name == nullptr) {
1225 fc_assert(ui_name != nullptr);
1226
1227 return FALSE;
1228 }
1229
1231 struct entry *pentry =
1232 secfile_insert_str(sfile, ui_name,
1233 "%s.ui_name", path);
1235 }
1236 }
1237 }
1238 }
1239
1240 comment_enablers(sfile);
1241 sect_idx = 0;
1243 char path[512];
1244
1245 if (pae->rulesave.ruledit_disabled) {
1246 continue;
1247 }
1248
1249 fc_snprintf(path, sizeof(path), "enabler_%d", sect_idx++);
1250
1252 "%s.action", path);
1253
1254 save_reqs_vector(sfile, &(pae->actor_reqs), path, "actor_reqs");
1255 save_reqs_vector(sfile, &(pae->target_reqs), path, "target_reqs");
1256
1257 if (pae->rulesave.comment != nullptr) {
1258 secfile_insert_str(sfile, pae->rulesave.comment, "%s.comment", path);
1259 }
1261
1262 return save_ruleset_file(sfile, filename);
1263}
1264
1265/**********************************************************************/
1268static bool save_game_ruleset(const char *filename, const char *name)
1269{
1270 struct section_file *sfile = create_ruleset_file(name, "game");
1271 int sect_idx;
1272 int col_idx;
1273 int set_count;
1274 enum gameloss_style gs;
1275 const char *style_names[32]; /* FIXME: Should determine max length automatically.
1276 * currently it's 3 (bits 0,1, and 2) so there's plenty of
1277 * safety margin here. */
1278 const char *tnames[game.server.ruledit.named_teams];
1279 enum trade_route_type trt;
1280 int i;
1281 bool locks;
1282
1283 if (sfile == nullptr) {
1284 return FALSE;
1285 }
1286
1287 if (game.server.ruledit.description_file != nullptr) {
1289 "ruledit.description_file");
1290 }
1291
1295 "ruledit.std_tileset_compat");
1296 }
1297
1298 if (game.control.preferred_tileset[0] != '\0') {
1300 "tileset.preferred");
1301 }
1302 if (game.control.preferred_soundset[0] != '\0') {
1304 "soundset.preferred");
1305 }
1306 if (game.control.preferred_musicset[0] != '\0') {
1308 "musicset.preferred");
1309 }
1310
1311 secfile_insert_str(sfile, game.control.name, "about.name");
1312 secfile_insert_str(sfile, game.control.version, "about.version");
1313
1314 if (game.control.alt_dir[0] != '\0') {
1315 secfile_insert_str(sfile, game.control.alt_dir, "about.alt_dir");
1316 }
1317
1318 if (game.ruleset_summary != nullptr) {
1319 struct entry *pentry =
1320 secfile_insert_str(sfile, game.ruleset_summary, "about.summary");
1322 }
1323
1324 if (game.ruleset_description != nullptr) {
1325 if (game.server.ruledit.description_file == nullptr) {
1327 "about.description");
1328 } else {
1330 "about.description");
1331 }
1332 }
1333
1334 if (game.ruleset_capabilities != nullptr) {
1336 "about.capabilities");
1337 } else {
1338 secfile_insert_str(sfile, "", "about.capabilities");
1339 }
1340
1342 "options", "global_init_techs");
1344 "options", "global_init_buildings");
1345
1347 FALSE,
1348 "options.popup_tech_help", nullptr);
1351 "civstyle.base_pollution", nullptr);
1352
1353 set_count = 0;
1355 if (game.info.gameloss_style & gs) {
1357 }
1358 }
1359
1360 if (set_count > 0) {
1362
1364 "civstyle.gameloss_style");
1365 }
1366
1369 "civstyle.happy_cost", nullptr);
1372 "civstyle.food_cost", nullptr);
1373 save_default_bool(sfile,
1376 FALSE,
1377 "civstyle.paradrop_to_transport", nullptr);
1380 "civstyle.base_bribe_cost", nullptr);
1383 }
1386 "civstyle.ransom_gold", nullptr);
1389 "civstyle.pillage_select", nullptr);
1392 "civstyle.tech_steal_allow_holes", nullptr);
1395 "civstyle.tech_trade_allow_holes", nullptr);
1398 "civstyle.tech_trade_loss_allow_holes", nullptr);
1401 "civstyle.tech_parasite_allow_holes", nullptr);
1404 "civstyle.tech_loss_allow_holes", nullptr);
1407 "civstyle.upgrade_veteran_loss", nullptr);
1410 "civstyle.autoupgrade_veteran_loss", nullptr);
1411
1413
1416 "civstyle.granary_food_ini");
1417
1420 "civstyle.granary_food_inc", nullptr);
1421
1423 char buffer[256];
1424
1425 fc_snprintf(buffer, sizeof(buffer),
1426 "civstyle.min_city_center_%s",
1428
1431 buffer, nullptr);
1433
1436 "civstyle.init_vis_radius_sq", nullptr);
1439 "civstyle.init_city_radius_sq", nullptr);
1440
1442
1445 secfile_insert_str(sfile,
1447 "civstyle.gold_upkeep_style");
1448 }
1450 1, "civstyle.output_granularity", nullptr);
1451
1454 }
1456 FALSE, "civstyle.airlift_from_always_enabled", nullptr);
1458 TRUE, "civstyle.airlift_to_always_enabled", nullptr);
1459
1463 secfile_insert_str(sfile,
1465 "wonder_visibility.small_wonders");
1466 }
1467
1470 "illness.illness_on", nullptr);
1473 "illness.illness_base_factor", nullptr);
1476 "illness.illness_min_size", nullptr);
1479 "illness.illness_trade_infection", nullptr);
1482 "illness.illness_pollution_factor", nullptr);
1483 comment_incite_cost(sfile);
1486 "incite_cost.base_incite_cost", nullptr);
1489 "incite_cost.improvement_factor", nullptr);
1492 "incite_cost.unit_factor", nullptr);
1495 "incite_cost.total_factor", nullptr);
1496
1499 }
1502 "combat_rules.tired_attack", nullptr);
1505 }
1508 "combat_rules.only_killing_makes_veteran", nullptr);
1511 }
1514 "combat_rules.only_real_fight_makes_veteran", nullptr);
1517 }
1520 "combat_rules.combat_odds_scaled_veterancy", nullptr);
1523 }
1526 "combat_rules.damage_reduces_bombard_rate", nullptr);
1529 }
1531 "combat_rules.low_firepower_badwallattacker", nullptr);
1534 }
1536 "combat_rules.low_firepower_pearl_harbor", nullptr);
1539 }
1541 "combat_rules.low_firepower_combat_bonus", nullptr);
1544 }
1546 "combat_rules.low_firepower_nonnat_bombard", nullptr);
1549 }
1552 "combat_rules.nuke_pop_loss_pct", nullptr);
1556 }
1559 "combat_rules.nuke_defender_survival_chance_pct", nullptr);
1562 "borders.radius_sq_city", nullptr);
1565 "borders.size_effect", nullptr);
1569 }
1572 "borders.radius_sq_city_permanent", nullptr);
1573
1576 "research.tech_cost_style");
1579 }
1582 "research.base_tech_cost", nullptr);
1585 }
1588 "research.min_tech_cost", nullptr);
1591 "research.tech_leakage");
1594 "research.tech_upkeep_style");
1597 "research.tech_upkeep_divider", nullptr);
1600 "research.free_tech_method");
1601
1604 "culture.victory_min_points", nullptr);
1607 "culture.victory_lead_pct", nullptr);
1610 }
1613 "culture.migration_pml", nullptr);
1616 }
1619 "culture.history_interest_pml", nullptr);
1622 }
1625 "world_peace.victory_turns", nullptr);
1626
1629 "calendar.skip_year_0", nullptr);
1632 "calendar.start_year", nullptr);
1633 if (game.calendar.calendar_fragments != 0) {
1635 }
1637 0, "calendar.fragments", nullptr);
1638
1639 for (i = 0; i < MAX_CALENDAR_FRAGMENTS; i++) {
1640 if (game.calendar.calendar_fragment_name[i][0] != '\0') {
1642 "calendar.fragment_name%d", i);
1643 }
1644 }
1645
1647 struct entry *pentry =
1649 "calendar.positive_label");
1651 }
1653 struct entry *pentry =
1655 "calendar.negative_label");
1657 }
1658
1659 if (game.plr_bg_color != nullptr) {
1660 rgbcolor_save(sfile, game.plr_bg_color, "playercolors.background");
1661 }
1662
1663 col_idx = 0;
1665 rgbcolor_save(sfile, pcol, "playercolors.colorlist%d", col_idx++);
1667
1668
1669 if (game.server.ruledit.named_teams > 0) {
1670 for (i = 0; i < game.server.ruledit.named_teams; i++) {
1672 }
1673
1676 "teams.names");
1677 }
1678
1679 comment_disasters(sfile);
1680
1681 sect_idx = 0;
1683 char path[512];
1685 const char *effect_names[DE_COUNT];
1686
1687 fc_snprintf(path, sizeof(path), "disaster_%d", sect_idx++);
1688
1689 save_name_translation(sfile, &(pd->name), path);
1690 save_reqs_vector(sfile, &(pd->reqs), path, "reqs");
1691 if (pd->frequency != GAME_DEFAULT_DISASTER_FREQ) {
1692 secfile_insert_int(sfile, pd->frequency,
1693 "%s.frequency", path);
1694 }
1695
1696 set_count = 0;
1700 if (BV_ISSET(pd->effects, de)) {
1702 }
1703 }
1704
1705 if (set_count > 0) {
1707 "%s.effects", path);
1708 }
1710
1711 comment_achievements(sfile);
1712
1713 sect_idx = 0;
1715 char path[512];
1716 struct entry *pentry;
1717
1718 fc_snprintf(path, sizeof(path), "achievement_%d", sect_idx++);
1719
1720 save_name_translation(sfile, &(pach->name), path);
1721
1723 "%s.type", path);
1724
1725 save_default_bool(sfile, pach->unique,
1727 path, "unique");
1728 save_default_int(sfile, pach->value,
1730 path, "value");
1731 save_default_int(sfile, pach->culture,
1732 0, path, "culture");
1733
1734 pentry = secfile_insert_str(sfile, pach->first_msg,
1735 "%s.first_msg", path);
1737 if (pach->cons_msg != nullptr) {
1738 pentry = secfile_insert_str(sfile, pach->cons_msg,
1739 "%s.cons_msg", path);
1741 }
1742
1744
1746
1747 set_count = 0;
1748 for (trt = 0; trt < TRT_LAST; trt++) {
1751
1752 if (set->trade_pct != 100 || strcmp(cancelling, "Active")) {
1753 char path[256];
1754
1755 fc_snprintf(path, sizeof(path),
1756 "trade.settings%d", set_count++);
1757
1759 "%s.type", path);
1760 secfile_insert_int(sfile, set->trade_pct,
1761 "%s.pct", path);
1763 "%s.cancelling", path);
1765 "%s.bonus", path);
1766 }
1767 }
1768
1770 0, "trade.min_trade_route_val", nullptr);
1771
1773 FALSE, "trade.reveal_trade_partner", nullptr);
1774
1777 "trade.goods_selection");
1778 }
1779
1780 /* Goods */
1781 comment_goods(sfile);
1782
1783 sect_idx = 0;
1785 char path[512];
1786 const char *flag_names[GF_COUNT];
1787 int flagi;
1788
1789 fc_snprintf(path, sizeof(path), "goods_%d", sect_idx++);
1790
1791 save_name_translation(sfile, &(pgood->name), path);
1792
1793 save_reqs_vector(sfile, &(pgood->reqs), path, "reqs");
1794
1795 save_default_int(sfile, pgood->from_pct, 100, path, "from_pct");
1796 save_default_int(sfile, pgood->to_pct, 100, path, "to_pct");
1797 save_default_int(sfile, pgood->onetime_pct, 100, path, "onetime_pct");
1798 save_default_int(sfile, pgood->select_priority, 1, path, "select_priority");
1799 save_default_int(sfile, pgood->replace_priority, 1, path, "replace_priority");
1800
1801 set_count = 0;
1802 for (flagi = 0; flagi < GF_COUNT; flagi++) {
1803 if (goods_has_flag(pgood, flagi)) {
1805 }
1806 }
1807
1808 if (set_count > 0) {
1810 "%s.flags", path);
1811 }
1812
1813 save_helptext(sfile, pgood->helptext, path, "helptext");
1815
1816 {
1817 const struct unit_type *access_unit = access_info_access_unit();
1818
1819 if (access_unit != nullptr) {
1820 secfile_insert_str(sfile, utype_rule_name(access_unit),
1821 "aarea.access_unit");
1822 }
1823 }
1824
1825 /* Clauses */
1826 comment_clauses(sfile);
1827
1828 sect_idx = 0;
1829 for (i = 0; i < CLAUSE_COUNT; i++) {
1830 struct clause_info *info = clause_info_get(i);
1831
1832 if (info->enabled) {
1833 char path[512];
1834
1835 fc_snprintf(path, sizeof(path), "clause_%d", sect_idx++);
1836
1838 "%s.type", path);
1839 save_reqs_vector(sfile, &(info->giver_reqs), path, "giver_reqs");
1840 save_reqs_vector(sfile, &(info->receiver_reqs), path, "receiver_reqs");
1841 save_reqs_vector(sfile, &(info->either_reqs), path, "either_reqs");
1842 }
1843 }
1844
1845 /* Counters */
1846 comment_counters(sfile);
1847
1848 sect_idx = 0;
1850 char path[512];
1851
1852 fc_snprintf(path, sizeof(path), "counter_%d", sect_idx++);
1853
1854 save_name_translation(sfile, &(pcounter->name), path);
1855
1856 save_default_int(sfile, pcounter->def, 0, path, "def");
1857 save_default_int(sfile, pcounter->checkpoint, 0, path, "checkpoint");
1858
1859 secfile_insert_str(sfile, counter_behavior_name(pcounter->type), "%s.type", path);
1860
1861 if (pcounter->helptext != nullptr
1862 && strvec_size(pcounter->helptext) > 0) {
1863 save_helptext(sfile, pcounter->helptext, path, "helptext");
1864 }
1866
1867 locks = FALSE;
1870 locks = TRUE;
1871 break;
1872 }
1874
1875 set_count = 0;
1877 struct sf_cb_data info = { pset, FALSE };
1878
1881 "settings.set%d.name", set_count);
1882 switch (setting_type(pset)) {
1883 case SST_BOOL:
1885 "settings.set%d.value", set_count);
1886 break;
1887 case SST_INT:
1889 "settings.set%d.value", set_count);
1890 break;
1891 case SST_STRING:
1893 "settings.set%d.value", set_count);
1894 break;
1895 case SST_ENUM:
1898 "settings.set%d.value", set_count);
1899 break;
1900 case SST_BITWISE:
1903 "settings.set%d.value", set_count);
1904 break;
1905 case SST_COUNT:
1907 secfile_insert_str(sfile, "Unknown setting type",
1908 "settings.set%d.value", set_count);
1909 break;
1910 }
1911
1912 if (locks) {
1914 "settings.set%d.lock", set_count);
1915 }
1916
1917 set_count++;
1918 }
1920
1921 return save_ruleset_file(sfile, filename);
1922}
1923
1924/**********************************************************************/
1927static bool save_governments_ruleset(const char *filename, const char *name)
1928{
1929 struct section_file *sfile = create_ruleset_file(name, "government");
1930 int sect_idx;
1931 bool uflags_government = FALSE;
1932 int i;
1933
1934 if (sfile == nullptr) {
1935 return FALSE;
1936 }
1937
1938 for (i = 0; i < MAX_NUM_USER_GOVERNMENT_FLAGS; i++) {
1940 const char *helptxt = gov_flag_helptxt(i + GOVF_USER_FLAG_1);
1941
1942 if (flagname != nullptr) {
1943 if (!uflags_government) {
1946 }
1947
1948 secfile_insert_str(sfile, flagname, "control.flags%d.name", i);
1949
1950 /* Save the user flag help text even when it is undefined. That makes
1951 * the formatting code happy. The resulting "" is ignored when the
1952 * ruleset is loaded. */
1953 secfile_insert_str(sfile, helptxt,
1954 "control.flags%d.helptxt", i);
1955 }
1956 }
1957
1958 save_gov_ref(sfile, game.government_during_revolution, "governments",
1959 "during_revolution");
1960
1961 comment_govs(sfile);
1962
1963 sect_idx = 0;
1965 char path[512];
1966 struct ruler_title *prtitle;
1967 const char *flag_names[TF_COUNT];
1968 int set_count;
1969 int flagi;
1970
1971 fc_snprintf(path, sizeof(path), "government_%d", sect_idx++);
1972
1973 save_name_translation(sfile, &(pg->name), path);
1974
1975 secfile_insert_str(sfile, pg->graphic_str, "%s.graphic", path);
1976 secfile_insert_str(sfile, pg->graphic_alt, "%s.graphic_alt", path);
1977 secfile_insert_str(sfile, pg->sound_str, "%s.sound", path);
1978 secfile_insert_str(sfile, pg->sound_alt, "%s.sound_alt", path);
1979
1980 save_reqs_vector(sfile, &(pg->reqs), path, "reqs");
1981
1982 if (pg->ai.better != nullptr) {
1983 save_gov_ref(sfile, pg->ai.better, path,
1984 "ai_better");
1985 }
1986
1987 ruler_title_hash_lookup(pg->ruler_titles, nullptr,
1988 &prtitle);
1989 if (prtitle != nullptr) {
1990 const char *title;
1991
1993 if (title != nullptr) {
1994 struct entry *pentry =
1995 secfile_insert_str(sfile, title, "%s.ruler_male_title", path);
1997 }
1998
2000 if (title != nullptr) {
2001 struct entry *pentry =
2002 secfile_insert_str(sfile, title, "%s.ruler_female_title", path);
2004 }
2005 }
2006
2007 set_count = 0;
2009 if (BV_ISSET(pg->flags, flagi)) {
2011 }
2012 }
2013
2014 if (set_count > 0) {
2016 "%s.flags", path);
2017 }
2018
2019 save_helptext(sfile, pg->helptext, path, "helptext");
2020
2022
2023 comment_policies(sfile);
2024
2025 sect_idx = 0;
2026 multipliers_iterate(pmul) {
2027 if (!pmul->ruledit_disabled) {
2028 char path[512];
2029
2030 fc_snprintf(path, sizeof(path), "multiplier_%d", sect_idx++);
2031
2032 save_name_translation(sfile, &(pmul->name), path);
2033
2034 secfile_insert_int(sfile, pmul->start, "%s.start", path);
2035 secfile_insert_int(sfile, pmul->stop, "%s.stop", path);
2036 secfile_insert_int(sfile, pmul->step, "%s.step", path);
2037 secfile_insert_int(sfile, pmul->def, "%s.default", path);
2038
2039 save_default_int(sfile, pmul->offset, 0, path, "offset");
2040 save_default_int(sfile, pmul->factor, 100, path, "factor");
2041 save_default_int(sfile, pmul->minimum_turns, 0, path, "minimum_turns");
2042
2043 save_reqs_vector(sfile, &(pmul->reqs), path, "reqs");
2044
2045 save_helptext(sfile, pmul->helptext, path, "helptext");
2046 }
2048
2049 return save_ruleset_file(sfile, filename);
2050}
2051
2052/**********************************************************************/
2055static bool save_traits(struct trait_limits *traits,
2056 struct trait_limits *default_traits,
2057 struct section_file *sfile,
2058 const char *secname, const char *field_prefix)
2059{
2060 enum trait tr;
2061
2062 /* FIXME: Use specenum trait names without duplicating them here.
2063 * Just needs to take care of case.
2064 * This list is also duplicated in ruleset.c:ruleset_load_traits() */
2065 const char *trait_names[] = {
2066 "expansionist",
2067 "trader",
2068 "aggressive",
2069 "builder",
2070 nullptr
2071 };
2072
2073 for (tr = trait_begin(); tr != trait_end() && trait_names[tr] != nullptr;
2074 tr = trait_next(tr)) {
2075 int default_default;
2076
2077 default_default = (traits[tr].min + traits[tr].max) / 2;
2078
2079 if ((default_traits == nullptr && traits[tr].min != TRAIT_DEFAULT_VALUE)
2080 || (default_traits != nullptr && traits[tr].min != default_traits[tr].min)) {
2081 secfile_insert_int(sfile, traits[tr].min, "%s.%s%s_min", secname, field_prefix,
2082 trait_names[tr]);
2083 }
2084 if ((default_traits == nullptr && traits[tr].max != TRAIT_DEFAULT_VALUE)
2085 || (default_traits != nullptr && traits[tr].max != default_traits[tr].max)) {
2086 secfile_insert_int(sfile, traits[tr].max, "%s.%s%s_max", secname, field_prefix,
2087 trait_names[tr]);
2088 }
2089 if (default_default != traits[tr].fixed) {
2090 secfile_insert_int(sfile, traits[tr].fixed, "%s.%s%s_default", secname, field_prefix,
2091 trait_names[tr]);
2092 }
2093 }
2094
2095 return TRUE;
2096}
2097
2098/**********************************************************************/
2101static bool save_nation(struct section_file *sfile, struct nation_type *pnat,
2102 int sect_idx)
2103{
2104 char path[512];
2105 int max_items = nation_city_list_size(pnat->server.default_cities);
2106 char *city_str[max_items];
2109 const char *list_items[max_items];
2110 int set_count;
2111 int subsect_idx;
2112
2113 fc_snprintf(path, sizeof(path), "nation_%d", sect_idx++);
2114
2115 if (pnat->translation_domain == nullptr) {
2116 secfile_insert_str(sfile, "freeciv-core", "%s.translation_domain", path);
2117 } else {
2118 secfile_insert_str(sfile, pnat->translation_domain, "%s.translation_domain", path);
2119 }
2120
2121 save_name_translation(sfile, &(pnat->adjective), path);
2122 secfile_insert_str(sfile, untranslated_name(&(pnat->noun_plural)), "%s.plural", path);
2123
2124 set_count = 0;
2126 if (nation_is_in_set(pnat, pset)) {
2128 }
2133 }
2135
2136 if (set_count > 0) {
2137 secfile_insert_str_vec(sfile, list_items, set_count, "%s.groups", path);
2138 }
2139
2140 set_count = 0;
2141 nation_list_iterate(pnat->server.conflicts_with, pconfl) {
2144 if (set_count > 0) {
2145 secfile_insert_str_vec(sfile, list_items, set_count, "%s.conflicts_with", path);
2146 }
2147
2148 subsect_idx = 0;
2150 secfile_insert_str(sfile, nation_leader_name(pleader), "%s.leaders%d.name",
2151 path, subsect_idx);
2152 secfile_insert_str(sfile,
2155 "%s.leaders%d.sex", path, subsect_idx++);
2157
2158 if (pnat->server.rgb != nullptr) {
2159 rgbcolor_save(sfile, pnat->server.rgb, "%s.color", path);
2160 }
2161
2162 save_traits(pnat->server.traits, game.server.default_traits,
2163 sfile, path, "trait_");
2164
2165 if (!pnat->is_playable) {
2166 secfile_insert_bool(sfile, pnat->is_playable, "%s.is_playable", path);
2167 }
2168
2169 if (pnat->barb_type != NOT_A_BARBARIAN) {
2170 secfile_insert_str(sfile, barbarian_type_name(pnat->barb_type),
2171 "%s.barbarian_type", path);
2172 }
2173
2174 if (strcmp(pnat->flag_graphic_str, "-")) {
2175 secfile_insert_str(sfile, pnat->flag_graphic_str, "%s.flag", path);
2176 }
2177 if (strcmp(pnat->flag_graphic_alt, "-")) {
2178 secfile_insert_str(sfile, pnat->flag_graphic_alt, "%s.flag_alt", path);
2179 }
2180
2181 subsect_idx = 0;
2183 struct ruler_title *prtitle;
2184
2185 if (ruler_title_hash_lookup(pgov->ruler_titles, pnat, &prtitle)) {
2187 "%s.ruler_titles%d.government", path, subsect_idx);
2189 "%s.ruler_titles%d.male_title", path, subsect_idx);
2191 "%s.ruler_titles%d.female_title", path, subsect_idx++);
2192 }
2194
2195 secfile_insert_str(sfile, style_rule_name(pnat->style), "%s.style", path);
2196
2197 set_count = 0;
2198 nation_list_iterate(pnat->server.civilwar_nations, pconfl) {
2201 if (set_count > 0) {
2202 secfile_insert_str_vec(sfile, list_items, set_count, "%s.civilwar_nations", path);
2203 }
2204
2205 save_tech_list(sfile, pnat->init_techs, path, "init_techs");
2206 save_building_list(sfile, pnat->init_buildings, path, "init_buildings");
2207 save_unit_list(sfile, pnat->init_units, path, "init_units");
2208
2209 if (pnat->init_government) {
2210 secfile_insert_str(sfile, government_rule_name(pnat->init_government),
2211 "%s.init_government", path);
2212 }
2213
2214 set_count = 0;
2215 nation_city_list_iterate(pnat->server.default_cities, pncity) {
2216 bool list_started = FALSE;
2217
2219 + strlen(")")
2220 + MAX_NUM_TERRAINS * (strlen(", ") + MAX_LEN_NAME));
2221
2224 case NCP_DISLIKE:
2225 strcat(city_str[set_count], " (!river");
2227 break;
2228 case NCP_LIKE:
2229 strcat(city_str[set_count], " (river");
2231 break;
2232 case NCP_NONE:
2233 break;
2234 }
2235
2237 const char *pref = nullptr;
2238
2240 case NCP_DISLIKE:
2241 pref = "!";
2242 break;
2243 case NCP_LIKE:
2244 pref = "";
2245 break;
2246 case NCP_NONE:
2247 pref = nullptr;
2248 break;
2249 }
2250
2251 if (pref != nullptr) {
2252 if (list_started) {
2253 strcat(city_str[set_count], ", ");
2254 } else {
2255 strcat(city_str[set_count], " (");
2257 }
2260 }
2261
2263
2264 if (list_started) {
2265 strcat(city_str[set_count], ")");
2266 }
2267
2269 set_count++;
2271 if (set_count > 0) {
2272 int i;
2273
2274 secfile_insert_str_vec(sfile, list_items, set_count, "%s.cities", path);
2275
2276 for (i = 0; i < set_count; i++) {
2277 FC_FREE(city_str[i]);
2278 }
2279 }
2280
2281 secfile_insert_str(sfile, pnat->legend, "%s.legend", path);
2282
2283 return TRUE;
2284}
2285
2286/**********************************************************************/
2289static bool save_nations_ruleset(const char *filename, const char *name,
2290 struct rule_data *data)
2291{
2292 struct section_file *sfile = create_ruleset_file(name, "nation");
2293
2294 if (sfile == nullptr) {
2295 return FALSE;
2296 }
2297
2298 if (data->nationlist != nullptr || game.server.ruledit.embedded_nations != nullptr) {
2300 if (data->nationlist != nullptr) {
2301 secfile_insert_str(sfile, data->nationlist, "ruledit.nationlist");
2302 }
2303 if (game.server.ruledit.embedded_nations != nullptr) {
2304 int i;
2305 const char **tmp = fc_malloc(game.server.ruledit.embedded_nations_count * sizeof(char *));
2306
2307 /* Dance around the secfile_insert_str_vec() parameter type (requires extra const)
2308 * resrictions */
2309 for (i = 0; i < game.server.ruledit.embedded_nations_count; i++) {
2311 }
2312
2315 "ruledit.embedded_nations");
2316 free(tmp);
2317 }
2318 }
2319
2320 save_traits(game.server.default_traits, nullptr, sfile,
2321 "default_traits", "");
2322
2323 if (data->nationlist == nullptr) {
2324 if (game.server.ruledit.allowed_govs != nullptr) {
2327 "compatibility.allowed_govs");
2328 }
2329 if (game.server.ruledit.allowed_terrains != nullptr) {
2332 "compatibility.allowed_terrains");
2333 }
2334 if (game.server.ruledit.allowed_styles != nullptr) {
2337 "compatibility.allowed_styles");
2338 }
2339 }
2340
2341 if (game.default_government != nullptr) {
2343 "compatibility.default_government");
2344 }
2345
2346 if (data->nationlist != nullptr) {
2347 secfile_insert_include(sfile, data->nationlist);
2348
2349 if (game.server.ruledit.embedded_nations != nullptr) {
2350 int sect_idx;
2351
2352 comment_nations(sfile);
2353
2355 sect_idx++) {
2356 struct nation_type *pnat
2358
2359 if (pnat == nullptr) {
2360 log_error("Embedded nation \"%s\" not found!",
2362 } else {
2363 save_nation(sfile, pnat, sect_idx);
2364 }
2365 }
2366 }
2367 } else {
2368 int sect_idx = 0;
2369
2370 comment_nationsets(sfile);
2371
2373 char path[512];
2374
2375 fc_snprintf(path, sizeof(path), "nset_%d", sect_idx++);
2376
2377 /* We don't use save_name_translation() for this as name and rule_name must
2378 * always be saved separately */
2379 secfile_insert_str(sfile, nation_set_untranslated_name(pset), "%s.name", path);
2380 secfile_insert_str(sfile, nation_set_rule_name(pset), "%s.rule_name", path);
2381 secfile_insert_str(sfile, nation_set_description(pset), "%s.description", path);
2383
2384 comment_nationgroups(sfile);
2385
2386 sect_idx = 0;
2388 char path[512];
2389
2390 fc_snprintf(path, sizeof(path), "ngroup_%d", sect_idx++);
2391
2392 save_name_translation(sfile, &(pgroup->name), path);
2393
2394 secfile_insert_int(sfile, pgroup->server.match, "%s.match", path);
2395 if (pgroup->hidden) {
2396 secfile_insert_bool(sfile, pgroup->hidden, "%s.hidden", path);
2397 }
2399
2400 comment_nations(sfile);
2401
2402 sect_idx = 0;
2404 save_nation(sfile, pnat, sect_idx++);
2406 }
2407
2408 return save_ruleset_file(sfile, filename);
2409}
2410
2411/**********************************************************************/
2414static bool save_techs_ruleset(const char *filename, const char *name)
2415{
2416 struct section_file *sfile = create_ruleset_file(name, "tech");
2417 int i;
2418 int sect_idx;
2420 bool uflags_tech = FALSE;
2421
2422 if (sfile == nullptr) {
2423 return FALSE;
2424 }
2425
2426 for (i = 0; i < MAX_NUM_USER_TECH_FLAGS; i++) {
2427 const char *flagname = tech_flag_id_name_cb(i + TECH_USER_1);
2428 const char *helptxt = tech_flag_helptxt(i + TECH_USER_1);
2429 struct entry *pentry;
2430
2431 if (flagname != nullptr) {
2432 if (!uflags_tech) {
2433 comment_uflags_tech(sfile);
2434 uflags_tech = TRUE;
2435 }
2436
2438 "control.flags%d.name", i);
2440
2441 /* Save the user flag help text even when it is undefined. That makes
2442 * the formatting code happy. The resulting "" is ignored when the
2443 * ruleset is loaded. */
2444 pentry = secfile_insert_str(sfile, helptxt,
2445 "control.flags%d.helptxt", i);
2447 }
2448 }
2449
2450 comment_tech_classes(sfile);
2451
2452 sect_idx = 0;
2454 char path[512];
2455
2456 fc_snprintf(path, sizeof(path), "techclass_%d", sect_idx++);
2457
2458 save_name_translation(sfile, &(ptclass->name), path);
2460
2461 comment_techs(sfile);
2462
2463 sect_idx = 0;
2465 if (pa->require[AR_ONE] != A_NEVER) {
2466 char path[512];
2467 const char *flag_names[TF_COUNT];
2468 int set_count;
2469 int flagi;
2470
2471 fc_snprintf(path, sizeof(path), "advance_%d", sect_idx++);
2472
2473 save_name_translation(sfile, &(pa->name), path);
2474
2475 if (game.control.num_tech_classes > 0) {
2476 if (pa->tclass != nullptr) {
2478 "%s.class", path);
2479 }
2480 }
2481
2482 save_tech_ref(sfile, pa->require[AR_ONE], path, "req1");
2483 save_tech_ref(sfile, pa->require[AR_TWO], path, "req2");
2484 if (pa->require[AR_ROOT] != a_none && !pa->inherited_root_req) {
2485 save_tech_ref(sfile, pa->require[AR_ROOT], path, "root_req");
2486 }
2487
2488 save_reqs_vector(sfile, &(pa->research_reqs), path,
2489 "research_reqs");
2490
2491 secfile_insert_str(sfile, pa->graphic_str, "%s.graphic", path);
2492 if (strcmp("-", pa->graphic_alt)) {
2493 secfile_insert_str(sfile, pa->graphic_alt, "%s.graphic_alt", path);
2494 }
2495 if (pa->bonus_message != nullptr) {
2496 struct entry *pentry =
2497 secfile_insert_str(sfile, pa->bonus_message,
2498 "%s.bonus_message", path);
2500 }
2501
2502 set_count = 0;
2503 for (flagi = 0; flagi < TF_COUNT; flagi++) {
2506 }
2507 }
2508
2509 if (set_count > 0) {
2511 "%s.flags", path);
2512 }
2513 if (pa->cost >= 0) {
2514 secfile_insert_int(sfile, pa->cost, "%s.cost", path);
2515 }
2516
2517 save_helptext(sfile, pa->helptext, path, "helptext");
2518 }
2519
2521
2522 return save_ruleset_file(sfile, filename);
2523}
2524
2525/**********************************************************************/
2528static bool save_terrain_ruleset(const char *filename, const char *name)
2529{
2530 struct section_file *sfile = create_ruleset_file(name, "terrain");
2531 int sect_idx;
2532 int i;
2533 bool uflags_terr = FALSE;
2534 bool uflags_extra = FALSE;
2535
2536 if (sfile == nullptr) {
2537 return FALSE;
2538 }
2539
2540 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
2542 const char *helptxt = terrain_flag_helptxt(i + TER_USER_1);
2543 struct entry *pentry;
2544
2545 if (flagname != nullptr) {
2546 if (!uflags_terr) {
2548 uflags_terr = TRUE;
2549 }
2550
2552 "control.flags%d.name", i);
2554
2555 /* Save the user flag help text even when it is undefined. That makes
2556 * the formatting code happy. The resulting "" is ignored when the
2557 * ruleset is loaded. */
2558 pentry = secfile_insert_str(sfile, helptxt,
2559 "control.flags%d.helptxt", i);
2561 }
2562 }
2563
2564 for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
2566 const char *helptxt = extra_flag_helptxt(i + EF_USER_FLAG_1);
2567 struct entry *pentry;
2568
2569 if (flagname != nullptr) {
2570 if (!uflags_extra) {
2571 /* TODO: Uncomment this, once there's a way to stop
2572 * the comment getting written inside preceding
2573 * terrain flags table. */
2574 /* comment_uflags_extra(sfile); */
2576 }
2577
2579 "control.extra_flags%d.name", i);
2581
2582 /* Save the user flag help text even when it is undefined. That makes
2583 * the formatting code happy. The resulting "" is ignored when the
2584 * ruleset is loaded. */
2585 pentry = secfile_insert_str(sfile, helptxt,
2586 "control.extra_flags%d.helptxt", i);
2588 }
2589 }
2590
2591 if (terrain_control.ocean_reclaim_requirement_pct <= 100) {
2592 secfile_insert_int(sfile, terrain_control.ocean_reclaim_requirement_pct,
2593 "parameters.ocean_reclaim_requirement");
2594 }
2595 if (terrain_control.land_channel_requirement_pct <= 100) {
2596 secfile_insert_int(sfile, terrain_control.land_channel_requirement_pct,
2597 "parameters.land_channel_requirement");
2598 }
2599 if (terrain_control.terrain_thaw_requirement_pct <= 100) {
2600 secfile_insert_int(sfile, terrain_control.terrain_thaw_requirement_pct,
2601 "parameters.thaw_requirement");
2602 }
2603 if (terrain_control.terrain_freeze_requirement_pct <= 100) {
2604 secfile_insert_int(sfile, terrain_control.terrain_freeze_requirement_pct,
2605 "parameters.freeze_requirement");
2606 }
2607 if (terrain_control.lake_max_size != 0) {
2608 secfile_insert_int(sfile, terrain_control.lake_max_size,
2609 "parameters.lake_max_size");
2610 }
2611 if (terrain_control.min_start_native_area != 0) {
2612 secfile_insert_int(sfile, terrain_control.min_start_native_area,
2613 "parameters.min_start_native_area");
2614 }
2615 if (terrain_control.move_fragments != 3) {
2616 secfile_insert_int(sfile, terrain_control.move_fragments,
2617 "parameters.move_fragments");
2618 }
2619 if (terrain_control.igter_cost != 1) {
2620 secfile_insert_int(sfile, terrain_control.igter_cost,
2621 "parameters.igter_cost");
2622 }
2623 if (terrain_control.pythagorean_diagonal != RS_DEFAULT_PYTHAGOREAN_DIAGONAL) {
2624 secfile_insert_bool(sfile, terrain_control.pythagorean_diagonal,
2625 "parameters.pythagorean_diagonal");
2626 }
2629 "parameters.ocean_resources");
2630 }
2631
2632 comment_terrains(sfile);
2633
2634 sect_idx = 0;
2636 char path[512];
2637 char identifier[2];
2638 int r;
2639 const char *flag_names[TER_USER_LAST];
2640 const char *puc_names[UCL_LAST];
2641 int flagi;
2642 int set_count;
2643
2644 fc_snprintf(path, sizeof(path), "terrain_%d", sect_idx++);
2645
2646 save_name_translation(sfile, &(pterr->name), path);
2647
2648 secfile_insert_str(sfile, pterr->graphic_str, "%s.graphic", path);
2649 secfile_insert_str(sfile, pterr->graphic_alt, "%s.graphic_alt", path);
2650 secfile_insert_str(sfile, pterr->graphic_alt2, "%s.graphic_alt2", path);
2651 identifier[0] = pterr->identifier;
2652 identifier[1] = '\0';
2653 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2654
2656 "%s.class", path);
2657
2658 secfile_insert_int(sfile, pterr->movement_cost, "%s.movement_cost", path);
2659 secfile_insert_int(sfile, pterr->defense_bonus, "%s.defense_bonus", path);
2660
2662 if (pterr->output[o] != 0) {
2663 secfile_insert_int(sfile, pterr->output[o], "%s.%s", path,
2665 }
2667
2668 /* Check resource count */
2669 for (r = 0; pterr->resources[r] != nullptr; r++) {
2670 /* Just increasing r as long as there are resources */
2671 }
2672
2673 {
2674 const char *resource_names[r];
2675 bool save_frequencies = FALSE;
2676
2677 r = 0;
2682 }
2684
2686 "%s.resources", path);
2687
2688 if (save_frequencies) {
2689 secfile_insert_int_vec(sfile, pterr->resource_freq, r,
2690 "%s.resource_freq", path);
2691 }
2692 }
2693
2695 if (pterr->road_output_incr_pct[o] != 0) {
2696 secfile_insert_int(sfile, pterr->road_output_incr_pct[o],
2697 "%s.road_%s_incr_pct", path,
2699 }
2701
2702 secfile_insert_int(sfile, pterr->base_time, "%s.base_time", path);
2703 secfile_insert_int(sfile, pterr->road_time, "%s.road_time", path);
2704
2705 save_terrain_ref(sfile, pterr->cultivate_result, pterr, path,
2706 "cultivate_result");
2707 secfile_insert_int(sfile, pterr->cultivate_time,
2708 "%s.cultivate_time", path);
2709
2710 save_terrain_ref(sfile, pterr->plant_result, pterr, path,
2711 "plant_result");
2712 secfile_insert_int(sfile, pterr->plant_time,
2713 "%s.plant_time", path);
2714
2715 secfile_insert_int(sfile, pterr->irrigation_food_incr,
2716 "%s.irrigation_food_incr", path);
2717 secfile_insert_int(sfile, pterr->irrigation_time,
2718 "%s.irrigation_time", path);
2719
2720 secfile_insert_int(sfile, pterr->mining_shield_incr,
2721 "%s.mining_shield_incr", path);
2722 secfile_insert_int(sfile, pterr->mining_time,
2723 "%s.mining_time", path);
2724
2725 save_terrain_ref(sfile, pterr->transform_result, pterr, path,
2726 "transform_result");
2727 secfile_insert_int(sfile, pterr->transform_time,
2728 "%s.transform_time", path);
2729
2730 if (pterr->num_animals > 0) {
2731 const char *animal_names[pterr->num_animals];
2732 int count = 0;
2733
2738 "%s.animals", path);
2739 }
2740
2741 secfile_insert_int(sfile, pterr->placing_time,
2742 "%s.placing_time", path);
2743 secfile_insert_int(sfile, pterr->pillage_time,
2744 "%s.pillage_time", path);
2745
2746 i = 0;
2747 extra_type_iterate(pextra) {
2748 int rmtime = pterr->extra_removal_times[extra_index(pextra)];
2749
2750 if (rmtime != 0) {
2751 secfile_insert_str(sfile, extra_rule_name(pextra),
2752 "%s.extra_settings%d.extra",
2753 path, i);
2755 "%s.extra_settings%d.removal_time",
2756 path, i++);
2757 }
2759
2760 save_terrain_ref(sfile, pterr->warmer_wetter_result, pterr, path,
2761 "warmer_wetter_result");
2762 save_terrain_ref(sfile, pterr->warmer_drier_result, pterr, path,
2763 "warmer_drier_result");
2764 save_terrain_ref(sfile, pterr->cooler_wetter_result, pterr, path,
2765 "cooler_wetter_result");
2766 save_terrain_ref(sfile, pterr->cooler_drier_result, pterr, path,
2767 "cooler_drier_result");
2768
2769 set_count = 0;
2770 for (flagi = 0; flagi < TER_USER_LAST; flagi++) {
2773 }
2774 }
2775
2776 if (set_count > 0) {
2778 "%s.flags", path);
2779 }
2780
2781 {
2783
2787 if (pterr->property[mtp] != 0) {
2788 secfile_insert_int(sfile, pterr->property[mtp],
2789 "%s.property_%s", path,
2791 }
2792 }
2793 }
2794
2795 set_count = 0;
2797 if (BV_ISSET(pterr->native_to, uclass_index(puc))) {
2799 }
2801
2802 if (set_count > 0) {
2804 "%s.native_to", path);
2805 }
2806
2807 rgbcolor_save(sfile, pterr->rgb, "%s.color", path);
2808
2809 save_helptext(sfile, pterr->helptext, path, "helptext");
2810
2812
2813 comment_resources(sfile);
2814
2815 sect_idx = 0;
2817 if (!pres->ruledit_disabled) {
2818 char path[512];
2819 char identifier[2];
2820
2821 fc_snprintf(path, sizeof(path), "resource_%d", sect_idx++);
2822
2824 "%s.extra", path);
2825
2827 if (pres->data.resource->output[o] != 0) {
2828 secfile_insert_int(sfile, pres->data.resource->output[o], "%s.%s",
2829 path, get_output_identifier(o));
2830 }
2832
2833 if (pres->data.resource->id_old_save != '\0') {
2834 identifier[0] = pres->data.resource->id_old_save;
2835 identifier[1] = '\0';
2836 secfile_insert_str(sfile, identifier, "%s.identifier", path);
2837 }
2838 }
2840
2841 {
2842 struct entry *pentry =
2843 secfile_insert_str(sfile, terrain_control.gui_type_base0,
2844 "extraui.ui_name_base_fortress");
2846 pentry = secfile_insert_str(sfile, terrain_control.gui_type_base1,
2847 "extraui.ui_name_base_airbase");
2849 }
2850
2851 comment_extras(sfile);
2852
2853 sect_idx = 0;
2855 char path[512];
2856 const char *flag_names[EF_COUNT];
2857 const char *cause_names[EC_COUNT];
2858 const char *puc_names[UCL_LAST];
2859 const char *extra_names[MAX_EXTRA_TYPES];
2860 int flagi;
2861 int causei;
2862 int set_count;
2863 bool worker_cause;
2864
2865 fc_snprintf(path, sizeof(path), "extra_%d", sect_idx++);
2866
2867 save_name_translation(sfile, &(pextra->name), path);
2868
2869 secfile_insert_str(sfile, extra_category_name(pextra->category),
2870 "%s.category", path);
2871
2872 set_count = 0;
2873 for (causei = 0; causei < EC_COUNT; causei++) {
2874 if (is_extra_caused_by(pextra, causei)) {
2876 }
2877 }
2878
2879 if (set_count > 0) {
2881 "%s.causes", path);
2882 }
2883
2884 set_count = 0;
2885 for (causei = 0; causei < ERM_COUNT; causei++) {
2886 if (is_extra_removed_by(pextra, causei)) {
2888 }
2889 }
2890
2891 if (set_count > 0) {
2893 "%s.rmcauses", path);
2894 }
2895
2896 if (strcmp(pextra->graphic_str, "-")) {
2897 secfile_insert_str(sfile, pextra->graphic_str, "%s.graphic", path);
2898 }
2899 if (strcmp(pextra->graphic_alt, "-")) {
2900 secfile_insert_str(sfile, pextra->graphic_alt, "%s.graphic_alt", path);
2901 }
2902 if (strcmp(pextra->activity_gfx, "-")) {
2903 secfile_insert_str(sfile, pextra->activity_gfx, "%s.activity_gfx", path);
2904 }
2905 if (strcmp(pextra->act_gfx_alt, "-")) {
2906 secfile_insert_str(sfile, pextra->act_gfx_alt, "%s.act_gfx_alt", path);
2907 }
2908 if (strcmp(pextra->act_gfx_alt2, "-")) {
2909 secfile_insert_str(sfile, pextra->act_gfx_alt2, "%s.act_gfx_alt2", path);
2910 }
2911 if (strcmp(pextra->rmact_gfx, "-")) {
2912 secfile_insert_str(sfile, pextra->rmact_gfx, "%s.rmact_gfx", path);
2913 }
2914 if (strcmp(pextra->rmact_gfx_alt, "-")) {
2915 secfile_insert_str(sfile, pextra->rmact_gfx_alt, "%s.rmact_gfx_alt", path);
2916 }
2917
2918 save_reqs_vector(sfile, &(pextra->reqs), path, "reqs");
2919 save_reqs_vector(sfile, &(pextra->rmreqs), path, "rmreqs");
2920 save_reqs_vector(sfile, &(pextra->appearance_reqs), path, "appearance_reqs");
2921 save_reqs_vector(sfile, &(pextra->disappearance_reqs), path, "disappearance_reqs");
2922
2924 if ((!pextra->buildable && worker_cause)
2925 || (pextra->buildable && !worker_cause)) {
2926 secfile_insert_bool(sfile, pextra->buildable, "%s.buildable", path);
2927 }
2928 if (!pextra->generated) {
2929 secfile_insert_bool(sfile, pextra->generated, "%s.generated", path);
2930 }
2931 secfile_insert_int(sfile, pextra->build_time, "%s.build_time", path);
2932 secfile_insert_int(sfile, pextra->removal_time, "%s.removal_time", path);
2933 if (pextra->build_time_factor != 1) {
2934 secfile_insert_int(sfile, pextra->build_time_factor, "%s.build_time_factor", path);
2935 }
2936 if (pextra->removal_time_factor != 1) {
2937 secfile_insert_int(sfile, pextra->removal_time_factor, "%s.removal_time_factor", path);
2938 }
2939 if (pextra->infracost != 0) {
2940 secfile_insert_int(sfile, pextra->infracost, "%s.infracost", path);
2941 }
2942 if (pextra->defense_bonus != 0) {
2943 secfile_insert_int(sfile, pextra->defense_bonus, "%s.defense_bonus", path);
2944 }
2945 if (pextra->eus != EUS_NORMAL) {
2947 "%s.unit_seen", path);
2948 }
2950 && pextra->appearance_chance != RS_DEFAULT_EXTRA_APPEARANCE) {
2951 secfile_insert_int(sfile, pextra->appearance_chance, "%s.appearance_chance", path);
2952 }
2954 && pextra->disappearance_chance != RS_DEFAULT_EXTRA_DISAPPEARANCE) {
2955 secfile_insert_int(sfile, pextra->disappearance_chance, "%s.disappearance_chance",
2956 path);
2957 }
2958
2959 set_count = 0;
2961 if (BV_ISSET(pextra->native_to, uclass_index(puc))) {
2963 }
2965
2966 if (set_count > 0) {
2968 "%s.native_to", path);
2969 }
2970
2971 if (pextra->no_aggr_near_city >= 0) {
2972 secfile_insert_int(sfile, pextra->no_aggr_near_city,
2973 "%s.no_aggr_near_city", path);
2974 }
2975
2976 set_count = 0;
2977 for (flagi = 0; flagi < EF_COUNT; flagi++) {
2978 if (extra_has_flag(pextra, flagi)) {
2980 }
2981 }
2982
2983 if (set_count > 0) {
2985 "%s.flags", path);
2986 }
2987
2988 set_count = 0;
2990 if (!can_extras_coexist(pextra, confl)) {
2992 }
2994
2995 if (set_count > 0) {
2997 "%s.conflicts", path);
2998 }
2999
3000 set_count = 0;
3001 extra_type_iterate(top) {
3002 if (BV_ISSET(pextra->hidden_by, extra_index(top))) {
3004 }
3006
3007 if (set_count > 0) {
3009 "%s.hidden_by", path);
3010 }
3011
3012 set_count = 0;
3013 extra_type_iterate(top) {
3014 if (BV_ISSET(pextra->bridged_over, extra_index(top))) {
3016 }
3018
3019 if (set_count > 0) {
3021 "%s.bridged_over", path);
3022 }
3023
3024 save_helptext(sfile, pextra->helptext, path, "helptext");
3025
3027
3028 comment_bases(sfile);
3029
3030 sect_idx = 0;
3032 if (!pextra->ruledit_disabled) {
3033 char path[512];
3034 struct base_type *pbase = extra_base_get(pextra);
3035
3036 fc_snprintf(path, sizeof(path), "base_%d", sect_idx++);
3037
3038 secfile_insert_str(sfile, extra_rule_name(pextra),
3039 "%s.extra", path);
3040
3042 "%s.gui_type", path);
3043
3044 if (pbase->border_sq >= 0) {
3045 secfile_insert_int(sfile, pbase->border_sq, "%s.border_sq", path);
3046 }
3047 if (pbase->vision_main_sq >= 0) {
3048 secfile_insert_int(sfile, pbase->vision_main_sq, "%s.vision_main_sq", path);
3049 }
3050 if (pbase->vision_invis_sq >= 0) {
3051 secfile_insert_int(sfile, pbase->vision_invis_sq, "%s.vision_invis_sq", path);
3052 }
3053 if (pbase->vision_subs_sq >= 0) {
3054 secfile_insert_int(sfile, pbase->vision_subs_sq, "%s.vision_subs_sq", path);
3055 }
3056 }
3058
3059 comment_roads(sfile);
3060
3061 sect_idx = 0;
3063 if (!pextra->ruledit_disabled) {
3064 struct road_type *proad = extra_road_get(pextra);
3065 char path[512];
3066 const char *flag_names[RF_COUNT];
3067 int flagi;
3068 int set_count;
3069
3070 fc_snprintf(path, sizeof(path), "road_%d", sect_idx++);
3071
3072 secfile_insert_str(sfile, extra_rule_name(pextra),
3073 "%s.extra", path);
3074
3075 save_reqs_vector(sfile, &(proad->first_reqs), path, "first_reqs");
3076
3077 secfile_insert_int(sfile, proad->move_cost, "%s.move_cost", path);
3078
3079 if (proad->move_mode != RMM_FAST_ALWAYS) {
3080 secfile_insert_str(sfile, road_move_mode_name(proad->move_mode),
3081 "%s.move_mode", path);
3082 }
3083
3085 if (proad->tile_incr_const[o] != 0) {
3086 secfile_insert_int(sfile, proad->tile_incr_const[o],
3087 "%s.%s_incr_const", path, get_output_identifier(o));
3088 }
3089 if (proad->tile_incr[o] != 0) {
3090 secfile_insert_int(sfile, proad->tile_incr[o],
3091 "%s.%s_incr", path, get_output_identifier(o));
3092 }
3093 if (proad->tile_bonus[o] != 0) {
3094 secfile_insert_int(sfile, proad->tile_bonus[o],
3095 "%s.%s_bonus", path, get_output_identifier(o));
3096 }
3098
3099 switch (proad->compat) {
3100 case ROCO_ROAD:
3101 secfile_insert_str(sfile, "Road", "%s.compat_special", path);
3102 break;
3103 case ROCO_RAILROAD:
3104 secfile_insert_str(sfile, "Railroad", "%s.compat_special", path);
3105 break;
3106 case ROCO_RIVER:
3107 secfile_insert_str(sfile, "River", "%s.compat_special", path);
3108 break;
3109 case ROCO_NONE:
3110 secfile_insert_str(sfile, "None", "%s.compat_special", path);
3111 break;
3112 }
3113
3115 "%s.gui_type", path);
3116
3117 set_count = 0;
3118 for (flagi = 0; flagi < RF_COUNT; flagi++) {
3119 if (road_has_flag(proad, flagi)) {
3121 }
3122 }
3123
3124 if (set_count > 0) {
3126 "%s.flags", path);
3127 }
3128
3129 if (extra_type_list_size(proad->integrators) > 0) {
3130 const char *integrate_names[extra_type_list_size(proad->integrators)];
3131
3132 set_count = 0;
3133 extra_type_list_iterate(proad->integrators, iextra) {
3134 if (iextra != pextra) {
3136 }
3138
3139 if (set_count > 0) {
3141 "%s.integrates", path);
3142 }
3143 }
3144 }
3146
3147 comment_tiledefs(sfile);
3148
3149 sect_idx = 0;
3151 char path[512];
3152 const char *extra_names[MAX_EXTRA_TYPES];
3153 int set_count;
3154
3155 fc_snprintf(path, sizeof(path), "tiledef_%d", sect_idx++);
3156
3157 save_name_translation(sfile, &(td->name), path);
3158
3159 set_count = 0;
3160 extra_type_list_iterate(td->extras, pextra) {
3163
3164 if (set_count > 0) {
3166 "%s.extras", path);
3167 }
3168
3169 if (td->known) {
3170 secfile_insert_bool(sfile, td->known, "%s.known", path);
3171 }
3172 if (td->owned) {
3173 secfile_insert_bool(sfile, td->owned, "%s.owned", path);
3174 }
3176
3177 return save_ruleset_file(sfile, filename);
3178}
3179
3180/**********************************************************************/
3183static bool save_veteran_system(struct section_file *sfile, const char *path,
3184 struct veteran_system *vsystem)
3185{
3186 const char *vlist_name[vsystem->levels];
3187 int vlist_power[vsystem->levels];
3188 int vlist_raise[vsystem->levels];
3189 int vlist_wraise[vsystem->levels];
3190 int vlist_move[vsystem->levels];
3191 int i;
3192
3193 for (i = 0; i < vsystem->levels; i++) {
3194 vlist_name[i] = rule_name_get(&(vsystem->definitions[i].name));
3195 vlist_power[i] = vsystem->definitions[i].power_fact;
3196 vlist_raise[i] = vsystem->definitions[i].base_raise_chance;
3197 vlist_wraise[i] = vsystem->definitions[i].work_raise_chance;
3198 vlist_move[i] = vsystem->definitions[i].move_bonus;
3199 }
3200
3202 "%s.veteran_names", path);
3204 "%s.veteran_power_fact", path);
3206 "%s.veteran_base_raise_chance", path);
3208 "%s.veteran_work_raise_chance", path);
3210 "%s.veteran_move_bonus", path);
3211
3212 return TRUE;
3213}
3214
3215/**********************************************************************/
3218static bool save_combat_bonuses(struct section_file *sfile,
3219 struct unit_type *put,
3220 char *path)
3221{
3222 int i;
3223 bool has_quiet = FALSE;
3224
3226 if (pbonus->quiet) {
3227 has_quiet = TRUE;
3228 }
3230
3231 i = 0;
3232
3235 "%s.bonuses%d.flag", path, i);
3237 "%s.bonuses%d.type", path, i);
3238 secfile_insert_int(sfile, pbonus->value,
3239 "%s.bonuses%d.value", path, i);
3240
3241 if (has_quiet) {
3242 secfile_insert_bool(sfile, pbonus->quiet,
3243 "%s.bonuses%d.quiet", path, i);
3244 }
3245
3246 i++;
3248
3249 return TRUE;
3250}
3251
3252/**********************************************************************/
3255static bool save_units_ruleset(const char *filename, const char *name)
3256{
3257 struct section_file *sfile = create_ruleset_file(name, "unit");
3258 int i;
3259 int sect_idx;
3260 bool uflags_utype = FALSE;
3261 bool uflags_uclass = FALSE;
3262
3263 if (sfile == nullptr) {
3264 return FALSE;
3265 }
3266
3267 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
3269 const char *helptxt = unit_type_flag_helptxt(i + UTYF_USER_FLAG_1);
3270 struct entry *pentry;
3271
3272 if (flagname != nullptr) {
3273 if (!uflags_utype) {
3274 comment_uflags_utype(sfile);
3276 }
3277
3279 "control.flags%d.name", i);
3281
3282 /* Save the user flag help text even when it is undefined. That makes
3283 * the formatting code happy. The resulting "" is ignored when the
3284 * ruleset is loaded. */
3285 pentry = secfile_insert_str(sfile, helptxt,
3286 "control.flags%d.helptxt", i);
3288 }
3289 }
3290
3291 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
3293 const char *helptxt = unit_class_flag_helptxt(i + UCF_USER_FLAG_1);
3294 struct entry *pentry;
3295
3296 if (flagname != nullptr) {
3297 if (!uflags_uclass) {
3298 /* TODO: Uncomment this, once there's a way to stop
3299 * the comment getting written inside preceding
3300 * utype flags table. */
3301 /* comment_uflags_uclass(sfile); */
3303 }
3304
3306 "control.class_flags%d.name", i);
3308
3309 /* Save the user flag help text even when it is undefined. That makes
3310 * the formatting code happy. The resulting "" is ignored when the
3311 * ruleset is loaded. */
3312 pentry = secfile_insert_str(sfile, helptxt,
3313 "control.class_flags%d.helptxt", i);
3315 }
3316 }
3317
3318 save_veteran_system(sfile, "veteran_system", game.veteran);
3319
3320 comment_uclasses(sfile);
3321
3322 sect_idx = 0;
3324 char path[512];
3325 const char *flag_names[UCF_COUNT];
3326 int flagi;
3327 int set_count;
3328
3329 fc_snprintf(path, sizeof(path), "unitclass_%d", sect_idx++);
3330
3331 save_name_translation(sfile, &(puc->name), path);
3332
3333 secfile_insert_int(sfile, puc->min_speed / SINGLE_MOVE,
3334 "%s.min_speed", path);
3335 secfile_insert_int(sfile, puc->hp_loss_pct, "%s.hp_loss_pct", path);
3336 if (puc->non_native_def_pct != 100) {
3337 secfile_insert_int(sfile, puc->non_native_def_pct,
3338 "%s.non_native_def_pct", path);
3339 }
3340
3341 set_count = 0;
3342 for (flagi = 0; flagi < UCF_COUNT; flagi++) {
3343 if (uclass_has_flag(puc, flagi)) {
3345 }
3346 }
3347
3348 if (set_count > 0) {
3350 "%s.flags", path);
3351 }
3352
3353 save_helptext(sfile, puc->helptext, path, "helptext");
3354
3356
3357 comment_utypes(sfile);
3358
3359 sect_idx = 0;
3361 if (!put->ruledit_disabled) {
3362 char path[512];
3363 const char *flag_names[UTYF_LAST_USER_FLAG + 1];
3364 int flagi;
3365 int set_count;
3366
3367 fc_snprintf(path, sizeof(path), "unit_%d", sect_idx++);
3368
3369 save_name_translation(sfile, &(put->name), path);
3370
3371 secfile_insert_str(sfile, uclass_rule_name(put->uclass),
3372 "%s.class", path);
3373
3374 save_reqs_vector(sfile, &(put->build_reqs), path, "reqs");
3375
3376 if (put->obsoleted_by != nullptr) {
3377 secfile_insert_str(sfile, utype_rule_name(put->obsoleted_by),
3378 "%s.obsolete_by", path);
3379 }
3380
3381 secfile_insert_str(sfile, put->graphic_str, "%s.graphic", path);
3382 if (strcmp("-", put->graphic_alt)) {
3383 secfile_insert_str(sfile, put->graphic_alt, "%s.graphic_alt", path);
3384 }
3385 if (strcmp("-", put->graphic_alt2)) {
3386 secfile_insert_str(sfile, put->graphic_alt2, "%s.graphic_alt2", path);
3387 }
3388 if (strcmp("-", put->sound_move)) {
3389 secfile_insert_str(sfile, put->sound_move, "%s.sound_move", path);
3390 }
3391 if (strcmp("-", put->sound_move_alt)) {
3392 secfile_insert_str(sfile, put->sound_move_alt, "%s.sound_move_alt", path);
3393 }
3394 if (strcmp("-", put->sound_fight)) {
3395 secfile_insert_str(sfile, put->sound_fight, "%s.sound_fight", path);
3396 }
3397 if (strcmp("-", put->sound_fight_alt)) {
3398 secfile_insert_str(sfile, put->sound_fight_alt, "%s.sound_fight_alt", path);
3399 }
3400
3401 secfile_insert_int(sfile, put->build_cost, "%s.build_cost", path);
3402 secfile_insert_int(sfile, put->pop_cost, "%s.pop_cost", path);
3403 if (DEFAULT_SPECIALIST < 0 || (nullptr != put->spec_type)) {
3404 secfile_insert_str(sfile, specialist_rule_name(put->spec_type),
3405 "%s.specialist", path);
3406 }
3407 secfile_insert_int(sfile, put->attack_strength, "%s.attack", path);
3408 secfile_insert_int(sfile, put->defense_strength, "%s.defense", path);
3409 secfile_insert_int(sfile, put->move_rate / SINGLE_MOVE, "%s.move_rate", path);
3410 secfile_insert_int(sfile, put->vision_radius_sq, "%s.vision_radius_sq", path);
3411 secfile_insert_int(sfile, put->transport_capacity, "%s.transport_cap", path);
3412
3413 save_uclass_vec(sfile, &(put->cargo), path, "cargo", FALSE);
3414 save_uclass_vec(sfile, &(put->embarks), path, "embarks", TRUE);
3415 save_uclass_vec(sfile, &(put->disembarks), path, "disembarks", TRUE);
3416
3417 if (put->vlayer != V_MAIN) {
3419 "%s.vision_layer", path);
3420 }
3421
3422 secfile_insert_int(sfile, put->hp, "%s.hitpoints", path);
3423 secfile_insert_int(sfile, put->firepower, "%s.firepower", path);
3424 secfile_insert_int(sfile, put->fuel, "%s.fuel", path);
3425 secfile_insert_int(sfile, put->happy_cost, "%s.uk_happy", path);
3426
3428 if (put->upkeep[o] != 0) {
3429 secfile_insert_int(sfile, put->upkeep[o], "%s.uk_%s",
3430 path, get_output_identifier(o));
3431 }
3433
3434 if (put->converted_to != nullptr) {
3435 secfile_insert_str(sfile, utype_rule_name(put->converted_to),
3436 "%s.convert_to", path);
3437 }
3438 if (put->convert_time != 1) {
3439 secfile_insert_int(sfile, put->convert_time, "%s.convert_time", path);
3440 }
3441
3442 save_combat_bonuses(sfile, put, path);
3443 save_uclass_vec(sfile, &(put->targets), path, "targets", TRUE);
3444
3445 if (put->veteran != nullptr) {
3446 save_veteran_system(sfile, path, put->veteran);
3447 }
3448
3449 if (put->paratroopers_range != 0) {
3450 secfile_insert_int(sfile, put->paratroopers_range,
3451 "%s.paratroopers_range", path);
3452 }
3453 if (put->bombard_rate != 0) {
3454 secfile_insert_int(sfile, put->bombard_rate,
3455 "%s.bombard_rate", path);
3456 }
3457 if (put->city_slots != 0) {
3458 secfile_insert_int(sfile, put->city_slots,
3459 "%s.city_slots", path);
3460 }
3461 if (put->city_size != 1) {
3462 secfile_insert_int(sfile, put->city_size,
3463 "%s.city_size", path);
3464 }
3465
3466 secfile_insert_str(sfile, transp_def_type_name(put->tp_defense),
3467 "%s.tp_defense", path);
3468
3469 set_count = 0;
3470 for (flagi = 0; flagi <= UTYF_LAST_USER_FLAG; flagi++) {
3471 if (utype_has_flag(put, flagi)) {
3473 }
3474 }
3475
3476 if (set_count > 0) {
3478 "%s.flags", path);
3479 }
3480
3481 set_count = 0;
3482 for (flagi = L_FIRST; flagi < L_LAST; flagi++) {
3483 if (utype_has_role(put, flagi)) {
3485 }
3486 }
3487
3488 if (set_count > 0) {
3490 "%s.roles", path);
3491 }
3492
3493 save_helptext(sfile, put->helptext, path, "helptext");
3494 }
3496
3497 return save_ruleset_file(sfile, filename);
3498}
3499
3500/**********************************************************************/
3503static bool save_script_lua(const char *filename, const char *name,
3504 const char *buffer)
3505{
3506 if (buffer != nullptr) {
3507 FILE *ffile = fc_fopen(filename, "w");
3508 int full_len = strlen(buffer);
3509 int len;
3510
3511 if (ffile != nullptr) {
3512 len = fwrite(buffer, 1, full_len, ffile);
3513
3514 if (len != full_len) {
3515 return FALSE;
3516 }
3517
3518 fclose(ffile);
3519 } else {
3520 return FALSE;
3521 }
3522 }
3523
3524 return TRUE;
3525}
3526
3527/**********************************************************************/
3530static bool save_luadata(const char *filename)
3531{
3532 if (game.server.luadata != nullptr) {
3533 return secfile_save(game.server.luadata, filename, 0, FZ_PLAIN, FALSE);
3534 }
3535
3536 return TRUE;
3537}
3538
3539/**********************************************************************/
3542bool save_ruleset(const char *path, const char *name, struct rule_data *data)
3543{
3544 if (make_dir(path, DIRMODE_DEFAULT)) {
3545 bool success = TRUE;
3546 char filename[500];
3547
3548 if (success) {
3549 fc_snprintf(filename, sizeof(filename), "%s/buildings.ruleset", path);
3550 success = save_buildings_ruleset(filename, name);
3551 }
3552
3553 if (success) {
3554 fc_snprintf(filename, sizeof(filename), "%s/styles.ruleset", path);
3555 success = save_styles_ruleset(filename, name);
3556 }
3557
3558 if (success) {
3559 fc_snprintf(filename, sizeof(filename), "%s/cities.ruleset", path);
3560 success = save_cities_ruleset(filename, name);
3561 }
3562
3563 if (success) {
3564 fc_snprintf(filename, sizeof(filename), "%s/effects.ruleset", path);
3565 success = save_effects_ruleset(filename, name);
3566 }
3567
3568 if (success) {
3569 fc_snprintf(filename, sizeof(filename), "%s/game.ruleset", path);
3570 success = save_game_ruleset(filename, name);
3571 }
3572
3573 if (success) {
3574 fc_snprintf(filename, sizeof(filename), "%s/governments.ruleset", path);
3576 }
3577
3578 if (success) {
3579 fc_snprintf(filename, sizeof(filename), "%s/nations.ruleset", path);
3580 success = save_nations_ruleset(filename, name, data);
3581 }
3582
3583 if (success) {
3584 fc_snprintf(filename, sizeof(filename), "%s/techs.ruleset", path);
3585 success = save_techs_ruleset(filename, name);
3586 }
3587
3588 if (success) {
3589 fc_snprintf(filename, sizeof(filename), "%s/terrain.ruleset", path);
3590 success = save_terrain_ruleset(filename, name);
3591 }
3592
3593 if (success) {
3594 fc_snprintf(filename, sizeof(filename), "%s/units.ruleset", path);
3595 success = save_units_ruleset(filename, name);
3596 }
3597
3598 if (success) {
3599 fc_snprintf(filename,sizeof(filename), "%s/actions.ruleset",path);
3600 success = save_actions_ruleset(filename, name);
3601 }
3602
3603 if (success) {
3604 fc_snprintf(filename, sizeof(filename), "%s/script.lua", path);
3606 }
3607
3608 if (success) {
3609 fc_snprintf(filename, sizeof(filename), "%s/parser.lua", path);
3611 }
3612
3613 if (success) {
3614 fc_snprintf(filename, sizeof(filename), "%s/luadata.txt", path);
3615 success = save_luadata(filename);
3616 }
3617
3618 return success;
3619 } else {
3620 log_error(_("Failed to create directory %s"), path);
3621 return FALSE;
3622 }
3623
3624 return TRUE;
3625}
const struct unit_type * access_info_access_unit(void)
Definition accessarea.c:71
#define achievements_iterate_end
#define achievements_iterate(_ach_)
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:6420
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7143
void action_array_end(action_id *act_array, int size)
Definition actions.c:6014
bool action_is_in_use(struct action *paction)
Definition actions.c:5920
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7340
const char * action_rule_name(const struct action *action)
Definition actions.c:1242
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:6967
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:6601
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:6792
const char * action_ui_name_default(int act)
Definition actions.c:6049
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:5982
bool action_id_is_internal(action_id act)
Definition actions.c:5958
#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:380
int actres_max_range_default(enum action_result result)
Definition actres.c:471
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:853
#define output_type_iterate_end
Definition city.h:859
char * uflags_government
Definition comments.c:55
void comment_borders_radius_permanent(struct section_file *sfile)
Definition comments.c:824
char * uflags_building
Definition comments.c:54
void comment_uflags_utype(struct section_file *sfile)
Definition comments.c:482
void comment_world_peace_turns(struct section_file *sfile)
Definition comments.c:905
void comment_combat_rules_nuke_defender_survival(struct section_file *sfile)
Definition comments.c:788
void comment_roads(struct section_file *sfile)
Definition comments.c:410
void comment_civstyle_granary(struct section_file *sfile)
Definition comments.c:627
void comment_research_tech_leakage(struct section_file *sfile)
Definition comments.c:860
void comment_uclasses(struct section_file *sfile)
Definition comments.c:362
void comment_calendar_fragments(struct section_file *sfile)
Definition comments.c:914
void comment_actions_quiet_actions(struct section_file *sfile)
Definition comments.c:815
void comment_uflags_terrain(struct section_file *sfile)
Definition comments.c:498
void comment_combat_rules_low_fp_pearl_harbor(struct section_file *sfile)
Definition comments.c:749
void comment_citystyles(struct section_file *sfile)
Definition comments.c:434
void comment_std_tileset_compat(struct section_file *sfile)
Definition comments.c:924
void comment_govs(struct section_file *sfile)
Definition comments.c:346
void comment_tiledefs(struct section_file *sfile)
Definition comments.c:418
void comment_research_base_tech_cost(struct section_file *sfile)
Definition comments.c:842
void comment_research_tech_cost_style(struct section_file *sfile)
Definition comments.c:833
void comment_combat_rules_only_killing_veteran(struct section_file *sfile)
Definition comments.c:699
void comment_bases(struct section_file *sfile)
Definition comments.c:402
void comment_terrains(struct section_file *sfile)
Definition comments.c:378
void comment_uflags_tech(struct section_file *sfile)
Definition comments.c:514
void comment_file_header(struct section_file *sfile)
Definition comments.c:314
void comment_effects(struct section_file *sfile)
Definition comments.c:450
void comment_actions_dc_initial_odds(struct section_file *sfile)
Definition comments.c:806
void comment_combat_rules_scaled_veterancy(struct section_file *sfile)
Definition comments.c:719
void comment_research_upkeep_style(struct section_file *sfile)
Definition comments.c:869
void comment_disasters(struct section_file *sfile)
Definition comments.c:466
void comment_clauses(struct section_file *sfile)
Definition comments.c:602
void comment_goods(struct section_file *sfile)
Definition comments.c:546
char * uflags_tech
Definition comments.c:53
void comment_civstyle_gameloss_style(struct section_file *sfile)
Definition comments.c:645
char * uflags_extra
Definition comments.c:52
void comment_civstyle_gold_upkeep_style(struct section_file *sfile)
Definition comments.c:654
void comment_extras(struct section_file *sfile)
Definition comments.c:394
void comment_uflags_government(struct section_file *sfile)
Definition comments.c:530
void comment_combat_rules_low_fp_nonnat_bombard(struct section_file *sfile)
Definition comments.c:769
void comment_ueffs(struct section_file *sfile)
Definition comments.c:458
void comment_techs(struct section_file *sfile)
Definition comments.c:338
void comment_nations(struct section_file *sfile)
Definition comments.c:578
void comment_trade_settings(struct section_file *sfile)
Definition comments.c:538
void comment_combat_rules_low_fp_combat_bonus(struct section_file *sfile)
Definition comments.c:759
void comment_nations_ruledit(struct section_file *sfile)
Definition comments.c:619
void comment_nationgroups(struct section_file *sfile)
Definition comments.c:586
void comment_specialists(struct section_file *sfile)
Definition comments.c:570
void comment_musicstyles(struct section_file *sfile)
Definition comments.c:442
void comment_civstyle_airlift_always(struct section_file *sfile)
Definition comments.c:663
void comment_resources(struct section_file *sfile)
Definition comments.c:386
void comment_civstyle_ransom_gold(struct section_file *sfile)
Definition comments.c:636
void comment_tech_classes(struct section_file *sfile)
Definition comments.c:330
void comment_culture_migration_pml(struct section_file *sfile)
Definition comments.c:896
void comment_combat_rules_only_real_fight_veteran(struct section_file *sfile)
Definition comments.c:709
char * uflags_uclass
Definition comments.c:50
void comment_research_free_tech_method(struct section_file *sfile)
Definition comments.c:878
void comment_combat_rules_nuke_pop_loss(struct section_file *sfile)
Definition comments.c:779
void comment_utypes(struct section_file *sfile)
Definition comments.c:370
char * uflags_utype
Definition comments.c:49
void comment_research_min_tech_cost(struct section_file *sfile)
Definition comments.c:851
void comment_culture_history_interest(struct section_file *sfile)
Definition comments.c:887
void comment_policies(struct section_file *sfile)
Definition comments.c:354
void comment_combat_rules_low_fp_badwallattacker(struct section_file *sfile)
Definition comments.c:739
void comment_achievements(struct section_file *sfile)
Definition comments.c:474
void comment_combat_rules_damage_reduces_bombard_rate(struct section_file *sfile)
Definition comments.c:729
void comment_actions(struct section_file *sfile)
Definition comments.c:554
void comment_counters(struct section_file *sfile)
Definition comments.c:610
void comment_styles(struct section_file *sfile)
Definition comments.c:426
void comment_combat_rules_tired_attack(struct section_file *sfile)
Definition comments.c:690
void comment_uflags_building(struct section_file *sfile)
Definition comments.c:522
void comment_buildings(struct section_file *sfile)
Definition comments.c:322
void comment_enablers(struct section_file *sfile)
Definition comments.c:562
void comment_nationsets(struct section_file *sfile)
Definition comments.c:594
void comment_wonder_visibility_small_wonders(struct section_file *sfile)
Definition comments.c:672
void comment_incite_cost(struct section_file *sfile)
Definition comments.c:681
void comment_auto_attack(struct section_file *sfile)
Definition comments.c:798
char * incite_cost
Definition comments.c:77
#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:1329
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1365
#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:493
@ ROCO_RAILROAD
Definition fc_types.h:948
@ ROCO_NONE
Definition fc_types.h:948
@ ROCO_RIVER
Definition fc_types.h:948
@ ROCO_ROAD
Definition fc_types.h:948
#define MAX_NUM_NATION_SETS
Definition fc_types.h:58
#define MAX_NUM_BUILDING_LIST
Definition fc_types.h:46
int action_id
Definition fc_types.h:250
#define MAX_CALENDAR_FRAGMENTS
Definition fc_types.h:63
#define MAX_NUM_NATION_GROUPS
Definition fc_types.h:59
#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:68
#define MAX_NUM_TECH_LIST
Definition fc_types.h:44
#define UCL_LAST
Definition fc_types.h:276
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:62
struct world wld
Definition game.c:63
#define RS_DEFAULT_RANSOM_GOLD
Definition game.h:882
#define RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
Definition game.h:874
#define RS_DEFAULT_NUKE_POP_LOSS_PCT
Definition game.h:871
#define RS_DEFAULT_BASE_POLLUTION
Definition game.h:857
#define RS_DEFAULT_INCITE_TOTAL_FCT
Definition game.h:830
#define RS_DEFAULT_ILLNESS_BASE_FACTOR
Definition game.h:788
#define RS_DEFAULT_NEG_YEAR_LABEL
Definition game.h:784
#define RS_DEFAULT_INCITE_IMPROVEMENT_FCT
Definition game.h:822
#define RS_ACTION_NO_MAX_DISTANCE
Definition game.h:910
#define RS_DEFAULT_BASE_BRIBE_COST
Definition game.h:878
#define RS_DEFAULT_TECH_UPKEEP_DIVIDER
Definition game.h:892
#define RS_DEFAULT_HAPPY_COST
Definition game.h:862
#define RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
Definition game.h:900
#define RS_DEFAULT_GRANARY_FOOD_INC
Definition game.h:836
#define RS_DEFAULT_ILLNESS_ON
Definition game.h:786
#define GAME_DEFAULT_CELEBRATESIZE
Definition game.h:507
#define RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
Definition game.h:901
#define RS_DEFAULT_UPGRADE_VETERAN_LOSS
Definition game.h:888
#define RS_DEFAULT_CALENDAR_SKIP_0
Definition game.h:804
#define RS_DEFAULT_CITY_RADIUS_SQ
Definition game.h:849
#define GAME_DEFAULT_START_YEAR
Definition game.h:756
#define RS_DEFAULT_BORDER_SIZE_EFFECT
Definition game.h:810
#define RS_DEFAULT_PILLAGE_SELECT
Definition game.h:886
#define RS_DEFAULT_POS_YEAR_LABEL
Definition game.h:782
#define RS_DEFAULT_VIS_RADIUS_SQ
Definition game.h:853
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
Definition game.h:814
#define RS_DEFAULT_TIRED_ATTACK
Definition game.h:870
#define RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
Definition game.h:902
#define RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
Definition game.h:796
#define RS_DEFAULT_FOOD_COST
Definition game.h:866
#define RS_DEFAULT_INCITE_UNIT_FCT
Definition game.h:826
#define RS_DEFAULT_INCITE_BASE_COST
Definition game.h:818
#define GAME_DEFAULT_ANGRYCITIZEN
Definition game.h:398
#define RS_DEFAULT_CITY_CENTER_OUTPUT
Definition game.h:840
#define RS_DEFAULT_ILLNESS_POLLUTION_PCT
Definition game.h:800
#define RS_DEFAULT_ILLNESS_MIN_SIZE
Definition game.h:792
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY
Definition game.h:806
const char * gov_flag_id_name_cb(enum gov_flag_id flag)
Definition government.c:649
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:390
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Definition government.c:381
const char * gov_flag_helptxt(enum gov_flag_id id)
Definition government.c:661
const char * government_rule_name(const struct government *pgovern)
Definition government.c:132
#define governments_iterate(NAME_pgov)
Definition government.h:136
#define governments_re_active_iterate(_p)
Definition government.h:141
#define governments_re_active_iterate_end
Definition government.h:145
#define governments_iterate_end
Definition government.h:139
#define MAX_NUM_USER_GOVERNMENT_FLAGS
Definition government.h:29
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:416
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:295
enum nation_city_preference nation_city_terrain_preference(const struct nation_city *pncity, const struct terrain *pterrain)
Definition nation.c:425
const char * nation_group_rule_name(const struct nation_group *pgroup)
Definition nation.c:1071
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:1088
bool nation_is_in_set(const struct nation_type *pnation, const struct nation_set *pset)
Definition nation.c:832
const char * nation_set_description(const struct nation_set *pset)
Definition nation.c:824
enum nation_city_preference nation_city_river_preference(const struct nation_city *pncity)
Definition nation.c:435
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:287
const char * nation_set_rule_name(const struct nation_set *pset)
Definition nation.c:806
#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:333
#define nation_sets_iterate(NAME_pset)
Definition nation.h:329
#define nations_iterate_end
Definition nation.h:364
@ 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:361
#define nation_leader_list_iterate_end
Definition nation.h:59
#define nation_groups_iterate(NAME_pgroup)
Definition nation.h:339
#define nation_groups_iterate_end
Definition nation.h:343
int len
Definition packhand.c:129
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, bool do_formatting)
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:116
#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:417
char * get_parser_buffer(void)
Definition ruleload.c:576
char * get_script_buffer(void)
Definition ruleload.c:568
#define RS_DEFAULT_CONVERT_SPEED
Definition ruleload.h:122
#define RS_DEFAULT_UBUILD_NAT
Definition ruleload.h:121
#define RS_DEFAULT_DAMAGE_REDUCES_BOMBARD_RATE
Definition ruleload.h:108
#define RS_DEFAULT_WORLD_PEACE_TURNS
Definition ruleload.h:98
#define RS_DEFAULT_TECH_TRADE_LOSS_HOLES
Definition ruleload.h:83
#define RS_DEFAULT_EXTRA_APPEARANCE
Definition ruleload.h:102
#define RS_DEFAULT_TECH_PARASITE_HOLES
Definition ruleload.h:84
#define GAME_DEFAULT_ACH_VALUE
Definition ruleload.h:77
#define RS_DEFAULT_TECH_TRADE_HOLES
Definition ruleload.h:82
#define RS_DEFAULT_CULTURE_VIC_POINTS
Definition ruleload.h:93
#define RS_DEFAULT_CULTURE_MIGRATION_PML
Definition ruleload.h:95
#define RS_DEFAULT_SMALL_WONDER_VISIBILITY
Definition ruleload.h:110
#define RS_DEFAULT_ONLY_KILLING_VETERAN
Definition ruleload.h:105
#define RS_DEFAULT_TECH_LOSS_HOLES
Definition ruleload.h:85
#define RS_DEFAULT_HISTORY_INTEREST_PML
Definition ruleload.h:96
#define RS_DEFAULT_GOODS_SELECTION
Definition ruleload.h:100
#define RS_DEFAULT_PYTHAGOREAN_DIAGONAL
Definition ruleload.h:86
#define RS_DEFAULT_TECH_STEAL_HOLES
Definition ruleload.h:81
#define GAME_DEFAULT_ACH_UNIQUE
Definition ruleload.h:76
#define RS_DEFAULT_COMBAT_ODDS_SCALED_VETERANCY
Definition ruleload.h:107
#define RS_DEFAULT_MUUK_FOOD_WIPE
Definition ruleload.h:78
#define RS_DEFAULT_MUUK_GOLD_WIPE
Definition ruleload.h:79
#define RS_DEFAULT_BASE_TECH_COST
Definition ruleload.h:112
#define RULESET_CAPABILITIES
Definition ruleload.h:24
#define RS_DEFAULT_NATIONALITY
Definition ruleload.h:120
#define GAME_DEFAULT_CHANGABLE_TAX
Definition ruleload.h:73
#define RS_DEFAULT_MUUK_SHIELD_WIPE
Definition ruleload.h:80
#define RS_DEFAULT_GOLD_UPKEEP_STYLE
Definition ruleload.h:88
#define GAME_DEFAULT_ADDTOSIZE
Definition ruleload.h:72
#define RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN
Definition ruleload.h:106
#define RS_DEFAULT_EXTRA_DISAPPEARANCE
Definition ruleload.h:103
#define RS_DEFAULT_MIN_TECH_COST
Definition ruleload.h:116
#define GAME_DEFAULT_VISION_REVEAL_TILES
Definition ruleload.h:74
#define RS_DEFAULT_CULTURE_VIC_LEAD
Definition ruleload.h:94
#define GAME_DEFAULT_DISASTER_FREQ
Definition ruleload.h:75
static bool save_reqs_vector(struct section_file *sfile, const struct requirement_vector *reqs, const char *path, const char *entry)
Definition rulesave.c:152
static bool save_tech_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:212
static bool save_name_translation(struct section_file *sfile, struct name_translation *name, const char *path)
Definition rulesave.c:129
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:252
static bool save_unit_list(struct section_file *sfile, struct unit_type **input, const char *path, const char *entry)
Definition rulesave.c:309
static bool save_nations_ruleset(const char *filename, const char *name, struct rule_data *data)
Definition rulesave.c:2289
static bool save_action_kind(struct section_file *sfile, action_id act)
Definition rulesave.c:925
static bool save_action_actor_consuming_always(struct section_file *sfile, action_id act)
Definition rulesave.c:949
static bool save_action_max_range(struct section_file *sfile, action_id act)
Definition rulesave.c:879
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:2055
#define FORMAT_VERSION
Definition rulesave.c:58
bool save_ruleset(const char *path, const char *name, struct rule_data *data)
Definition rulesave.c:3542
static bool save_cities_ruleset(const char *filename, const char *name)
Definition rulesave.c:674
static bool save_techs_ruleset(const char *filename, const char *name)
Definition rulesave.c:2414
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:332
static bool save_action_post_success_force(struct section_file *sfile, int performer_slot, struct action *paction)
Definition rulesave.c:1027
static bool save_ruleset_file(struct section_file *sfile, const char *filename)
Definition rulesave.c:382
static bool save_veteran_system(struct section_file *sfile, const char *path, struct veteran_system *vsystem)
Definition rulesave.c:3183
static bool save_bv_actions(struct section_file *sfile, bv_actions content, const char *path)
Definition rulesave.c:1056
static bool save_default_bool(struct section_file *sfile, bool value, bool default_value, const char *path, const char *entry)
Definition rulesave.c:108
static bool effect_save(struct effect *peffect, void *data)
Definition rulesave.c:805
static bool save_game_ruleset(const char *filename, const char *name)
Definition rulesave.c:1268
static bool save_buildings_ruleset(const char *filename, const char *name)
Definition rulesave.c:390
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:550
static bool unexpected_non_otype(const struct requirement *req)
Definition rulesave.c:644
static bool save_building_list(struct section_file *sfile, int *input, const char *path, const char *entry)
Definition rulesave.c:285
static bool save_luadata(const char *filename)
Definition rulesave.c:3530
static bool save_governments_ruleset(const char *filename, const char *name)
Definition rulesave.c:1927
static bool save_action_blocked_by(struct section_file *sfile, struct action *paction)
Definition rulesave.c:974
static bool save_actions_ruleset(const char *filename, const char *name)
Definition rulesave.c:1089
static bool save_units_ruleset(const char *filename, const char *name)
Definition rulesave.c:3255
static bool save_terrain_ruleset(const char *filename, const char *name)
Definition rulesave.c:2528
static bool save_muuk_action_auto(struct section_file *sfile, const int aap, const char *item)
Definition rulesave.c:654
static bool save_action_range(struct section_file *sfile, action_id act)
Definition rulesave.c:899
static bool save_gov_ref(struct section_file *sfile, const struct government *gov, const char *path, const char *entry)
Definition rulesave.c:272
static bool save_styles_ruleset(const char *filename, const char *name)
Definition rulesave.c:486
static struct section_file * create_ruleset_file(const char *rsname, const char *rstype)
Definition rulesave.c:63
static bool save_combat_bonuses(struct section_file *sfile, struct unit_type *put, char *path)
Definition rulesave.c:3218
static bool save_effects_ruleset(const char *filename, const char *name)
Definition rulesave.c:835
static bool save_default_int(struct section_file *sfile, int value, int default_value, const char *path, const char *entry)
Definition rulesave.c:88
static bool save_helptext(struct section_file *sfile, struct strvec *to_save, const char *path, const char *entry)
Definition rulesave.c:359
static bool save_nation(struct section_file *sfile, struct nation_type *pnat, int sect_idx)
Definition rulesave.c:2101
static bool save_script_lua(const char *filename, const char *name, const char *buffer)
Definition rulesave.c:3503
static bool save_action_auto_actions(struct section_file *sfile, const int aap, const char *actions_path)
Definition rulesave.c:601
static bool save_tech_ref(struct section_file *sfile, const struct advance *padv, const char *path, const char *entry)
Definition rulesave.c:235
bool setting_ruleset_locked(const struct setting *pset)
Definition settings.c:4711
int setting_int_get(struct setting *pset)
Definition settings.c:3848
enum sset_type setting_type(const struct setting *pset)
Definition settings.c:3422
const char * setting_enum_secfile_str(secfile_data_t data, int val)
Definition settings.c:3930
enum setting_default_level setting_get_setdef(const struct setting *pset)
Definition settings.c:5666
const char * setting_name(const struct setting *pset)
Definition settings.c:3393
int setting_bitwise_get(struct setting *pset)
Definition settings.c:4319
char * setting_str_get(struct setting *pset)
Definition settings.c:3919
bool setting_bool_get(struct setting *pset)
Definition settings.c:3736
const char * setting_bitwise_secfile_str(secfile_data_t data, int bit)
Definition settings.c:4126
int read_enum_value(const struct setting *pset)
Definition settings.c:4056
#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:110
bool is_super_specialist_id(Specialist_type_id sp)
Definition specialist.c:188
const char * specialist_rule_name(const struct specialist *sp)
Definition specialist.c:157
#define specialist_type_iterate_end
Definition specialist.h:85
#define specialist_type_iterate(sp)
Definition specialist.h:79
#define DEFAULT_SPECIALIST
Definition specialist.h:43
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:799
Definition climisc.h:82
char calendar_fragment_name[MAX_CALENDAR_FRAGMENTS][MAX_LEN_NAME]
char negative_year_label[MAX_LEN_NAME]
char positive_year_label[MAX_LEN_NAME]
bool tech_steal_allow_holes
enum gameloss_style gameloss_style
int granary_food_ini[MAX_GRANARY_INIS]
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
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
int min_city_center_output[O_LAST]
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
char alt_dir[MAX_LEN_NAME]
char version[MAX_LEN_NAME]
char preferred_musicset[MAX_LEN_NAME]
char name[MAX_LEN_NAME]
char preferred_tileset[MAX_LEN_NAME]
char preferred_soundset[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:595
struct civ_map map
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:104
#define music_styles_iterate(_p)
Definition style.h:75
#define music_styles_iterate_end
Definition style.h:82
#define styles_re_active_iterate_end
Definition style.h:62
#define styles_re_active_iterate(_p)
Definition style.h:58
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:925
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:470
#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:173
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:229
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:110
const char * tech_flag_id_name_cb(enum tech_flag_id flag)
Definition tech.c:438
const char * tech_class_rule_name(const struct tech_class *ptclass)
Definition tech.c:357
bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag)
Definition tech.c:221
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:314
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:90
const char * tech_flag_helptxt(enum tech_flag_id id)
Definition tech.c:450
#define advance_re_active_iterate(_p)
Definition tech.h:279
#define A_NEVER
Definition tech.h:51
#define tech_class_iterate_end
Definition tech.h:201
#define MAX_NUM_USER_TECH_FLAGS
Definition tech.h:105
@ AR_TWO
Definition tech.h:109
@ AR_ROOT
Definition tech.h:110
@ AR_ONE
Definition tech.h:108
#define advance_re_active_iterate_end
Definition tech.h:283
#define A_NONE
Definition tech.h:43
#define tech_class_iterate(_p)
Definition tech.h:195
#define A_LAST
Definition tech.h:45
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:820
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:249
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Definition terrain.c:832
#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
#define tiledef_iterate_end
Definition tiledef.h:58
#define tiledef_iterate(_p)
Definition tiledef.h:52
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:1881
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:224
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1604
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1667
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1869
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1932
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1944
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
#define unit_type_re_active_iterate(_p)
Definition unittype.h:877
#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:918
#define unit_class_re_active_iterate_end
Definition unittype.h:934
#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:624
#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:930
#define uclass_index(_c_)
Definition unittype.h:749
#define unit_class_iterate_end
Definition unittype.h:925
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:128
#define unit_type_re_active_iterate_end
Definition unittype.h:881
const char * freeciv_datafile_version(void)
Definition version.c:186