Freeciv-3.3
Loading...
Searching...
No Matches
rscompat.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/* ANSI */
19#ifdef HAVE_STRING_H
20#include <string.h>
21#endif
22
23/* utility */
24#include "capability.h"
25#include "log.h"
26#include "registry.h"
27
28/* common */
29#include "actions.h"
30#include "effects.h"
31#include "fc_types.h"
32#include "game.h"
33#include "movement.h"
34#include "requirements.h"
35#include "unittype.h"
36
37/* server */
38#include "rssanity.h"
39#include "ruleload.h"
40#include "settings.h"
41
42#include "rscompat.h"
43
44#define MAXIMUM_CLAIMED_OCEAN_SIZE_3_2 (20)
45
46#define enough_new_user_flags(_new_flags_, _name_, \
47 _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_) \
48FC_STATIC_ASSERT((ARRAY_SIZE(_new_flags_) \
49 <= _LAST_USER_FLAG_ - _LAST_USER_FLAG_PREV_), \
50 not_enough_new_##_name_##_user_flags)
51
52#define UTYF_LAST_USER_FLAG_3_2 UTYF_USER_FLAG_50
53#define TECH_LAST_USER_FLAG_3_2 TECH_USER_7
54
55static int first_free_unit_type_user_flag(void);
56static int first_free_tech_user_flag(void);
57
58/**********************************************************************/
62{
63 memset(info, 0, sizeof(*info));
64}
65
66/**********************************************************************/
71 const char *filename,
72 const struct rscompat_info *info)
73{
74 const char *datafile_options;
75 bool ok = FALSE;
76 int format;
77
78 if (!(datafile_options = secfile_lookup_str(file, "datafile.options"))) {
79 log_fatal("\"%s\": ruleset capability problem:", filename);
81
82 return 0;
83 }
84
85 if (info->compat_mode) {
86 /* Check alternative capstr first, so that when we do the main capstr check,
87 * we already know that failures there are fatal (error message correct, can return
88 * immediately) */
89
92 ok = TRUE;
93 }
94 }
95
96 if (!ok) {
98 log_fatal("\"%s\": ruleset datafile appears incompatible:", filename);
99 log_fatal(" datafile options: %s", datafile_options);
100 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
101 ruleset_error(NULL, LOG_ERROR, "Capability problem");
102
103 return 0;
104 }
106 log_fatal("\"%s\": ruleset datafile claims required option(s)"
107 " that we don't support:", filename);
108 log_fatal(" datafile options: %s", datafile_options);
109 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
110 ruleset_error(NULL, LOG_ERROR, "Capability problem");
111
112 return 0;
113 }
114 }
115
116 if (!secfile_lookup_int(file, &format, "datafile.format_version")) {
117 log_error("\"%s\": lacking legal format_version field", filename);
119
120 return 0;
121 } else if (format == 0) {
122 log_error("\"%s\": Illegal format_version value", filename);
123 ruleset_error(NULL, LOG_ERROR, "Format version error");
124 }
125
126 return format;
127}
128/**********************************************************************/
136 const char *filename,
137 const struct rscompat_info *info)
138{
139 int format_version;
140
141 fc_assert_ret_val(info->version > 0, FALSE);
142
143 format_version = rscompat_check_capabilities(file, filename, info);
144 if (format_version <= 0) {
145 /* Already logged in rscompat_check_capabilities */
146 return FALSE;
147 }
148
149 if (format_version != info->version) {
150 log_fatal("\"%s\": ruleset datafile format version differs from"
151 " other ruleset datafile(s):", filename);
152 log_fatal(" datafile format version: %d", format_version);
153 log_fatal(" expected format version: %d", info->version);
154 ruleset_error(NULL, LOG_ERROR, "Inconsistent format versions");
155
156 return FALSE;
157 }
158
159 return TRUE;
160}
161
162/**********************************************************************/
169static bool
171{
172 struct req_vec_problem *problem;
173
175 /* Some changes requires starting to process an action's enablers from
176 * the beginning. */
177 bool needs_restart = FALSE;
178
180 /* A hard obligatory requirement is missing. */
181
182 int i;
183
184 if (problem->num_suggested_solutions == 0) {
185 /* Didn't get any suggestions about how to solve this. */
186
187 log_error("While adding hard obligatory reqs to action enabler"
188 " for %s: %s"
189 " Don't know how to fix it."
190 " Dropping it.",
191 action_rule_name(paction), problem->description);
192 ae->rulesave.ruledit_disabled = TRUE;
193
195 return TRUE;
196 }
197
198 /* Sanity check. */
199 fc_assert_ret_val(problem->num_suggested_solutions > 0,
201
202 /* Only append is supported for upgrade */
203 for (i = 0; i < problem->num_suggested_solutions; i++) {
204 if (problem->suggested_solutions[i].operation != RVCO_APPEND) {
205 /* A problem that isn't caused by missing obligatory hard
206 * requirements has been detected.
207 *
208 * Probably an old requirement that contradicted a hard requirement
209 * that wasn't documented by making it obligatory. In that case all
210 * suggested solutions has been applied to the enabler creating a
211 * new copy for each possible fulfillment of the new obligatory hard
212 * requirement.
213 *
214 * If another copy of the original enabler has survived this isn't
215 * an error. It probably isn't event an indication of a potential
216 * problem.
217 *
218 * If no possible solution survives the enabler was never in use
219 * because the action it self would have blocked it. In that case
220 * this is an error. */
221
222 log_warn("While adding hard obligatory reqs to action enabler"
223 " for %s: %s"
224 " Dropping it.",
225 action_rule_name(paction), problem->description);
226 ae->rulesave.ruledit_disabled = TRUE;
228 return TRUE;
229 }
230 }
231
232 for (i = 0; i < problem->num_suggested_solutions; i++) {
234
235 /* There can be more than one suggestion to apply. In that case both
236 * are applied to their own copy. The original should therefore be
237 * kept for now. */
239
240 /* Apply the solution. */
241 if (!req_vec_change_apply(&problem->suggested_solutions[i],
243 new_enabler)) {
244 log_error("While adding hard obligatory reqs to action enabler"
245 " for %s: %s"
246 "Failed to apply solution %s."
247 " Dropping it.",
248 action_rule_name(paction), problem->description,
250 &problem->suggested_solutions[i],
252 new_enabler->rulesave.ruledit_disabled = TRUE;
254 return TRUE;
255 }
256
257 if (problem->num_suggested_solutions - 1 == i) {
258 /* The last modification is to the original enabler. */
259 ae->action = new_enabler->action;
260 ae->rulesave.ruledit_disabled = new_enabler->rulesave.ruledit_disabled;
261 requirement_vector_copy(&ae->actor_reqs,
262 &new_enabler->actor_reqs);
263 requirement_vector_copy(&ae->target_reqs,
264 &new_enabler->target_reqs);
266 } else {
267 /* Register the new enabler */
269
270 /* This changes the number of action enablers. */
272 }
273 }
274
276
277 if (needs_restart) {
278 /* May need to apply future upgrades to the copies too. */
279 return TRUE;
280 }
281 }
282
283 return needs_restart;
284}
285
286/**********************************************************************/
291{
292 log_normal("action enablers: adding obligatory hard requirements.");
293 log_warn("More than one way to fulfill a new obligatory hard requirement"
294 " may exist."
295 " In that case the enabler is copied so each alternative"
296 " solution is applied to a copy of the enabler."
297 " If an action enabler becomes self contradicting after applying"
298 " a solution it is dropped."
299 " Note that other copies of the original enabler may have"
300 " survived even if one copy is dropped.");
301
302 action_iterate(act_id) {
304
305 /* RSFORMAT_3_3 */
308 requirement_vector_append(&ae->target_reqs,
309 req_from_str("PlayerState", "Player",
310 FALSE, TRUE, TRUE,
311 "Barbarian"));
313 }
314
315 do {
318 if (ae->rulesave.ruledit_disabled) {
319 /* Ignore disabled enablers */
320 continue;
321 }
323 /* Something important, probably the number of action enablers
324 * for this action, changed. Start over again on this action's
325 * enablers. */
327 break;
328 }
331
333}
334
335/**********************************************************************/
346{
347 if (info->version < RSFORMAT_3_3) {
348 int first_free;
349 int i;
350
351 /* Some unit type flags moved to the ruleset between 3.2 and 3.3.
352 * Add them back as user flags.
353 * XXX: ruleset might not need all of these, and may have enough
354 * flags of its own that these additional ones prevent conversion. */
355 const struct {
356 const char *name;
357 const char *helptxt;
358 } new_flags_33[] = {
359 { N_("NoVeteran"), N_("May acquire veteran status.") },
360 { N_("CanEscape"), N_("Can try to escape stack death.") },
361 { N_("Shield2Gold"), N_("May switch from shield upkeep to gold upkeep") }
362 };
363
366
367 /* Unit type flags. */
369
370 for (i = 0; i < ARRAY_SIZE(new_flags_33); i++) {
372 /* Can't add the user unit type flags. */
374 "Can't upgrade the ruleset. Not enough free unit type "
375 "user flags to add user flags for the unit type flags "
376 "that used to be hardcoded.");
377 return FALSE;
378 }
379 /* Shouldn't be possible for valid old ruleset to have flag names that
380 * clash with these ones */
384 "Ruleset had illegal user unit type flag '%s'",
386 return FALSE;
387 }
390 new_flags_33[i].helptxt);
391 }
392 }
393
394 if (info->version < RSFORMAT_3_3) {
395 int first_free;
396 int i;
397
398 /* Some tech flags moved to the ruleset between 3.2 and 3.3.
399 * Add them back as user flags.
400 * XXX: ruleset might not need all of these, and may have enough
401 * flags of its own that these additional ones prevent conversion. */
402 const struct {
403 const char *name;
404 const char *helptxt;
405 } new_flags_33[] = {
406 { N_("Claim_Ocean"),
407 N_("National borders expand freely into the ocean.") },
408 { N_("Claim_Ocean_Limited"),
409 N_("National borders from oceanic sources expand freely.") },
410 };
411
414
415 /* Tech flags. */
417
418 for (i = 0; i < ARRAY_SIZE(new_flags_33); i++) {
420 /* Can't add the user unit type flags. */
422 "Can't upgrade the ruleset. Not enough free tech "
423 "user flags to add user flags for the tech flags "
424 "that used to be hardcoded.");
425 return FALSE;
426 }
427 /* Shouldn't be possible for valid old ruleset to have flag names that
428 * clash with these ones */
432 "Ruleset had illegal user tech flag '%s'",
434 return FALSE;
435 }
438 new_flags_33[i].helptxt);
439 }
440 }
441
442 /* No errors encountered. */
443 return TRUE;
444}
445
446/**********************************************************************/
449static bool effect_list_compat_cb(struct effect *peffect, void *data)
450{
451 struct rscompat_info *info = (struct rscompat_info *)data;
452
453 if (info->version < RSFORMAT_3_3) {
454 if (peffect->type == EFT_SHIELD2GOLD_PCT) {
456 req_from_str("UnitTypeFlag", "Local",
457 FALSE, FALSE, FALSE,
458 "Shield2Gold"));
459 }
460 }
461
462 /* Go to the next effect. */
463 return TRUE;
464}
465
466/**********************************************************************/
470{
471 struct action_enabler *enabler;
472 struct effect *effect;
473 struct requirement e_req;
474
475 if (!info->compat_mode || info->version >= RSFORMAT_CURRENT) {
476 /* There isn't anything here that should be done outside of compat
477 * mode. */
478 return;
479 }
480
484 }
486
489 e_req = req_from_str("UnitTypeFlag", "Local", FALSE, FALSE, FALSE,
490 "NoVeteran");
493
495 enabler->action = ACTION_ESCAPE;
496 e_req = req_from_str("UnitTypeFlag", "Local", FALSE, TRUE, FALSE,
497 "CanEscape");
500
503 enabler->action = ACTION_CIVIL_WAR;
505 }
506
507 /* Upgrade existing effects. Done before new effects are added to prevent
508 * the new effects from being upgraded by accident. */
510
511 /* Old hardcoded behavior always had tech leakage enabled,
512 * thought limited by game.info.tech_leakage setting. */
513 effect_new(EFT_TECH_LEAKAGE, 1, nullptr);
514
515 /* Old behavior: Land tiles can be claimed by land border sources on the
516 * same continent. */
517 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
524 /* Tile-range TREL_SAME_REGION implies TREL_SAME_TCLASS */
525
526 /* Old behavior: Oceanic tiles can be claimed by adjacent border
527 * sources. */
528 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
533 FALSE, TRUE, FALSE, 2);
535
536 /* Old behavior: Oceanic tiles part of an ocean that is no larger than
537 * MAXIMUM_CLAIMED_OCEAN_SIZE tiles and that is adjacent to only one
538 * continent (i.e. surrounded by it) can be claimed by land border
539 * sources on that continent. */
540 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
545 FALSE, TRUE, FALSE,
551 /* Tile-range TREL_REGION_SURROUNDED implies negated TREL_SAME_TCLASS */
552
553 /* Old behavior: Oceanic tiles adjacent to no more than two other oceanic
554 * tiles and (individually) adjacent to only a single continent can be
555 * claimed by land border sources on that continent. */
556 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
564 FALSE, TRUE, FALSE, 2 + 1);
569
570 /* Old behavior: Oceanic tiles can be claimed by any oceanic border
571 * sources with the Claim_Ocean_Limited techflag. */
572 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
579 e_req = req_from_str("TechFlag", "Player", FALSE, TRUE, FALSE,
580 "Claim_Ocean_Limited");
582
583 /* Old behavior: Oceanic tiles can be claimed by any border sources
584 * with the Claim_Ocean techflag. */
585 effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr);
589 e_req = req_from_str("TechFlag", "Player", FALSE, TRUE, FALSE,
590 "Claim_Ocean");
592
593 /* Make sure that all action enablers added or modified by the
594 * compatibility post processing fulfills all hard action requirements. */
596
597 /* The ruleset may need adjustments it didn't need before compatibility
598 * post processing.
599 *
600 * If this isn't done a user of ruleset compatibility that ends up using
601 * the rules risks bad rules. A user that saves the ruleset rather than
602 * using it risks an unexpected change on the next load and save. */
604}
605
606/**********************************************************************/
611{
612 int flag;
613
614 /* Find the first unused user defined unit type flag. */
615 for (flag = 0; flag < MAX_NUM_USER_UNIT_FLAGS; flag++) {
617 return flag;
618 }
619 }
620
621 /* All unit type user flags are taken. */
623}
624
625/**********************************************************************/
630{
631 int flag;
632
633 /* Find the first unused user defined tech flag. */
634 for (flag = 0; flag < MAX_NUM_USER_TECH_FLAGS; flag++) {
635 if (tech_flag_id_name_cb(flag + TECH_USER_1) == nullptr) {
636 return flag;
637 }
638 }
639
640 /* All tech user flags are taken. */
642}
643
644/**********************************************************************/
647const char *rscompat_utype_flag_name_3_3(const char *old_name)
648{
649 if (!fc_strcasecmp("Settlers", old_name)) {
650 return "Workers";
651 }
652
653 return old_name;
654}
655
656/**********************************************************************/
659const char *rscompat_universal_name_3_3(const char *old_name)
660{
661 if (!fc_strcasecmp("UnitFlag", old_name)) {
662 return "UnitTypeFlag";
663 }
664
665 return old_name;
666}
667
668/**********************************************************************/
671const char *rscompat_effect_name_3_3(const char *old_name)
672{
673 if (!fc_strcasecmp("Martial_Law_Each", old_name)) {
674 return "Martial_Law_By_Unit";
675 } else if (!fc_strcasecmp("Shield2Gold_Factor", old_name)) {
676 return "Shield2Gold_Pct";
677 }
678
679 return old_name;
680}
681
682/**********************************************************************/
685const char *blocked_by_old_name_3_3(const char *new_name)
686{
687 if (!fc_strcasecmp("conquer_city_shrink_blocked_by", new_name)) {
688 return "conquer_city_blocked_by";
689 }
690 if (!fc_strcasecmp("conquer_city_shrink_2_blocked_by", new_name)) {
691 return "conquer_city_2_blocked_by";
692 }
693 if (!fc_strcasecmp("conquer_city_shrink_3_blocked_by", new_name)) {
694 return "conquer_city_3_blocked_by";
695 }
696 if (!fc_strcasecmp("conquer_city_shrink_4_blocked_by", new_name)) {
697 return "conquer_city_4_blocked_by";
698 }
699
700 return nullptr;
701}
702
703/**********************************************************************/
706const char *ui_name_old_name_3_3(const char *new_name)
707{
708 if (!fc_strcasecmp("ui_name_conquer_city_shrink", new_name)) {
709 return "ui_name_conquer_city";
710 }
711 if (!fc_strcasecmp("ui_name_conquer_city_shrink_2", new_name)) {
712 return "ui_name_conquer_city_2";
713 }
714 if (!fc_strcasecmp("ui_name_conquer_city_shrink_3", new_name)) {
715 return "ui_name_conquer_city_3";
716 }
717 if (!fc_strcasecmp("ui_name_conquer_city_shrink_4", new_name)) {
718 return "ui_name_conquer_city_4";
719 }
720
721 return nullptr;
722}
723
724#define RS_DEFAULT_CIVIL_WAR_CELEB -5
725#define RS_DEFAULT_CIVIL_WAR_UNHAPPY 5
726
727/**********************************************************************/
731{
733 "civstyle.civil_war_bonus_celebrating");
734
735 if (bonus != 0) {
736 struct requirement e_req;
737 struct effect *peffect;
738
739 peffect = effect_new(EFT_CIVIL_WAR_CITY_BONUS, -bonus, nullptr);
740 e_req = req_from_str("CityStatus", "City", FALSE, TRUE, FALSE,
741 "Celebration");
743 }
744
746 "civstyle.civil_war_bonus_unhappy");
747
748 if (bonus != 0) {
749 struct requirement e_req;
750 struct effect *peffect;
751
752 peffect = effect_new(EFT_CIVIL_WAR_CITY_BONUS, -bonus, nullptr);
753 e_req = req_from_str("CityStatus", "City", FALSE, TRUE, FALSE,
754 "Disorder");
756 }
757}
758
759/**********************************************************************/
762bool load_action_ui_name_3_3(struct section_file *file, int act,
763 const char *entry_name,
764 struct rscompat_info *compat)
765{
766 const char *text;
767 const char *def = action_ui_name_default(act);
768 struct action *paction = action_by_number(act);
769
770 if (entry_name == nullptr) {
771 text = def;
772 } else {
773 text = secfile_lookup_str_default(file, nullptr,
774 "actions.%s", entry_name);
775
776 if (text == nullptr && compat->compat_mode && compat->version < RSFORMAT_3_3) {
777 text = secfile_lookup_str_default(file, nullptr,
778 "actions.%s", ui_name_old_name_3_3(entry_name));
779 }
780
781 if (text == nullptr) {
782 text = def;
783 } else {
784 if (strcmp(def, text)) {
785 paction->configured = TRUE;
786 }
787 }
788 }
789
790 sz_strlcpy(paction->ui_name, text);
791
792 return TRUE;
793}
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:1897
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:2074
const char * action_rule_name(const struct action *action)
Definition actions.c:1216
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:1526
const char * action_ui_name_default(int act)
Definition actions.c:6090
struct action_enabler * action_enabler_new(void)
Definition actions.c:1475
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:1511
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1559
struct requirement_vector * action_enabler_vector_by_number(const void *enabler, req_vec_num_in_item number)
Definition actions.c:2050
#define enabler_get_action(_enabler_)
Definition actions.h:186
static struct action * action_by_number(action_id act_id)
Definition actions.h:400
#define action_has_result(_act_, _res_)
Definition actions.h:184
#define action_enabler_list_iterate_end
Definition actions.h:194
#define action_iterate_end
Definition actions.h:218
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:192
#define action_iterate(_act_)
Definition actions.h:214
#define BV_SET(bv, bit)
Definition bitvector.h:89
bool has_capabilities(const char *us, const char *them)
Definition capability.c:88
char * incite_cost
Definition comments.c:76
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1321
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:186
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:266
#define N_(String)
Definition fcintl.h:69
struct civ_game game
Definition game.c:61
const char * name
Definition inputfile.c:127
#define log_warn(message,...)
Definition log.h:106
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_fatal(message,...)
Definition log.h:101
#define log_normal(message,...)
Definition log.h:108
@ LOG_ERROR
Definition log.h:31
#define log_error(message,...)
Definition log.h:104
#define FC_FREE(ptr)
Definition mem.h:41
const char * secfile_error(void)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
const char * entry_name(const struct entry *pentry)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool req_vec_change_apply(const struct req_vec_change *modification, requirement_vector_by_number getter, const void *parent_item)
const char * req_vec_change_translation(const struct req_vec_change *change, const requirement_vector_namer namer)
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
void req_vec_problem_free(struct req_vec_problem *issue)
#define RS_DEFAULT_CIVIL_WAR_UNHAPPY
Definition rscompat.c:725
bool load_action_ui_name_3_3(struct section_file *file, int act, const char *entry_name, struct rscompat_info *compat)
Definition rscompat.c:762
void rscompat_civil_war_effects_3_3(struct section_file *game_rs)
Definition rscompat.c:730
const char * rscompat_effect_name_3_3(const char *old_name)
Definition rscompat.c:671
const char * ui_name_old_name_3_3(const char *new_name)
Definition rscompat.c:706
#define UTYF_LAST_USER_FLAG_3_2
Definition rscompat.c:52
static bool rscompat_enabler_add_obligatory_hard_reqs(struct action_enabler *ae)
Definition rscompat.c:170
#define MAXIMUM_CLAIMED_OCEAN_SIZE_3_2
Definition rscompat.c:44
#define RS_DEFAULT_CIVIL_WAR_CELEB
Definition rscompat.c:724
bool rscompat_names(struct rscompat_info *info)
Definition rscompat.c:345
#define TECH_LAST_USER_FLAG_3_2
Definition rscompat.c:53
void rscompat_postprocess(struct rscompat_info *info)
Definition rscompat.c:469
const char * rscompat_utype_flag_name_3_3(const char *old_name)
Definition rscompat.c:647
int rscompat_check_capabilities(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:70
void rscompat_enablers_add_obligatory_hard_reqs(void)
Definition rscompat.c:290
const char * blocked_by_old_name_3_3(const char *new_name)
Definition rscompat.c:685
static int first_free_tech_user_flag(void)
Definition rscompat.c:629
static bool effect_list_compat_cb(struct effect *peffect, void *data)
Definition rscompat.c:449
const char * rscompat_universal_name_3_3(const char *old_name)
Definition rscompat.c:659
static int first_free_unit_type_user_flag(void)
Definition rscompat.c:610
void rscompat_init_info(struct rscompat_info *info)
Definition rscompat.c:61
bool rscompat_check_cap_and_version(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:135
#define enough_new_user_flags(_new_flags_, _name_, _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_)
Definition rscompat.c:46
#define RULESET_COMPAT_CAP
Definition rscompat.h:27
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1616
#define ruleset_error(logger, level, format,...)
Definition ruleload.h:59
#define RULESET_CAPABILITIES
Definition ruleload.h:24
#define RSFORMAT_CURRENT
Definition ruleload.h:38
#define RSFORMAT_3_3
Definition ruleload.h:37
static struct compatibility compat[]
Definition savecompat.c:115
#define ARRAY_SIZE(x)
Definition shared.h:85
bool civil_war_enabled
Definition game.h:131
struct civ_game::@32::@36 server
struct civ_game::@32::@36::@37 deprecated
bool compat_mode
Definition rscompat.h:31
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * tech_flag_id_name_cb(enum tech_flag_id flag)
Definition tech.c:433
void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt)
Definition tech.c:404
#define MAX_NUM_USER_TECH_FLAGS
Definition tech.h:103
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:203
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1909
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1880
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:336
#define UTYF_LAST_USER_FLAG
Definition unittype.h:335
#define unit_type_iterate(_p)
Definition unittype.h:860
#define unit_type_iterate_end
Definition unittype.h:867