71 #define RULES_SUFFIX "ruleset"
72 #define SCRIPT_SUFFIX "lua"
74 #define ADVANCE_SECTION_PREFIX "advance_"
75 #define TECH_CLASS_SECTION_PREFIX "techclass_"
76 #define BUILDING_SECTION_PREFIX "building_"
77 #define CITYSTYLE_SECTION_PREFIX "citystyle_"
78 #define MUSICSTYLE_SECTION_PREFIX "musicstyle_"
79 #define EFFECT_SECTION_PREFIX "effect_"
80 #define GOVERNMENT_SECTION_PREFIX "government_"
81 #define NATION_SET_SECTION_PREFIX "nset"
82 #define NATION_GROUP_SECTION_PREFIX "ngroup"
83 #define NATION_SECTION_PREFIX "nation"
84 #define STYLE_SECTION_PREFIX "style_"
85 #define CLAUSE_SECTION_PREFIX "clause_"
86 #define EXTRA_SECTION_PREFIX "extra_"
87 #define BASE_SECTION_PREFIX "base_"
88 #define ROAD_SECTION_PREFIX "road_"
89 #define RESOURCE_SECTION_PREFIX "resource_"
90 #define GOODS_SECTION_PREFIX "goods_"
91 #define SPECIALIST_SECTION_PREFIX "specialist_"
92 #define TERRAIN_SECTION_PREFIX "terrain_"
93 #define UNIT_CLASS_SECTION_PREFIX "unitclass_"
94 #define UNIT_SECTION_PREFIX "unit_"
95 #define DISASTER_SECTION_PREFIX "disaster_"
96 #define ACHIEVEMENT_SECTION_PREFIX "achievement_"
97 #define ACTION_ENABLER_SECTION_PREFIX "actionenabler_"
98 #define MULTIPLIER_SECTION_PREFIX "multiplier_"
100 #define check_name(name) (check_strlen(name, MAX_LEN_NAME, nullptr))
101 #define check_cityname(name) (check_strlen(name, MAX_LEN_CITYNAME, nullptr))
105 #define MAX_SECTION_LABEL 64
106 #define section_strlcpy(dst, src) \
107 (void) loud_strlcpy(dst, src, MAX_SECTION_LABEL, name_too_long)
114 static struct requirement_vector
reqs_list;
118 bool buffer_script,
bool load_luadata);
140 const char *secfile_str1,
const char *secfile_str2,
141 const char **allowed_terrains,
size_t atcount);
183 size_t err_len,
bool compat);
186 int def,
int min,
int max,
187 const char *path, ...)
201 const
char *extension,
bool optional)
210 qCDebug(ruleset_category,
"Trying \"%s\".", filename);
212 if (!dfilename.isEmpty()) {
216 fc_snprintf(filename,
sizeof(filename),
"default/%s.%s",
name, extension);
217 qCDebug(ruleset_category,
"Trying \"%s\": default ruleset directory.",
220 if (!dfilename.isEmpty()) {
226 qCDebug(ruleset_category,
227 "Trying \"%s\": alternative ruleset filename syntax.", filename);
229 if (!dfilename.isEmpty()) {
231 }
else if (!optional) {
232 qCCritical(ruleset_category,
234 _(
"Could not find a readable \"%s.%s\" ruleset file."),
name,
263 if (dfilename.isEmpty()) {
269 sfilename = dfilename;
272 if (secfile ==
nullptr) {
273 qCCritical(ruleset_category,
"Could not load ruleset '%s':\n%s",
285 char **buffer,
bool optional)
290 if (dfilename.isEmpty()) {
294 if (buffer ==
nullptr) {
296 qCCritical(ruleset_category,
"\"%s\": could not load ruleset script.",
297 qUtf8Printable(dfilename));
317 if (dfilename.isEmpty()) {
323 sfilename = dfilename;
326 if (secfile ==
nullptr) {
327 qCCritical(ruleset_category,
"Could not load luadata '%s':\n%s",
340 const char *sec,
const char *sub,
343 const char *type, *
name;
345 const char *filename;
349 requirement_vector_reserve(&
reqs_list, 0);
352 file,
nullptr,
"%s.%s%d.type", sec, sub, j));
356 bool survives, present, quiet;
357 struct entry *pentry;
389 qCCritical(ruleset_category,
390 "\"%s\": trying to have an floating point entry as a "
391 "requirement name in '%s.%s%d'.",
392 filename, sec, sub, j);
401 if (
nullptr ==
name) {
402 qCCritical(ruleset_category,
403 "\"%s\": error in handling requirement name for '%s.%s%d'.",
404 filename, sec, sub, j);
418 qCCritical(ruleset_category,
419 "\"%s\": invalid boolean value for survives for "
421 filename, sec, sub, j);
427 qCCritical(ruleset_category,
428 "\"%s\": invalid boolean value for present for "
430 filename, sec, sub, j);
435 qCCritical(ruleset_category,
436 "\"%s\": invalid boolean value for quiet for "
438 filename, sec, sub, j);
441 if (
compat->compat_mode) {
447 if (
compat->compat_mode) {
452 if (req.
source.
kind == universals_n_invalid()) {
453 qCCritical(ruleset_category,
454 "\"%s\" [%s] has invalid or unknown req: "
456 filename, sec, type,
name);
461 requirement_vector_append(&
reqs_list, req);
465 qCCritical(ruleset_category,
466 "Too many (%d) requirements for %s. Max is %d", j, rfor,
479 struct combat_bonus_list *list,
485 const char *filename;
491 file,
nullptr,
"%s.%s%d.flag", sec, sub, j));
496 bonus->
flag = unit_type_flag_id_by_name(
498 if (!unit_type_flag_id_is_valid(bonus->flag)) {
499 qCritical(
"\"%s\": unknown flag name \"%s\" in '%s.%s'.", filename,
507 bonus->type = combat_bonus_type_by_name(type,
fc_strcasecmp);
508 if (!combat_bonus_type_is_valid(bonus->type)) {
509 qCritical(
"\"%s\": unknown bonus type \"%s\" in '%s.%s'.", filename,
518 qCritical(
"\"%s\": failed to get value from '%s.%s%d'.", filename, sec,
527 combat_bonus_list_append(list, bonus);
542 const char *prefix,
const char *
entry,
543 const char *filename,
const char *description)
548 if (!sval || !strcmp(sval,
"Never")) {
554 qCCritical(ruleset_category,
"\"%s\" %s %s: couldn't match \"%s\".",
555 filename, (description ? description : prefix),
entry,
573 const char *filename,
const char *description)
579 if (!sval || strcmp(sval,
"None") == 0) {
585 qCCritical(ruleset_category,
"\"%s\" %s %s: couldn't match \"%s\".",
586 filename, (description ? description : prefix),
entry,
604 std::array<unit_type *, MAX_NUM_UNIT_LIST> &output,
const char *filename)
611 output.fill(
nullptr);
619 qCCritical(ruleset_category,
620 "\"%s\": string vector %s.%s too long (%d, max %d)", filename,
623 }
else if (nval == 1 && strcmp(slist[0],
"") == 0) {
628 for (i = 0; i < nval; i++) {
629 const char *sval = slist[i];
633 qCCritical(ruleset_category,
634 "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename,
635 prefix,
entry, i, sval);
639 output[i] = punittype;
640 log_debug(
"\"%s\" %s.%s (%d): %s (%d)", filename, prefix,
entry, i,
658 const char *
entry,
int *output,
659 const char *filename)
671 if (slist ==
nullptr) {
673 }
else if (nval == 0) {
678 qCCritical(ruleset_category,
679 "\"%s\": string vector %s.%s too long (%d, max %d)", filename,
685 if (nval == 1 && strcmp(slist[0],
"") == 0) {
690 for (i = 0; i < nval && ok; i++) {
691 const char *sval = slist[i];
694 if (
nullptr == padvance) {
695 qCCritical(ruleset_category,
696 "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename,
697 prefix,
entry, i, sval);
701 qCCritical(ruleset_category,
"\"%s\" %s.%s (%d): \"%s\" is removed.",
702 filename, prefix,
entry, i, sval);
708 log_debug(
"\"%s\" %s.%s (%d): %s (%d)", filename, prefix,
entry, i,
727 const char *prefix,
const char *
entry,
728 int *output,
const char *filename)
741 qCCritical(ruleset_category,
742 "\"%s\": string vector %s.%s too long (%d, max %d)", filename,
745 }
else if (nval == 0 || (nval == 1 && strcmp(slist[0],
"") == 0)) {
746 if (slist !=
nullptr) {
753 for (i = 0; i < nval; i++) {
754 const char *sval = slist[i];
757 if (
nullptr == pimprove) {
758 qCCritical(ruleset_category,
759 "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename,
760 prefix,
entry, i, sval);
783 const char *filename,
const char *description)
789 if (strcmp(sval,
"None") == 0) {
793 if (*result ==
nullptr) {
794 qCCritical(ruleset_category,
"\"%s\" %s %s: couldn't match \"%s\".",
795 filename, (description ? description : prefix),
entry,
811 const char *filename,
824 qCCritical(ruleset_category,
"\"%s\" %s: couldn't match \"%s\".",
825 filename,
entry, sval);
838 if (
nullptr != sval) {
839 char copy[strlen(sval) + 1];
843 if (strlen(copy) > 0) {
857 if (
size ==
static_cast<size_t>(-1)) {
859 for (; *vec; vec++) {
865 for (i = 0; i <
size; i++, vec++) {
866 psv->replace(i, *vec);
882 if (
nullptr != vec) {
903 if (pres ==
nullptr) {
904 qCCritical(ruleset_category,
"\"%s\" [%s] has unknown \"%s\".", filename,
916 const char *filename,
struct terrain *pthis,
924 if (
nullptr ==
name || *
name ==
'\0' || (0 == strcmp(
name,
"none"))
925 || (0 == strcmp(
name,
"no"))) {
930 if (0 == strcmp(
name,
"yes")) {
939 if (pterr ==
nullptr) {
940 qCCritical(ruleset_category,
"\"%s\" [%s] has unknown \"%s\".",
956 const char *sec_name,
const char *property_name,
957 const char *filename,
const char *item_name,
968 if (*turns > max_turns) {
969 qCCritical(ruleset_category,
970 "\"%s\": \"%s\": \"%s\" value %d too large (max %d)",
971 filename, item_name ? item_name : sec_name, property_name,
984 const char *sec_name)
990 qCCritical(ruleset_category,
"\"%s\" [%s]: no \"name\" specified.",
1005 const char *secname,
1006 const char *field_prefix)
1012 const char *trait_names[] = {
"expansionist",
"trader",
"aggressive",
1013 "builder",
nullptr};
1015 for (tr = trait_begin(); tr != trait_end() && trait_names[tr] !=
nullptr;
1016 tr = trait_next(tr)) {
1018 file, -1,
"%s.%s%s_min", secname, field_prefix, trait_names[tr]);
1020 file, -1,
"%s.%s%s_max", secname, field_prefix, trait_names[tr]);
1022 file, -1,
"%s.%s%s_default", secname, field_prefix, trait_names[tr]);
1035 struct section_list *sec;
1042 if (
compat->ver_game <= 0) {
1050 nval = (
nullptr != sec ? section_list_size(sec) : 0);
1054 qCCritical(ruleset_category,
1055 "\"%s\": Too many achievement types (%d, max %d)", filename,
1065 const char *sec_name =
1069 qCCritical(ruleset_category,
"\"%s\": Cannot load achievement names",
1078 section_list_destroy(sec);
1080 if (
compat->ver_game >= 10) {
1084 nval = (
nullptr != sec ? section_list_size(sec) : 0);
1087 qCCritical(ruleset_category,
1088 "\"%s\": Too many goods types (%d, max %d)", filename,
1091 }
else if (nval < 1) {
1092 qCCritical(ruleset_category,
1093 "\"%s\": At least one goods type needed", filename);
1102 const char *sec_name =
1106 qCCritical(ruleset_category,
"\"%s\": Cannot load goods names",
1114 section_list_destroy(sec);
1128 struct section_list *sec =
nullptr;
1137 if (
compat->ver_techs <= 0) {
1146 "control.flags%d.name", i));
1149 file,
nullptr,
"control.flags%d.helptxt", i);
1151 != tech_flag_id_invalid()) {
1152 qCCritical(ruleset_category,
"\"%s\": Duplicate tech flag name '%s'",
1158 qCCritical(ruleset_category,
"\"%s\": Too many user tech flags!",
1178 nval = (
nullptr != sec ? section_list_size(sec) : 0);
1182 qCCritical(ruleset_category,
1183 "\"%s\": Too many tech classes (%d, max %d)", filename, num,
1193 const char *sec_name =
1197 qCCritical(ruleset_category,
1198 "\"%s\": Cannot load tech class names", filename);
1210 section_list_destroy(sec);
1213 if (
nullptr == sec || 0 == (num_techs = section_list_size(sec))) {
1214 qCCritical(ruleset_category,
"\"%s\": No Advances?!?", filename);
1217 qCDebug(ruleset_category,
"%d advances (including possibly unused)",
1220 qCCritical(ruleset_category,
1221 "\"%s\": Too many advances (%d, max %d)", filename,
1243 section_list_destroy(sec);
1254 struct section_list *sec;
1267 const char *sec_name =
section_name(section_list_get(sec, i));
1276 section_list_destroy(sec);
1283 const char *sec_name =
section_name(section_list_get(sec, i));
1286 struct requirement_vector *research_reqs;
1301 qCCritical(ruleset_category,
1302 "\"%s\" [%s] \"%s\": \"Never\" with non-\"Never\".",
1308 qCCritical(ruleset_category,
1309 "\"%s\" [%s] \"%s\": should have \"None\" second.",
1316 a->tclass =
nullptr;
1318 const char *classname;
1321 if (classname !=
nullptr) {
1322 classname =
Q_(classname);
1324 if (a->tclass ==
nullptr) {
1325 qCCritical(ruleset_category,
1326 "\"%s\" [%s] \"%s\": Uknown tech class \"%s\".",
1332 a->tclass =
nullptr;
1338 if (research_reqs ==
nullptr) {
1343 requirement_vector_copy(&a->research_reqs, research_reqs);
1348 for (j = 0; j < nval; j++) {
1350 if (strcmp(sval,
"") == 0) {
1354 if (!tech_flag_id_is_valid(tech_flag_id(ival))) {
1355 qCCritical(ruleset_category,
1356 "\"%s\" [%s] \"%s\": bad flag name \"%s\".", filename,
1372 file,
"-",
"%s.graphic", sec_name));
1374 file,
"-",
"%s.graphic_alt", sec_name));
1377 a->bonus_message =
lookup_string(file, sec_name,
"bonus_message");
1399 bool out_of_order =
false;
1406 && (a == b->require[
AR_ONE] || a == b->require[
AR_TWO])) {
1408 b->inherited_root_req =
true;
1410 out_of_order =
true;
1445 qCCritical(ruleset_category,
1446 "\"%s\" tech \"%s\": req1 leads to removed tech.",
1452 qCCritical(ruleset_category,
1453 "\"%s\" tech \"%s\": req2 leads to removed tech.",
1463 section_list_destroy(sec);
1478 struct section_list *sec =
nullptr;
1486 if (
compat->ver_units <= 0) {
1495 "control.flags%d.name", i));
1498 file,
nullptr,
"control.flags%d.helptxt", i);
1502 != unit_type_flag_id_invalid()) {
1503 qCCritical(ruleset_category,
"\"%s\": Duplicate unit flag name '%s'",
1509 qCCritical(ruleset_category,
"\"%s\": Too many user unit type flags!",
1530 file,
nullptr,
"control.class_flags%d.name", i));
1533 file,
nullptr,
"control.class_flags%d.helptxt", i);
1536 != unit_class_flag_id_invalid()) {
1537 qCCritical(ruleset_category,
1538 "\"%s\": Duplicate unit class flag name "
1545 qCCritical(ruleset_category,
1546 "\"%s\": Too many user unit class flags!", filename);
1567 file, 3, 1, 15,
"control.sentry_range");
1573 if (
nullptr == sec || 0 == (nval = section_list_size(sec))) {
1574 qCCritical(ruleset_category,
"\"%s\": No unit classes?!?", filename);
1577 qCDebug(ruleset_category,
"%d unit classes", nval);
1579 qCCritical(ruleset_category,
1580 "\"%s\": Too many unit classes (%d, max %d)", filename,
1602 section_list_destroy(sec);
1608 if (
nullptr == sec || 0 == (nval = section_list_size(sec))) {
1609 qCCritical(ruleset_category,
"\"%s\": No unit types?!?", filename);
1612 qCDebug(ruleset_category,
"%d unit types (including possibly unused)",
1615 qCCritical(ruleset_category,
1616 "\"%s\": Too many unit types (%d, max %d)", filename,
1637 section_list_destroy(sec);
1647 size_t err_len,
bool compat)
1649 const char **vlist_name;
1650 int *vlist_power, *vlist_raise, *vlist_wraise, *vlist_move;
1651 size_t count_name, count_power, count_raise, count_wraise, count_move;
1656 if (*vsystem !=
nullptr) {
1657 fc_snprintf(err, err_len,
"Veteran system is defined?!");
1665 "%s.veteran_power_fact", path);
1667 "%s.veteran_base_raise_chance", path);
1668 if (vlist_raise ==
nullptr &&
compat) {
1670 "%s.veteran_raise_chance", path);
1673 file, &count_wraise,
"%s.veteran_work_raise_chance", path);
1675 "%s.veteran_move_bonus", path);
1680 "\"%s\": Too many veteran levels (section "
1681 "'%s': %lu, max %d)",
1684 }
else if (count_name != count_power || count_name != count_raise
1685 || count_name != count_wraise || count_name != count_move) {
1688 "\"%s\": Different lengths for the veteran "
1689 "settings in section '%s'",
1691 }
else if (count_name == 0) {
1698 #define rs_sanity_veteran(_path, _entry, _i, _condition, _action) \
1700 qCritical("Invalid veteran definition '%s.%s[%d]'!", _path, _entry, \
1702 log_debug("Failed check: '%s'. Update value: '%s'.", #_condition, \
1706 for (i = 0; i < count_name; i++) {
1709 vlist_power[i] = 0);
1711 (vlist_raise[i] < 0), vlist_raise[i] = 0);
1713 (vlist_wraise[i] < 0), vlist_wraise[i] = 0);
1719 (vlist_power[i] != 100), vlist_power[i] = 100);
1720 }
else if (i == count_name - 1) {
1723 (vlist_power[i] < vlist_power[i - 1]),
1724 vlist_power[i] = vlist_power[i - 1]);
1726 (vlist_raise[i] != 0), vlist_raise[i] = 0);
1728 (vlist_wraise[i] != 0), vlist_wraise[i] = 0);
1732 (vlist_power[i] < vlist_power[i - 1]),
1733 vlist_power[i] = vlist_power[i - 1]);
1735 (vlist_raise[i] > 100), vlist_raise[i] = 100);
1737 (vlist_wraise[i] > 100), vlist_wraise[i] = 100);
1741 vlist_move[i], vlist_raise[i],
1744 #undef rs_sanity_veteran
1747 delete[] vlist_name;
1748 delete[] vlist_power;
1749 delete[] vlist_raise;
1750 delete[] vlist_wraise;
1751 delete[] vlist_move;
1753 vlist_name =
nullptr;
1754 vlist_power =
nullptr;
1755 vlist_raise =
nullptr;
1756 vlist_wraise =
nullptr;
1757 vlist_move =
nullptr;
1770 struct section_list *sec, *csec;
1771 const char *sval, **slist;
1777 sizeof(msg),
compat->compat_mode)
1779 qCCritical(ruleset_category,
1780 "Error loading the default veteran system: %s", msg);
1785 nval = (
nullptr != sec ? section_list_size(sec) : 0);
1788 nval = (
nullptr != csec ? section_list_size(csec) : 0);
1794 const char *hut_str;
1795 const char *sec_name =
section_name(section_list_get(csec, i));
1813 file, 100,
"%s.non_native_def_pct", sec_name);
1824 qCCritical(ruleset_category,
1825 "\"%s\" unit_class \"%s\":"
1826 " Illegal hut behavior \"%s\".",
1834 for (j = 0; j < nval; j++) {
1836 if (strcmp(sval,
"") == 0) {
1840 if (!unit_class_flag_id_is_valid(unit_class_flag_id(ival))) {
1842 ival = unit_type_flag_id_by_name(
1844 if (unit_type_flag_id_is_valid(unit_type_flag_id(ival))) {
1845 qCCritical(ruleset_category,
1846 "\"%s\" unit_class \"%s\": unit_type flag \"%s\"!",
1849 qCCritical(ruleset_category,
1850 "\"%s\" unit_class \"%s\": bad flag name \"%s\".",
1875 const struct section *psection = section_list_get(sec, i);
1878 if (!
lookup_tech(file, &u->require_advance, sec_name,
"tech_req",
1883 if (u->require_advance ==
A_NEVER) {
1884 qCCritical(ruleset_category,
"%s lacks valid tech_req.",
1905 char tmp[200] =
"\0";
1910 if (need_government ==
nullptr) {
1914 requirement_vector_append(
1921 sizeof(msg),
compat->compat_mode)) {
1922 qCCritical(ruleset_category,
"Error loading the veteran system: %s",
1931 &u->converted_to, filename,
1936 u->convert_time = 1;
1937 lookup_time(file, &u->convert_time, sec_name,
"convert_time", filename,
1949 const char *sec_name =
section_name(section_list_get(sec, i));
1964 requirement_vector_append(
1973 qCCritical(ruleset_category,
1974 "\"%s\" unit_type \"%s\":"
1975 " bad class \"%s\".",
1983 file,
"-",
"%s.sound_move", sec_name));
1988 file,
"-",
"%s.sound_fight", sec_name));
2001 file,
"-",
"%s.graphic_alt", sec_name));
2013 "%s.vision_radius_sq", sec_name)
2015 "%s.transport_cap", sec_name)
2038 if (u->transport_capacity > 0) {
2040 qCCritical(ruleset_category,
2041 "\"%s\" unit type \"%s\" "
2042 "has transport_cap %d, but no cargo unit classes.",
2049 qCCritical(ruleset_category,
2050 "\"%s\" unit type \"%s\" "
2051 "has cargo defined, but transport_cap is 0.",
2059 for (j = 0; j < nval; j++) {
2063 qCCritical(ruleset_category,
2064 "\"%s\" unit_type \"%s\":"
2065 "has unknown unit class %s as cargo.",
2082 for (j = 0; j < nval; j++) {
2086 qCCritical(ruleset_category,
2087 "\"%s\" unit_type \"%s\":"
2088 "has unknown unit class %s as target.",
2105 for (j = 0; j < nval; j++) {
2109 qCCritical(ruleset_category,
2110 "\"%s\" unit_type \"%s\":"
2111 "has unknown unit class %s as embarkable.",
2128 for (j = 0; j < nval; j++) {
2132 qCCritical(ruleset_category,
2133 "\"%s\" unit_type \"%s\":"
2134 "has unknown unit class %s as disembarkable.",
2161 u->vlayer = vision_layer_by_name(
2165 if (!vision_layer_is_valid(u->vlayer)) {
2166 qCCritical(ruleset_category,
2167 "\"%s\" unit_type \"%s\":"
2168 "has unknown vision layer %s.",
2177 file, 0,
"%s.paratroopers_range", sec_name);
2179 u->rscompat_cache.paratroopers_mr_req =
2183 u->rscompat_cache.paratroopers_mr_sub =
2188 u->rscompat_cache.paratroopers_mr_req = 0;
2189 u->rscompat_cache.paratroopers_mr_sub = 0;
2212 for (j = 0; j < nval; j++) {
2214 if (0 == strcmp(sval,
"")) {
2218 u->vlayer = V_INVIS;
2220 ival = unit_type_flag_id_by_name(
2222 if (!unit_type_flag_id_is_valid(unit_type_flag_id(ival))) {
2225 if (unit_class_flag_id_is_valid(unit_class_flag_id(ival))) {
2226 qCCritical(ruleset_category,
2227 "\"%s\" unit_type \"%s\": unit_class flag!",
2230 qCCritical(ruleset_category,
2231 "\"%s\" unit_type \"%s\": bad flag name \"%s\".",
2261 for (j = 0; j < nval; j++) {
2263 if (strcmp(sval,
"") == 0) {
2267 if (!unit_role_id_is_valid(unit_role_id(ival))) {
2268 qCCritical(ruleset_category,
2269 "\"%s\" unit_type \"%s\": bad role name \"%s\".",
2291 "\"%s\" unit_type \"%s\": depends on removed tech \"%s\".",
2300 qCCritical(ruleset_category,
2301 "\"%s\": Unit %s would build size %d cities", filename,
2310 if (
utype_has_role(u, L_FERRYBOAT) && u->transport_capacity == 0) {
2311 qCWarning(ruleset_category,
2312 "\"%s\": Unit %s has FerryBoat flag but cannot transport",
2320 section_list_destroy(csec);
2321 section_list_destroy(sec);
2337 struct section_list *sec;
2344 if (
compat->ver_buildings <= 0) {
2353 if (
nullptr == sec || 0 == (nval = section_list_size(sec))) {
2354 qCCritical(ruleset_category,
"\"%s\": No improvements?!?", filename);
2357 qCDebug(ruleset_category,
2358 "%d improvement types (including possibly unused)", nval);
2360 qCCritical(ruleset_category,
2361 "\"%s\": Too many improvements (%d, max %d)", filename,
2370 for (i = 0; i < nval; i++) {
2381 section_list_destroy(sec);
2392 struct section_list *sec;
2399 nval = (
nullptr != sec ? section_list_size(sec) : 0);
2401 for (i = 0; i < nval && ok; i++) {
2403 const char *sec_name =
section_name(section_list_get(sec, i));
2407 if (
reqs ==
nullptr) {
2411 const char *sval, **slist;
2417 if (!impr_genus_id_is_valid(b->
genus)) {
2418 qCCritical(ruleset_category,
2419 "\"%s\" improvement \"%s\": couldn't match "
2429 for (j = 0; j < nflags; j++) {
2431 if (strcmp(sval,
"") == 0) {
2435 if (!impr_flag_id_is_valid(impr_flag_id(ival))) {
2436 qCCritical(ruleset_category,
2437 "\"%s\" improvement \"%s\": bad flag name \"%s\".",
2452 requirement_vector_copy(&b->
reqs,
reqs);
2458 if (obs_reqs ==
nullptr) {
2462 requirement_vector_copy(&b->
obsolete_by, obs_reqs);
2477 file,
"-",
"%s.graphic", sec_name));
2479 file,
"-",
"%s.graphic_alt", sec_name));
2482 file,
"-",
"%s.sound", sec_name));
2484 file,
"-",
"%s.sound_alt", sec_name));
2489 section_list_destroy(sec);
2505 struct section_list *sec =
nullptr;
2512 if (
compat->ver_terrain <= 0) {
2521 "control.flags%d.name", i));
2524 file,
nullptr,
"control.flags%d.helptxt", i);
2527 != terrain_flag_id_invalid()) {
2528 qCCritical(ruleset_category,
2529 "\"%s\": Duplicate terrain flag name '%s'", filename, flag);
2534 qCCritical(ruleset_category,
"\"%s\": Too many user terrain flags!",
2554 file,
nullptr,
"control.extra_flags%d.name", i));
2557 file,
nullptr,
"control.extra_flags%d.helptxt", i);
2560 != extra_flag_id_invalid()) {
2561 qCCritical(ruleset_category,
"\"%s\": Duplicate extra flag name '%s'",
2567 qCCritical(ruleset_category,
"\"%s\": Too many user extra flags!",
2587 if (
nullptr == sec || 0 == (nval = section_list_size(sec))) {
2588 qCCritical(ruleset_category,
2589 "\"%s\": ruleset doesn't have any terrains.", filename);
2593 qCCritical(ruleset_category,
2594 "\"%s\": Too many terrains (%d, max %d)", filename, nval,
2611 const char *sec_name =
section_name(section_list_get(sec, terri));
2623 section_list_destroy(sec);
2630 nval = (
nullptr != sec ? section_list_size(sec) : 0);
2632 qCCritical(ruleset_category,
2633 "\"%s\": Too many extra types (%d, max %d)", filename, nval,
2648 for (idx = 0; idx < nval; idx++) {
2649 const char *sec_name =
section_name(section_list_get(sec, idx));
2661 section_list_destroy(sec);
2668 nval = (
nullptr != sec ? section_list_size(sec) : 0);
2670 qCCritical(ruleset_category,
2671 "\"%s\": Too many base types (%d, max %d)", filename, nval,
2688 for (idx = 0; idx < nval; idx++) {
2689 const char *sec_name =
section_name(section_list_get(sec, idx));
2692 if (base_name !=
nullptr) {
2695 if (pextra !=
nullptr) {
2699 qCCritical(ruleset_category,
2700 "No extra definition matching base definition \"%s\"",
2707 "Base section \"%s\" does not associate base with any extra",
2714 section_list_destroy(sec);
2721 nval = (
nullptr != sec ? section_list_size(sec) : 0);
2723 qCCritical(ruleset_category,
2724 "\"%s\": Too many road types (%d, max %d)", filename, nval,
2741 for (idx = 0; idx < nval; idx++) {
2742 const char *sec_name =
section_name(section_list_get(sec, idx));
2745 if (road_name !=
nullptr) {
2748 if (pextra !=
nullptr) {
2752 qCCritical(ruleset_category,
2753 "No extra definition matching road definition \"%s\"",
2760 "Road section \"%s\" does not associate road with any extra",
2767 section_list_destroy(sec);
2774 nval = (
nullptr != sec ? section_list_size(sec) : 0);
2776 qCCritical(ruleset_category,
2777 "\"%s\": Too many resource types (%d, max %d)", filename,
2794 for (idx = 0; idx < nval; idx++) {
2795 const char *sec_name =
section_name(section_list_get(sec, idx));
2796 const char *resource_name;
2802 if (resource_name !=
nullptr) {
2805 if (pextra !=
nullptr) {
2811 "No extra definition matching resource definition \"%s\"",
2816 qCCritical(ruleset_category,
2817 "Resource section %s does not list extra this "
2818 "resource belongs to.",
2825 section_list_destroy(sec);
2838 bool compat_road =
false;
2839 bool compat_rail =
false;
2840 bool compat_river =
false;
2849 file, 101,
"parameters.ocean_reclaim_requirement");
2851 file, 101,
"parameters.land_channel_requirement");
2859 file, 0,
"parameters.min_start_native_area");
2863 qCCritical(ruleset_category,
"\"%s\": move_fragments must be at least 1",
2871 qCCritical(ruleset_category,
"\"%s\": igter_cost must be at least 1",
2878 "parameters.pythagorean_diagonal");
2884 "extraui.ui_name_base_fortress");
2888 "extraui.ui_name_base_airbase");
2906 pterrain->identifier =
2908 if (
'\0' == pterrain->identifier) {
2909 qCCritical(ruleset_category,
"\"%s\" [%s] identifier missing value.",
2910 filename, tsection);
2915 qCCritical(ruleset_category,
2916 "\"%s\" [%s] cannot use '%c' as an identifier;"
2917 " it is reserved for unknown terrain.",
2918 filename, tsection, pterrain->identifier);
2922 for (j =
T_FIRST; j < i; j++) {
2924 qCCritical(ruleset_category,
2925 "\"%s\" [%s] has the same identifier as [%s].",
2937 pterrain->tclass = terrain_class_by_name(cstr,
fc_strcasecmp);
2938 if (!terrain_class_is_valid(pterrain->tclass)) {
2939 qCCritical(ruleset_category,
"\"%s\": [%s] unknown class \"%s\"",
2940 filename, tsection, cstr);
2946 "%s.movement_cost", tsection)
2948 "%s.defense_bonus", tsection)) {
2962 pterrain->resources =
new extra_type *[nval + 1]();
2963 for (j = 0; j < nval; j++) {
2965 if (pterrain->resources[j] ==
nullptr) {
2970 pterrain->resources[nval] =
nullptr;
2980 pterrain->road_output_incr_pct[o] =
2986 if (!
lookup_time(file, &pterrain->base_time, tsection,
"base_time",
2987 filename,
nullptr, &ok)
2988 || !
lookup_time(file, &pterrain->road_time, tsection,
"road_time",
2989 filename,
nullptr, &ok)) {
2995 if (!
lookup_terrain(file,
"irrigation_result", filename, pterrain,
2996 &pterrain->irrigation_result)) {
3001 "%s.irrigation_food_incr", tsection)
3002 || !
lookup_time(file, &pterrain->irrigation_time, tsection,
3003 "irrigation_time", filename,
nullptr, &ok)) {
3010 &pterrain->mining_result)) {
3015 "%s.mining_shield_incr", tsection)
3016 || !
lookup_time(file, &pterrain->mining_time, tsection,
3017 "mining_time", filename,
nullptr, &ok)) {
3023 if (!
lookup_time(file, &pterrain->cultivate_time, tsection,
3024 "cultivate_time", filename,
nullptr, &ok)) {
3025 if (
compat->compat_mode) {
3026 if (pterrain->irrigation_result != pterrain) {
3027 pterrain->cultivate_time = pterrain->irrigation_time;
3028 pterrain->irrigation_time = 0;
3030 pterrain->cultivate_time = 0;
3039 if (!
lookup_time(file, &pterrain->plant_time, tsection,
"plant_time",
3040 filename,
nullptr, &ok)) {
3041 if (
compat->compat_mode) {
3042 if (pterrain->mining_result != pterrain) {
3043 pterrain->plant_time = pterrain->mining_time;
3044 pterrain->mining_time = 0;
3046 pterrain->plant_time = 0;
3061 if (!
lookup_terrain(file,
"transform_result", filename, pterrain,
3062 &pterrain->transform_result)) {
3066 if (!
lookup_time(file, &pterrain->transform_time, tsection,
3067 "transform_time", filename,
nullptr, &ok)) {
3073 pterrain->placing_time = 1;
3074 lookup_time(file, &pterrain->placing_time, tsection,
"placing_time",
3075 filename,
nullptr, &ok);
3077 pterrain->pillage_time = 1;
3078 lookup_time(file, &pterrain->pillage_time, tsection,
"pillage_time",
3079 filename,
nullptr, &ok);
3080 pterrain->clean_pollution_time = 3;
3081 lookup_time(file, &pterrain->clean_pollution_time, tsection,
3082 "clean_pollution_time", filename,
nullptr, &ok);
3083 pterrain->clean_fallout_time = 3;
3084 lookup_time(file, &pterrain->clean_fallout_time, tsection,
3085 "clean_fallout_time", filename,
nullptr, &ok);
3087 if (!
lookup_terrain(file,
"warmer_wetter_result", filename, pterrain,
3088 &pterrain->warmer_wetter_result)
3089 || !
lookup_terrain(file,
"warmer_drier_result", filename, pterrain,
3090 &pterrain->warmer_drier_result)
3092 pterrain, &pterrain->cooler_wetter_result)
3093 || !
lookup_terrain(file,
"cooler_drier_result", filename, pterrain,
3094 &pterrain->cooler_drier_result)) {
3101 for (j = 0; j < nval; j++) {
3102 const char *sval = slist[j];
3103 enum terrain_flag_id flag =
3106 if (!terrain_flag_id_is_valid(flag)) {
3107 qCCritical(ruleset_category,
3108 "\"%s\" [%s] has unknown flag \"%s\".", filename,
3113 BV_SET(pterrain->flags, flag);
3124 enum mapgen_terrain_property mtp;
3125 for (mtp = mapgen_terrain_property_begin();
3126 mtp != mapgen_terrain_property_end();
3127 mtp = mapgen_terrain_property_next(mtp)) {
3128 pterrain->property[mtp] =
3130 mapgen_terrain_property_name(mtp));
3136 for (j = 0; j < nval; j++) {
3140 qCCritical(ruleset_category,
3141 "\"%s\" [%s] is native to unknown unit class \"%s\".",
3142 filename, tsection, slist[j]);
3159 if (!
rgbcolor_load(file, &pterrain->rgb,
"%s.color", tsection)) {
3160 qCCritical(ruleset_category,
3161 "Missing terrain color definition: %s",
3168 pterrain->helptext =
lookup_strvec(file, tsection,
"helptext");
3181 || pextra->category != ECAT_RESOURCE) {
3184 struct requirement_vector *
reqs;
3185 const char *catname;
3187 enum extra_cause cause;
3188 enum extra_rmcause rmcause;
3189 const char *eus_name;
3190 const char *vis_req_name;
3191 const struct advance *vis_req;
3194 if (catname ==
nullptr) {
3195 qCCritical(ruleset_category,
3196 "\"%s\" extra \"%s\" has no category.", filename,
3201 pextra->category = extra_category_by_name(catname,
fc_strcasecmp);
3202 if (!extra_category_is_valid(pextra->category)) {
3203 qCCritical(ruleset_category,
3204 "\"%s\" extra \"%s\" has invalid category \"%s\".",
3212 for (cj = 0; cj < nval; cj++) {
3213 const char *sval = slist[cj];
3216 if (!extra_cause_is_valid(cause)) {
3217 qCCritical(ruleset_category,
3218 "\"%s\" extra \"%s\": unknown cause \"%s\".",
3223 pextra->causes |= (1 << cause);
3228 if (pextra->causes == 0) {
3237 pextra->data.special_idx =
3246 pextra->rmcauses = 0;
3247 for (j = 0; j < nval; j++) {
3248 const char *sval = slist[j];
3251 if (!extra_rmcause_is_valid(rmcause)) {
3252 qCCritical(ruleset_category,
3253 "\"%s\" extra \"%s\": unknown rmcause \"%s\".",
3258 pextra->rmcauses |= (1 << rmcause);
3282 pextra->graphic_str,
3290 if (
reqs ==
nullptr) {
3294 requirement_vector_copy(&pextra->reqs,
reqs);
3298 if (
reqs ==
nullptr) {
3302 requirement_vector_copy(&pextra->rmreqs,
reqs);
3306 if (
reqs ==
nullptr) {
3310 requirement_vector_copy(&pextra->appearance_reqs,
reqs);
3314 if (
reqs ==
nullptr) {
3318 requirement_vector_copy(&pextra->disappearance_reqs,
reqs);
3326 pextra->build_time = 0;
3330 file, 1,
"%s.build_time_factor",
section);
3331 pextra->removal_time = 0;
3335 file, 1,
"%s.removal_time_factor",
section);
3337 pextra->defense_bonus =
3339 if (pextra->defense_bonus != 0) {
3349 pextra->eus = extra_unit_seen_type_by_name(eus_name,
fc_strcasecmp);
3350 if (!extra_unit_seen_type_is_valid(pextra->eus)) {
3353 "\"%s\" extra \"%s\" has illegal unit_seen value \"%s\".",
3358 if (pextra->eus == EUS_HIDDEN) {
3362 pextra->appearance_chance =
3364 "%s.appearance_chance",
section);
3365 pextra->disappearance_chance =
3367 "%s.disappearance_chance",
section);
3371 for (j = 0; j < nval; j++) {
3374 if (uclass ==
nullptr) {
3375 qCCritical(ruleset_category,
3376 "\"%s\" extra \"%s\" is native to unknown unit "
3394 for (j = 0; j < nval; j++) {
3395 const char *sval = slist[j];
3396 enum extra_flag_id flag =
3399 if (!extra_flag_id_is_valid(flag)) {
3400 qCCritical(ruleset_category,
3401 "\"%s\" extra \"%s\": unknown flag \"%s\".", filename,
3406 BV_SET(pextra->flags, flag);
3417 for (j = 0; j < nval; j++) {
3418 const char *sval = slist[j];
3421 if (pextra2 ==
nullptr) {
3422 qCCritical(ruleset_category,
3423 "\"%s\" extra \"%s\": unknown conflict extra \"%s\".",
3442 for (j = 0; j < nval; j++) {
3443 const char *sval = slist[j];
3446 if (top ==
nullptr) {
3447 qCCritical(ruleset_category,
3448 "\"%s\" extra \"%s\" hidden by unknown extra \"%s\".",
3466 for (j = 0; j < nval; j++) {
3467 const char *sval = slist[j];
3470 if (top ==
nullptr) {
3473 "\"%s\" extra \"%s\" bridged over unknown extra \"%s\".",
3489 file,
"None",
"%s.visibility_req",
section);
3492 if (vis_req ==
nullptr) {
3493 qCCritical(ruleset_category,
3494 "\"%s\" %s: unknown visibility_req %s.", filename,
3519 if (!presource->data.resource) {
3520 qCCritical(ruleset_category,
3521 "\"%s\" extra \"%s\" has \"Resource\" cause but no "
3522 "corresponding [resource_*] section",
3537 presource->data.resource->id_old_save = identifier[0];
3539 == presource->data.resource->id_old_save) {
3540 qCCritical(ruleset_category,
"\"%s\" [%s] identifier missing value.",
3541 filename, rsection);
3546 == presource->data.resource->id_old_save) {
3547 qCCritical(ruleset_category,
3548 "\"%s\" [%s] cannot use '%c' as an identifier;"
3551 presource->data.resource->id_old_save);
3559 for (j = 0; ok && j <
game.
control.num_resource_types; j++) {
3565 qCCritical(ruleset_category,
3566 "\"%s\" resource section [%s]: extra \"%s\" does not "
3567 "have \"Resource\" in its causes",
3568 filename,
section, extra_name);
3582 if (pres->data.resource->id_old_save
3583 == pres2->data.resource->id_old_save
3585 qCCritical(ruleset_category,
3586 "\"%s\" [%s] has the same identifier as [%s].",
3610 const char *gui_str;
3613 qCCritical(ruleset_category,
3614 "\"%s\" extra \"%s\" has \"Base\" cause but no "
3615 "corresponding [base_*] section",
3624 if (!base_gui_type_is_valid(pbase->
gui_type)) {
3625 qCCritical(ruleset_category,
3626 "\"%s\" base \"%s\": unknown gui_type \"%s\".", filename,
3637 file, -1,
"%s.vision_invis_sq",
section);
3643 for (bj = 0; bj < nval; bj++) {
3644 const char *sval = slist[bj];
3645 enum base_flag_id flag = base_flag_id_by_name(sval,
fc_strcasecmp);
3647 if (!base_flag_id_is_valid(flag)) {
3648 qCCritical(ruleset_category,
3649 "\"%s\" base \"%s\": unknown flag \"%s\".", filename,
3653 }
else if ((!
compat->compat_mode ||
compat->ver_terrain >= 20)
3655 qCCritical(ruleset_category,
3656 "\"%s\" base \"%s\": retired flag "
3657 "\"%s\". Please update the ruleset.",
3677 if (pextra == pextra2) {
3693 for (j = 0; ok && j <
game.
control.num_base_types; j++) {
3699 qCCritical(ruleset_category,
3700 "\"%s\" base section [%s]: extra \"%s\" does not have "
3701 "\"Base\" in its causes",
3702 filename,
section, extra_name);
3709 bv_extras compat_bridged;
3711 if (
compat->compat_mode) {
3721 for (j = 0; j < nval; j++) {
3723 BV_SET(compat_bridged, pextra->id);
3737 const char *special;
3738 const char *modestr;
3739 struct requirement_vector *
reqs;
3742 qCCritical(ruleset_category,
3743 "\"%s\" extra \"%s\" has \"Road\" cause but no "
3744 "corresponding [road_*] section",
3753 if (
reqs ==
nullptr) {
3769 if (!road_move_mode_is_valid(proad->
move_mode)) {
3770 qCCritical(ruleset_category,
3771 "Illegal move_mode \"%s\" for road \"%s\"", modestr,
3792 qCCritical(ruleset_category,
3793 "Multiple roads marked as compatibility \"Road\"");
3800 qCCritical(ruleset_category,
3801 "Multiple roads marked as compatibility \"Railroad\"");
3808 qCCritical(ruleset_category,
3809 "Multiple roads marked as compatibility \"River\"");
3812 compat_river =
true;
3817 qCCritical(ruleset_category,
3818 "Illegal compatibility special \"%s\" for road %s",
3829 for (j = 0; j < nval; j++) {
3830 const char *sval = slist[j];
3834 if (textra !=
nullptr) {
3838 if (top ==
nullptr) {
3841 "\"%s\" road \"%s\" integrates with unknown road \"%s\".",
3858 for (j = 0; j < nval; j++) {
3859 const char *sval = slist[j];
3864 }
else if (
compat->compat_mode
3868 if (
BV_ISSET(compat_bridged, pbridged->id)) {
3869 BV_SET(pextra->bridged_over, pbridged->id);
3874 enum road_flag_id flag = road_flag_id_by_name(sval,
fc_strcasecmp);
3876 if (!road_flag_id_is_valid(flag)) {
3877 qCCritical(ruleset_category,
3878 "\"%s\" road \"%s\": unknown flag \"%s\".", filename,
3896 for (j = 0; ok && j <
game.
control.num_road_types; j++) {
3902 qCCritical(ruleset_category,
3903 "\"%s\" road section [%s]: extra \"%s\" does not have "
3904 "\"Road\" in its causes",
3905 filename,
section, extra_name);
3914 pextra->bridged = extra_type_list_new();
3917 if (
BV_ISSET(pextra->bridged_over, pbridged->id)) {
3918 extra_type_list_append(pextra->bridged, pbridged);
3941 struct section_list *sec;
3945 compat->ver_governments =
3947 if (
compat->ver_governments <= 0) {
3955 if (
nullptr == sec || 0 == (nval = section_list_size(sec))) {
3956 qCCritical(ruleset_category,
"\"%s\": No governments?!?", filename);
3958 }
else if (nval >
G_LAST) {
3959 qCCritical(ruleset_category,
"\"%s\": Too many governments (%d, max %d)",
3970 const char *sec_name =
3980 section_list_destroy(sec);
3984 nval = (
nullptr != sec ? section_list_size(sec) : 0);
3987 qCCritical(ruleset_category,
3988 "\"%s\": Too many multipliers (%d, max %d)", filename, nval,
3999 const char *sec_name =
4003 qCCritical(ruleset_category,
4004 "\"%s\": Cannot load multiplier names", filename);
4011 section_list_destroy(sec);
4023 struct section_list *sec;
4030 file,
"governments.during_revolution", filename,
nullptr);
4036 game.
info.government_during_revolution_id =
4042 const char *sec_name =
section_name(section_list_get(sec, i));
4046 if (
reqs ==
nullptr) {
4056 if (g.ai.better ==
nullptr) {
4061 g.ai.better =
nullptr;
4063 requirement_vector_copy(&g.reqs,
reqs);
4077 const char *sec_name =
4079 const char *male, *female;
4084 qCCritical(ruleset_category,
4085 "Lack of default ruler titles for "
4086 "government \"%s\" (nb %d): %s",
4093 qCCritical(ruleset_category,
4094 "Lack of default ruler titles for "
4095 "government \"%s\" (nb %d).",
4103 section_list_destroy(sec);
4110 const char *sec_name =
section_name(section_list_get(sec,
id));
4111 struct requirement_vector *
reqs;
4123 if (pmul->stop <= pmul->start) {
4124 qCCritical(ruleset_category,
4125 "Multiplier \"%s\" stop (%d) must be greater "
4136 if (((pmul->stop - pmul->start) % pmul->step) != 0) {
4137 qCCritical(ruleset_category,
4138 "Multiplier \"%s\" step (%d) does not fit "
4139 "exactly into interval start-stop (%d to %d)",
4150 if (pmul->def < pmul->start || pmul->def > pmul->stop) {
4151 qCCritical(ruleset_category,
4152 "Multiplier \"%s\" default (%d) not within "
4153 "legal range (%d to %d)",
4159 if (((pmul->def - pmul->start) % pmul->step) != 0) {
4160 qCCritical(ruleset_category,
4161 "Multiplier \"%s\" default (%d) not legal "
4162 "with respect to step size %d",
4171 if (pmul->factor == 0) {
4172 qCCritical(ruleset_category,
4173 "Multiplier \"%s\" scaling factor must "
4182 if (
reqs ==
nullptr) {
4186 requirement_vector_copy(&pmul->reqs,
reqs);
4191 section_list_destroy(sec);
4217 lsend_packet_ruleset_control(dest, &(
game.
control));
4220 struct packet_ruleset_summary summary;
4224 lsend_packet_ruleset_summary(dest, &summary);
4227 while (desc_left > 0) {
4228 struct packet_ruleset_description_part part;
4229 int this_len = desc_left;
4235 part.text[this_len] =
'\0';
4239 desc_left -= this_len;
4241 lsend_packet_ruleset_description_part(dest, &part);
4258 if (prev_leader == pleader) {
4277 struct section_list *sec;
4283 if (
compat->ver_nations <= 0) {
4291 if (
nullptr == sec) {
4292 qCCritical(ruleset_category,
"No available nations in this ruleset!");
4295 qCCritical(ruleset_category,
"Too many nations (max %d, we have %d)!",
4299 game.
control.nation_count = section_list_size(sec);
4304 const char *sec_name =
section_name(section_list_get(sec, i));
4306 file,
nullptr,
"%s.translation_domain", sec_name);
4307 const char *noun_plural =
4310 if (domain ==
nullptr) {
4311 domain =
"freeciv-nations";
4314 if (!strcmp(
"freeciv", domain)) {
4315 pl.translation_domain =
nullptr;
4316 }
else if (!strcmp(
"freeciv-nations", domain)) {
4317 pl.translation_domain =
new char[strlen(domain) + 1];
4318 qstrcpy(pl.translation_domain, domain);
4320 qCCritical(ruleset_category,
4321 "Unsupported translation domain \"%s\" for %s", domain,
4331 name_set(&pl.noun_plural, domain, noun_plural);
4334 for (j = 0; j < i && ok; j++) {
4344 qCCritical(ruleset_category,
4345 "Two nations defined with the same adjective \"%s\": "
4346 "in section \'%s\' and section \'%s\'",
4354 qCCritical(ruleset_category,
4355 "Two nations defined with the same rule_name \"%s\": "
4356 "in section \'%s\' and section \'%s\'",
4364 qCCritical(ruleset_category,
4365 "Two nations defined with the same plural name \"%s\": "
4366 "in section \'%s\' and section \'%s\'",
4378 section_list_destroy(sec);
4389 if (
nullptr ==
name) {
4395 if (pgroup ==
nullptr) {
4401 section_list_destroy(sec);
4417 for (i = 0; i <
len; i++) {
4431 const char *secfile_str1,
const char *secfile_str2,
4432 const char **allowed_terrains,
size_t atcount)
4437 secfile_str1, secfile_str2);
4444 for (j = 0; j < dim; j++) {
4446 char city_name[
len + 1], *p, *next, *end;
4456 if ((p = strchr(city_name,
'('))) {
4459 if (!(end = strchr(p,
')'))) {
4460 qCCritical(ruleset_category,
4461 "\"%s\" [%s] %s: city name \"%s\" "
4462 "unmatched parenthesis.",
4467 for (*end++ =
'\0';
'\0' != *end; end++) {
4468 if (!QChar::isSpace(*end)) {
4469 qCCritical(ruleset_category,
4470 "\"%s\" [%s] %s: city name \"%s\" "
4471 "contains characters after last parenthesis.",
4486 qCCritical(ruleset_category,
4487 "\"%s\" [%s] %s: city name \"%s\" "
4489 secfile_name(file), secfile_str1, secfile_str2, city_name);
4500 if ((next = strchr(p,
','))) {
4516 if (
game.
server.ruledit.allowed_terrains !=
nullptr
4519 qCCritical(ruleset_category,
4520 "\"%s\" [%s] %s: city \"%s\" "
4521 "has terrain hint \"%s\" not in allowed_terrains.",
4531 if (
nullptr == pterrain) {
4533 size_t l = qstrlen(p);
4535 if (0 < l &&
's' == QChar::toLower(p[l - 1])) {
4536 char saved = p[l - 1];
4540 if (pterrain ==
nullptr) {
4552 if (pterrain !=
nullptr
4553 &&
game.
server.ruledit.allowed_terrains !=
nullptr) {
4557 qCCritical(ruleset_category,
4558 "\"%s\" [%s] %s: city \"%s\" "
4559 "has terrain hint \"%s\" not in allowed_terrains.",
4565 }
else if (!pterrain) {
4568 if (
game.
server.ruledit.allowed_terrains ==
nullptr
4570 p,
game.
server.ruledit.allowed_terrains, atcount)) {
4571 qCCritical(ruleset_category,
4572 "\"%s\" [%s] %s: city \"%s\" "
4573 "has unknown terrain hint \"%s\".",
4580 if (
nullptr != pterrain) {
4585 p = next ? next + 1 :
nullptr;
4586 }
while (
nullptr != p &&
'\0' != *p);
4605 const char *
name, *bad_leader;
4609 struct section_list *sec =
nullptr;
4614 if (
name !=
nullptr) {
4619 "ruledit.embedded_nations");
4621 if (vec !=
nullptr) {
4624 new char *[
game.
server.ruledit.embedded_nations_count];
4626 for (j = 0; j <
game.
server.ruledit.embedded_nations_count; j++) {
4638 for (tr = trait_begin(); tr != trait_end(); tr = trait_next(tr)) {
4639 if (
game.
server.default_traits[tr].min < 0) {
4642 if (
game.
server.default_traits[tr].max < 0) {
4645 if (
game.
server.default_traits[tr].fixed < 0) {
4646 int diff =
game.
server.default_traits[tr].max
4651 diff / 2 +
game.
server.default_traits[tr].min;
4655 qCCritical(ruleset_category,
"Default values for trait %s not sane.",
4664 "compatibility.allowed_govs");
4665 if (vec !=
nullptr) {
4670 (
const char **)
game.
server.ruledit.nc_agovs;
4672 for (j = 0; j <
game.
server.ruledit.ag_count; j++) {
4681 "compatibility.allowed_terrains");
4682 if (vec !=
nullptr) {
4687 (
const char **)
game.
server.ruledit.nc_aterrs;
4689 for (j = 0; j <
game.
server.ruledit.at_count; j++) {
4698 "compatibility.allowed_styles");
4699 if (vec !=
nullptr) {
4704 (
const char **)
game.
server.ruledit.nc_astyles;
4706 for (j = 0; j <
game.
server.ruledit.as_count; j++) {
4715 "compatibility.default_government");
4719 if (sval !=
nullptr) {
4722 qCCritical(ruleset_category,
4723 "Tried to set unknown government type \"%s\" as "
4724 "default_government!",
4739 const char *set_name, *set_rule_name, *set_description;
4747 if (
nullptr == set_name ||
nullptr == set_rule_name) {
4759 section_list_destroy(sec);
4762 qCCritical(ruleset_category,
4764 "must be defined.");
4772 "compatibility.default_nationset");
4773 if (sval !=
nullptr) {
4775 if (pset !=
nullptr) {
4778 qCCritical(ruleset_category,
"Unknown default_nationset \"%s\".",
4803 if (pgroup ==
nullptr) {
4821 section_list_destroy(sec);
4828 for (
auto &pnation :
nations) {
4831 char tmp[200] =
"\0";
4833 const char *sec_name =
section_name(section_list_get(sec, i));
4837 if (default_set >= 0) {
4838 nation_set_list_append(pnation.sets,
4842 for (j = 0; j < dim; j++) {
4846 fc_assert(pset ==
nullptr || pgroup ==
nullptr);
4848 if (
nullptr != pset) {
4849 nation_set_list_append(pnation.sets, pset);
4850 }
else if (
nullptr != pgroup) {
4851 nation_group_list_append(pnation.groups, pgroup);
4857 qCDebug(ruleset_category,
"Nation %s: Unknown set/group \"%s\".",
4863 if (nation_set_list_size(pnation.sets) < 1) {
4864 qCCritical(ruleset_category,
4865 "Nation %s is not a member of any nation set",
4874 for (j = 0; j < dim; j++) {
4877 if (&pnation == pconflict) {
4878 qCCritical(ruleset_category,
"Nation %s conflicts with itself",
4882 }
else if (
nullptr != pconflict) {
4883 nation_list_append(pnation.server.conflicts_with, pconflict);
4889 qCDebug(ruleset_category,
4890 "Nation %s: conflicts_with nation \"%s\" is unknown.",
4903 bool is_male =
false;
4906 if (
nullptr ==
name) {
4916 qCCritical(ruleset_category,
4917 "Nation %s: leader name \"%s\" "
4925 if (
nullptr == sex) {
4926 qCCritical(ruleset_category,
"Nation %s: leader \"%s\": %s.",
4933 qCCritical(ruleset_category,
4934 "Nation %s: leader \"%s\" has unsupported "
4935 "sex variant \"%s\".",
4954 qCCritical(ruleset_category,
4955 "Nation %s: Too many leaders; max is %d",
4959 }
else if (0 == j) {
4960 qCCritical(ruleset_category,
4961 "Nation %s: no leaders; at least one is required.",
4969 qCCritical(ruleset_category,
4970 "Nation %s: leader \"%s\" defined more than once.",
4978 (void)
rgbcolor_load(file, &pnation.server.rgb,
"%s.color", sec_name);
4982 for (tr = trait_begin(); tr != trait_end(); tr = trait_next(tr)) {
4983 bool server_traits_used =
true;
4985 if (pnation.server.traits[tr].min < 0) {
4986 pnation.server.traits[tr].min =
game.
server.default_traits[tr].min;
4988 server_traits_used =
false;
4990 if (pnation.server.traits[tr].max < 0) {
4991 pnation.server.traits[tr].max =
game.
server.default_traits[tr].max;
4993 server_traits_used =
false;
4995 if (pnation.server.traits[tr].fixed < 0) {
4996 if (server_traits_used) {
4997 pnation.server.traits[tr].fixed =
5000 int diff = pnation.server.traits[tr].max
5001 - pnation.server.traits[tr].min;
5004 pnation.server.traits[tr].fixed =
5005 diff / 2 + pnation.server.traits[tr].min;
5008 if (pnation.server.traits[tr].max < pnation.server.traits[tr].min) {
5009 qCCritical(ruleset_category,
"%s values for trait %s not sane.",
5021 file,
true,
"%s.is_playable", sec_name);
5025 "%s.barbarian_type", sec_name);
5026 pnation.barb_type = barbarian_type_by_name(barb_type,
fc_strcasecmp);
5027 if (!barbarian_type_is_valid(pnation.barb_type)) {
5028 qCCritical(ruleset_category,
5029 "Nation %s, barbarian_type is invalid (\"%s\")",
5035 if (pnation.barb_type != NOT_A_BARBARIAN && pnation.is_playable) {
5038 qCCritical(ruleset_category,
5039 "Nation %s marked both barbarian and playable.",
5049 pnation.flag_graphic_alt,
5054 const char *male, *female;
5057 file,
nullptr,
"%s.ruler_titles%d.government", sec_name, j);
5058 if (
nullptr ==
name) {
5076 if (gov !=
nullptr &&
game.
server.ruledit.allowed_govs !=
nullptr) {
5081 qCCritical(ruleset_category,
5082 "Nation %s: government \"%s\" not in allowed_govs.",
5089 if (
game.
server.ruledit.allowed_govs ==
nullptr
5092 qCCritical(ruleset_category,
5093 "Nation %s: government \"%s\" not found.",
5099 if (
nullptr != male &&
nullptr != female) {
5121 if (pnation.style ==
nullptr) {
5122 if (
game.
server.ruledit.allowed_styles ==
nullptr
5125 qCCritical(ruleset_category,
"Nation %s: Illegal style \"%s\"",
5130 qCDebug(ruleset_category,
5131 "Nation %s: style \"%s\" not supported in this "
5132 "ruleset; using default.",
5141 for (j = 0; j < dim; j++) {
5147 if (pconflict == &pnation) {
5148 qCCritical(ruleset_category,
5149 "Nation %s is its own civil war nation",
5153 }
else if (
nullptr != pconflict) {
5154 nation_list_append(pnation.server.civilwar_nations, pconflict);
5155 nation_list_append(pconflict->
server.parent_nations, &pnation);
5161 qCDebug(ruleset_category,
5162 "Nation %s: civil war nation \"%s\" is unknown.",
5179 pnation.init_buildings, filename)) {
5191 pnation.init_government =
5195 if (pnation.init_government ==
nullptr) {
5201 if (
game.
server.ruledit.allowed_govs !=
nullptr
5206 qCCritical(ruleset_category,
5207 "Nation %s: init_government \"%s\" not allowed.",
5226 qCCritical(ruleset_category,
"Nation %s: legend \"%s\" is too long.",
5232 pnation.player =
nullptr;
5234 section_list_destroy(sec);
5241 section_list_destroy(sec);
5255 int num_playable = 0, barb_land_count = 0, barb_sea_count = 0,
5256 barb_both_count = 0;
5258 for (
auto &pnation :
nations) {
5261 case NOT_A_BARBARIAN:
5266 case LAND_BARBARIAN:
5272 case ANIMAL_BARBARIAN:
5275 case LAND_AND_SEA_BARBARIAN:
5283 if (num_playable < 1) {
5284 qCCritical(ruleset_category,
5285 "Nation set \"%s\" has no playable nations. "
5286 "At least one required!",
5291 if (barb_land_count == 0 && barb_both_count == 0) {
5292 qCCritical(ruleset_category,
5293 "No land barbarian nation defined in set \"%s\". "
5294 "At least one required!",
5299 if (barb_sea_count == 0 && barb_both_count == 0) {
5300 qCCritical(ruleset_category,
5301 "No sea barbarian nation defined in set \"%s\". "
5302 "At least one required!",
5322 struct section_list *sec;
5326 if (
compat->ver_styles <= 0) {
5334 if (
nullptr == sec) {
5335 qCCritical(ruleset_category,
5336 "No available nation styles in this ruleset!");
5346 const char *sec_name =
section_name(section_list_get(sec, i));
5353 section_list_destroy(sec);
5360 if (
nullptr != sec) {
5373 section_list_destroy(sec);
5388 struct section_list *sec;
5398 struct requirement_vector *
reqs;
5399 const char *sec_name =
section_name(section_list_get(sec, i));
5410 file,
"generic",
"%s.citizens_graphic_alt", sec_name));
5414 if (
reqs ==
nullptr) {
5421 section_list_destroy(sec);
5426 if (sec !=
nullptr) {
5429 game.
control.num_music_styles = section_list_size(sec);
5435 struct requirement_vector *
reqs;
5440 file,
"-",
"%s.music_peaceful", sec_name);
5452 if (
reqs ==
nullptr) {
5456 requirement_vector_copy(&pmus->
reqs,
reqs);
5463 section_list_destroy(sec);
5476 const char *uflags_path,
5477 const char *filename)
5482 enum unit_type_flag_id *protecor_flag;
5489 if (!protecor_flag) {
5491 qCCritical(ruleset_category,
"\"%s\": %s: bad unit type flag list.",
5492 filename, uflags_path);
5497 for (i = 0; i < psize; i++) {
5498 requirement_vector_append(&auto_perf->
reqs,
5504 delete[] protecor_flag;
5505 protecor_flag =
nullptr;
5517 const char *actions_path,
5518 const char *filename)
5522 enum gen_action *unit_acts;
5531 qCCritical(ruleset_category,
"\"%s\": %s: bad action list", filename,
5537 for (i = 0; i < asize; i++) {
5542 unit_acts =
nullptr;
5553 const char *
item,
const char *filename)
5555 char uflags_path[100];
5556 char action_path[100];
5559 "missing_unit_upkeep.%s_protected",
item);
5561 "missing_unit_upkeep.%s_unit_act",
item);
5576 struct section_list *sec;
5580 if (
compat->ver_cities <= 0) {
5589 if (section_list_size(sec) >=
SP_MAX) {
5590 qCCritical(ruleset_category,
5591 "\"%s\": Too many specialists (%d, max %d).", filename,
5592 section_list_size(sec),
SP_MAX);
5600 game.
control.num_specialist_types = section_list_size(sec);
5605 struct requirement_vector *
reqs;
5614 "%s.short_name", sec_name);
5618 if (tag ==
nullptr) {
5619 qCCritical(ruleset_category,
5620 "\"%s\": No graphic tag for specialist at %s.", filename,
5627 file,
"-",
"%s.graphic_alt", sec_name));
5631 if (
reqs ==
nullptr) {
5635 requirement_vector_copy(&s->
reqs,
reqs);
5639 if (requirement_vector_size(&s->
reqs) == 0
5649 qCCritical(ruleset_category,
5650 "\"%s\": must give a min_size of 0 for at least one "
5655 section_list_destroy(sec);
5669 "parameters.changeable_budget")) {
5671 qCWarning(ruleset_category,
5672 "parameters.changable_tax is deprecated; use "
5673 "parameters.changeable_budget instead.");
5687 qCCritical(ruleset_category,
5688 "\"%s\": Forced taxes do not add up in ruleset!", filename);
5697 "parameters.vision_reveal_tiles");
5719 auto_perf->
cause = AAPC_UNIT_UPKEEP;
5722 requirement_vector_append(
5724 req_from_str(
"OutputType",
"Local",
false,
true,
true,
"Food"));
5736 auto_perf->
cause = AAPC_UNIT_UPKEEP;
5739 requirement_vector_append(
5741 req_from_str(
"OutputType",
"Local",
false,
true,
true,
"Gold"));
5753 auto_perf->
cause = AAPC_UNIT_UPKEEP;
5756 requirement_vector_append(
5758 req_from_str(
"OutputType",
"Local",
false,
true,
true,
"Shield"));
5767 "missing_unit_upkeep.shield_wipe");
5783 struct section_list *sec;
5785 const char *filename;
5791 if (
compat->ver_effects <= 0) {
5804 enum effect_type eff;
5809 struct requirement_vector *
reqs;
5813 if (type ==
nullptr) {
5814 qCCritical(ruleset_category,
"\"%s\" [%s] missing effect type.",
5815 filename, sec_name);
5826 if (!effect_type_is_valid(eff)) {
5827 qCCritical(ruleset_category,
5828 "\"%s\" [%s] lists unknown effect type \"%s\".", filename,
5837 const char *multiplier_name =
5840 if (multiplier_name) {
5843 qCCritical(ruleset_category,
5844 "\"%s\" [%s] has unknown multiplier \"%s\".", filename,
5845 sec_name, multiplier_name);
5857 if (
reqs ==
nullptr) {
5868 if (
compat->compat_mode) {
5870 if (
reqs ==
nullptr) {
5876 preq->present = !preq->present;
5884 if (sec !=
nullptr) {
5885 section_list_destroy(sec);
5899 int def,
int min,
int max,
5900 const char *path, ...)
5906 va_start(args, path);
5915 qCCritical(ruleset_category,
5916 "\"%s\" should be in the interval [%d, %d] "
5917 "but is %d; using the minimal value.",
5918 fullpath, min, max, ival);
5923 qCCritical(ruleset_category,
5924 "\"%s\" should be in the interval [%d, %d] "
5925 "but is %d; using the maximal value.",
5926 fullpath, min, max, ival);
5953 struct entry *pentry;
5972 qCCritical(ruleset_category,
"Bad actions.%s",
6044 const char *sval, **svec;
6045 const char *filename;
6049 const char *pref_text;
6051 struct section_list *sec =
nullptr;
6056 if (file ==
nullptr) {
6063 if (
name !=
nullptr) {
6069 if (pref_text[0] !=
'\0') {
6070 qCWarning(deprecations_category,
6071 "Entry tileset.prefered in game.ruleset."
6072 " Use correct spelling tileset.preferred instead");
6076 if (pref_text[0] !=
'\0') {
6086 if (pref_text[0] !=
'\0') {
6087 qCWarning(deprecations_category,
6088 "Entry soundset.prefered in game.ruleset."
6089 " Use correct spelling soundset.preferred instead");
6093 if (pref_text[0] !=
'\0') {
6103 if (pref_text[0] !=
'\0') {
6104 qCWarning(deprecations_category,
6105 "Entry musicset.prefered in game.ruleset."
6106 " Use correct spelling musicset.preferred instead");
6110 if (pref_text[0] !=
'\0') {
6124 if (pref_text[0] !=
'\0') {
6133 if (pref_text[0] !=
'\0') {
6142 if (pref_text[0] !=
'\0') {
6146 len = qstrlen(pref_text);
6158 if (pref_text[0] !=
'\0') {
6162 len = qstrlen(pref_text);
6176 if (pref_text[0] !=
'\0') {
6177 int len = qstrlen(pref_text);
6210 game.
info.gameloss_style = GAMELOSS_STYLE_CLASSICAL;
6213 for (j = 0; j < nval; j++) {
6214 enum gameloss_style style;
6217 if (strcmp(sval,
"") == 0) {
6221 if (!gameloss_style_is_valid(style)) {
6222 qCCritical(ruleset_category,
6223 "\"%s\": bad value \"%s\" for gameloss_style.", filename,
6229 gameloss_style(
game.
info.gameloss_style | style);
6239 "civstyle.initial_diplomatic_state");
6242 if (!diplstate_type_is_valid(
game.
server.initial_diplomatic_state)) {
6243 qCritical() <<
"Invalid value for initial_diplomatic_state:"
6252 "civstyle.happy_cost");
6255 "civstyle.food_cost");
6257 file,
true,
"civstyle.civil_war_enabled");
6259 game.
info.civil_war_bonus_celebrating =
6261 "civstyle.civil_war_bonus_celebrating");
6263 game.
info.civil_war_bonus_unhappy =
6265 "civstyle.civil_war_bonus_unhappy");
6268 file,
false,
"civstyle.paradrop_to_transport");
6277 "civstyle.ransom_gold");
6284 "civstyle.tech_steal_allow_holes");
6287 "civstyle.tech_trade_allow_holes");
6288 game.
info.tech_trade_loss_allow_holes =
6290 "civstyle.tech_trade_loss_allow_holes");
6291 game.
info.tech_parasite_allow_holes =
6293 "civstyle.tech_parasite_allow_holes");
6306 "civstyle.autoupgrade_veteran_loss");
6314 game.
info.granary_num_inis =
static_cast<int>(gni_tmp);
6317 qCCritical(ruleset_category,
6318 "Too many granary_food_ini entries (%d, max %d)",
6321 }
else if (
game.
info.granary_num_inis == 0) {
6322 qCritical(
"No values for granary_food_ini. Using default "
6331 for (gi = 0; gi <
game.
info.granary_num_inis; gi++) {
6332 if (food_ini && food_ini[gi] <= 0) {
6336 food_ini[gi] = food_ini[gi - 1];
6338 qCritical(
"Bad value for granary_food_ini[%i]. Using %i.", gi,
6341 game.
info.granary_food_ini[gi] = food_ini[gi];
6355 game.
info.min_city_center_output[o] =
6365 const char *tus_text;
6376 "civstyle.gold_upkeep_style");
6379 if (!gold_upkeep_style_is_valid(
game.
info.gold_upkeep_style)) {
6380 qCCritical(ruleset_category,
"Unknown gold upkeep style \"%s\"",
6401 "illness.illness_trade_infection");
6414 "incite_cost.improvement_factor");
6438 struct requirement_vector *
reqs;
6443 auto_perf->
cause = AAPC_UNIT_MOVED_ADJ;
6447 if (
reqs ==
nullptr) {
6451 requirement_vector_copy(&auto_perf->
reqs,
reqs);
6454 file, auto_perf,
"auto_attack.attack_actions", filename)) {
6456 qCCritical(ruleset_category,
"\"%s\": %s: failed load %s.", filename,
6457 "auto_attack",
"attack_actions");
6461 if (
compat->compat_mode) {
6462 enum unit_type_flag_id *protecor_flag;
6468 "auto_attack.will_never");
6470 if (!protecor_flag) {
6472 qCCritical(ruleset_category,
6473 "\"%s\": %s: bad unit type flag list.", filename,
6474 "auto_attack.will_never");
6480 protecor_flag =
nullptr;
6486 qCCritical(ruleset_category,
"\"%s\": %s: failed to upgrade.",
6487 filename,
"auto_attack");
6492 delete[] protecor_flag;
6493 protecor_flag =
nullptr;
6500 int force_capture_units, force_bombard, force_explode_nuclear;
6503 "actions.force_trade_route")) {
6507 ACTION_TRADE_ROUTE);
6512 force_capture_units =
6514 "actions.force_capture_units");
6516 if (force_capture_units) {
6518 ACTION_CAPTURE_UNITS);
6520 ACTION_CAPTURE_UNITS);
6522 ACTION_CAPTURE_UNITS);
6524 ACTION_CAPTURE_UNITS);
6526 ACTION_CAPTURE_UNITS);
6528 ACTION_CAPTURE_UNITS);
6530 ACTION_CAPTURE_UNITS);
6532 ACTION_CAPTURE_UNITS);
6534 ACTION_CAPTURE_UNITS);
6536 ACTION_CAPTURE_UNITS);
6544 if (force_bombard) {
6584 force_explode_nuclear =
6586 "actions.force_explode_nuclear");
6588 if (force_explode_nuclear) {
6620 "actions.poison_empties_food_stock");
6626 "actions.steal_maps_reveals_all_cities");
6650 enum gen_action *quiet_actions;
6655 "actions.quiet_actions");
6657 if (!quiet_actions) {
6659 qCCritical(ruleset_category,
6660 "\"%s\": actions.quiet_actions: bad action list",
6666 for (j = 0; j < asize; j++) {
6671 delete[] quiet_actions;
6672 quiet_actions =
nullptr;
6686 struct requirement_vector *actor_reqs;
6687 struct requirement_vector *target_reqs;
6688 const char *action_text;
6694 if (action_text ==
nullptr) {
6695 qCCritical(ruleset_category,
6696 "\"%s\" [%s] missing action to enable.", filename,
6704 qCCritical(ruleset_category,
6705 "\"%s\" [%s] lists unknown action type \"%s\".",
6706 filename, sec_name, action_text);
6715 if (actor_reqs ==
nullptr) {
6720 requirement_vector_copy(&enabler->
actor_reqs, actor_reqs);
6723 "target_reqs", action_text);
6724 if (target_reqs ==
nullptr) {
6729 requirement_vector_copy(&enabler->
target_reqs, target_reqs);
6734 section_list_destroy(sec);
6739 if (
compat->compat_mode) {
6741 file,
true,
"global_unit_options.slow_invasions");
6749 const char *tus_text;
6757 "combat_rules.only_killing_makes_veteran");
6763 game.
info.nuke_defender_survival_chance_pct =
6768 "combat_rules.nuke_defender_survival_chance_pct");
6778 game.
info.border_city_permanent_radius_sq =
6783 "borders.radius_sq_city_permanent");
6787 "research.tech_cost_style");
6790 if (!tech_cost_style_is_valid(
game.
info.tech_cost_style)) {
6791 qCCritical(ruleset_category,
"Unknown tech cost style \"%s\"",
6797 "research.tech_leakage");
6800 if (!tech_leakage_style_is_valid(
game.
info.tech_leakage)) {
6801 qCCritical(ruleset_category,
"Unknown tech leakage \"%s\"", tus_text);
6804 if (
game.
info.tech_cost_style == TECH_COST_CIV1CIV2
6805 &&
game.
info.tech_leakage != TECH_LEAKAGE_NONE) {
6806 qCritical(
"Only tech_leakage \"%s\" supported with "
6807 "tech_cost_style \"%s\". ",
6808 tech_leakage_style_name(TECH_LEAKAGE_NONE),
6809 tech_cost_style_name(TECH_COST_CIV1CIV2));
6810 qCritical(
"Switching to tech_leakage \"%s\".",
6811 tech_leakage_style_name(TECH_LEAKAGE_NONE));
6812 game.
info.tech_leakage = TECH_LEAKAGE_NONE;
6819 "research.tech_upkeep_style");
6824 if (!tech_upkeep_style_is_valid(
game.
info.tech_upkeep_style)) {
6825 qCCritical(ruleset_category,
"Unknown tech upkeep style \"%s\"",
6837 "research.free_tech_method");
6838 if (sval ==
nullptr) {
6839 qCCritical(ruleset_category,
"No free_tech_method given");
6844 if (!free_tech_method_is_valid(
game.
info.free_tech_method)) {
6845 qCCritical(ruleset_category,
"Bad value %s for free_tech_method.",
6864 "culture.history_interest_pml");
6875 qCCritical(ruleset_category,
"Too many calendar fragments. Max is %d",
6882 "calendar.positive_label"));
6885 "calendar.negative_label"));
6887 for (cf = 0; cf <
game.
calendar.calendar_fragments; cf++) {
6891 "calendar.fragment_name%d", cf);
6892 if (fname !=
nullptr) {
6893 qstrncpy(
game.
calendar.calendar_fragment_name[cf], fname,
6901 struct rgbcolor *prgbcolor =
nullptr;
6902 bool color_read =
true;
6910 while (color_read) {
6911 prgbcolor =
nullptr;
6914 rgbcolor_load(file, &prgbcolor,
"playercolors.colorlist%d", i);
6923 qCCritical(ruleset_category,
"No player colors defined!");
6930 "playercolors.background")) {
6931 qCCritical(ruleset_category,
6932 "No background player color defined! (%s)",
6947 for (i = 0; i < teams; i++) {
6954 nval = (
nullptr != sec ? section_list_size(sec) : 0);
6958 qCCritical(ruleset_category,
6959 "\"%s\": Too many disaster types (%d, max %d)", filename,
6961 section_list_destroy(sec);
6974 struct requirement_vector *
reqs;
6975 const char *sec_name =
section_name(section_list_get(sec,
id));
6978 qCCritical(ruleset_category,
"\"%s\": Cannot load disaster names",
6986 if (
reqs ==
nullptr) {
6990 requirement_vector_copy(&pdis->reqs,
reqs);
6999 for (j = 0; j < eff_count; j++) {
7000 const char *dsval = svec[j];
7001 enum disaster_effect_id
effect;
7005 if (!disaster_effect_id_is_valid(
effect)) {
7006 qCCritical(ruleset_category,
7007 "\"%s\" disaster \"%s\": unknown effect \"%s\".",
7024 section_list_destroy(sec);
7033 const char *sec_name =
section_name(section_list_get(sec,
id));
7034 const char *type_name;
7040 pach->type = achievement_type_by_name(type_name,
fc_strcasecmp);
7041 if (!achievement_type_is_valid(pach->type)) {
7042 qCCritical(ruleset_category,
"Achievement has unknown type \"%s\".",
7043 type_name !=
nullptr ? type_name :
"(nullptr)");
7058 if (msg ==
nullptr) {
7059 qCCritical(ruleset_category,
"Achievement %s has no first msg!",
7070 if (msg ==
nullptr) {
7071 if (!pach->unique) {
7072 qCCritical(ruleset_category,
7073 "Achievement %s has no msg for consecutive gainers!",
7087 section_list_destroy(sec);
7092 file,
nullptr,
"trade.settings%d.type", i));
7097 qCCritical(ruleset_category,
7098 "\"%s\" unknown trade route type \"%s\".", filename,
7110 file,
"Active",
"trade.settings%d.cancelling", i);
7113 qCCritical(ruleset_category,
7114 "\"%s\" unknown traderoute cancelling type \"%s\".",
7120 "trade.settings%d.bonus", i);
7125 if (!traderoute_bonus_type_is_valid(set->
bonus_type)) {
7126 qCCritical(ruleset_category,
7127 "\"%s\" unknown traderoute bonus type \"%s\".",
7142 if (!goods_selection_method_is_valid(
game.
info.goods_selection)) {
7143 qCCritical(ruleset_category,
7144 "\"%s\" goods selection method \"%s\" unknown.", filename,
7156 const char *sec_name =
section_name(section_list_get(sec,
id));
7157 struct requirement_vector *
reqs;
7163 if (
reqs ==
nullptr) {
7167 requirement_vector_copy(&pgood->reqs,
reqs);
7173 pgood->onetime_pct =
7178 for (j = 0; j < nval; j++) {
7179 enum goods_flag_id flag;
7183 if (!goods_flag_id_is_valid(flag)) {
7184 qCCritical(ruleset_category,
7185 "\"%s\" good \"%s\": unknown flag \"%s\".", filename,
7190 BV_SET(pgood->flags, flag);
7196 pgood->helptext =
lookup_strvec(file, sec_name,
"helptext");
7199 section_list_destroy(sec);
7205 if (sec !=
nullptr) {
7206 int num = section_list_size(sec);
7208 for (i = 0; i < num; i++) {
7209 const char *sec_name =
section_name(section_list_get(sec, i));
7210 const char *clause_name =
7212 enum clause_type type =
7215 struct requirement_vector *
reqs;
7217 if (!clause_type_is_valid(type)) {
7218 qCCritical(ruleset_category,
"\"%s\" unknown clause type \"%s\".",
7219 filename, clause_name);
7227 qCCritical(ruleset_category,
7228 "\"%s\" dublicate clause type \"%s\" definition.",
7229 filename, clause_name);
7236 if (
reqs ==
nullptr) {
7244 if (
reqs ==
nullptr) {
7253 section_list_destroy(sec);
7268 struct packet_ruleset_unit_class packet;
7269 struct packet_ruleset_unit_class_flag fpacket;
7273 const char *flagname;
7274 const char *helptxt;
7276 fpacket.id = i + UCF_USER_FLAG_1;
7279 unit_class_flag_id_name(unit_class_flag_id(i + UCF_USER_FLAG_1));
7280 if (flagname ==
nullptr) {
7281 fpacket.name[0] =
'\0';
7288 if (helptxt ==
nullptr) {
7289 fpacket.helptxt[0] =
'\0';
7294 lsend_packet_ruleset_unit_class_flag(dest, &fpacket);
7302 packet.min_speed = c->min_speed;
7303 packet.hp_loss_pct = c->hp_loss_pct;
7304 packet.hut_behavior = c->hut_behavior;
7305 packet.non_native_def_pct = c->non_native_def_pct;
7306 packet.flags = c->flags;
7310 lsend_packet_ruleset_unit_class(dest, &packet);
7321 struct packet_ruleset_unit packet;
7322 struct packet_ruleset_unit_flag fpacket;
7326 const char *flagname;
7327 const char *helptxt;
7329 fpacket.id = i + UTYF_USER_FLAG_1;
7332 unit_type_flag_id_name(unit_type_flag_id(i + UTYF_USER_FLAG_1));
7333 if (flagname ==
nullptr) {
7334 fpacket.name[0] =
'\0';
7341 if (helptxt ==
nullptr) {
7342 fpacket.helptxt[0] =
'\0';
7347 lsend_packet_ruleset_unit_flag(dest, &fpacket);
7355 sz_strlcpy(packet.sound_move, u->sound_move);
7356 sz_strlcpy(packet.sound_move_alt, u->sound_move_alt);
7357 sz_strlcpy(packet.sound_fight, u->sound_fight);
7358 sz_strlcpy(packet.sound_fight_alt, u->sound_fight_alt);
7359 sz_strlcpy(packet.graphic_str, u->graphic_str);
7360 sz_strlcpy(packet.graphic_alt, u->graphic_alt);
7362 packet.build_cost = u->build_cost;
7363 packet.pop_cost = u->pop_cost;
7364 packet.attack_strength = u->attack_strength;
7365 packet.defense_strength = u->defense_strength;
7366 packet.move_rate = u->move_rate;
7367 packet.tech_requirement = u->require_advance
7374 packet.build_reqs[i++] = *req;
7377 packet.build_reqs_count = i;
7379 packet.vision_radius_sq = u->vision_radius_sq;
7380 packet.transport_capacity = u->transport_capacity;
7382 packet.firepower = u->firepower;
7383 packet.obsoleted_by =
7385 packet.converted_to =
7387 packet.convert_time = u->convert_time;
7388 packet.fuel = u->fuel;
7389 packet.flags = u->flags;
7390 packet.roles = u->roles;
7391 packet.happy_cost = u->happy_cost;
7394 packet.paratroopers_range = u->paratroopers_range;
7395 packet.bombard_rate = u->bombard_rate;
7396 packet.city_size = u->city_size;
7397 packet.city_slots = u->city_slots;
7398 packet.cargo = u->cargo;
7399 packet.targets = u->targets;
7400 packet.embarks = u->embarks;
7401 packet.disembarks = u->disembarks;
7402 packet.vlayer = u->vlayer;
7404 if (u->veteran ==
nullptr) {
7406 packet.veteran_levels = 0;
7411 for (i = 0; i < packet.veteran_levels; i++) {
7423 packet.worker = u->adv.worker;
7425 lsend_packet_ruleset_unit(dest, &packet);
7429 struct packet_ruleset_unit_bonus bonuspacket;
7431 bonuspacket.unit = packet.id;
7432 bonuspacket.flag = pbonus->flag;
7433 bonuspacket.type = pbonus->type;
7434 bonuspacket.value = pbonus->value;
7435 bonuspacket.quiet = pbonus->quiet;
7437 lsend_packet_ruleset_unit_bonus(dest, &bonuspacket);
7450 struct packet_ruleset_specialist packet;
7457 packet.id = spec_id;
7466 packet.reqs_count = j;
7470 lsend_packet_ruleset_specialist(dest, &packet);
7479 struct packet_ruleset_tech_class packet;
7483 packet.id = ptclass->idx;
7486 packet.cost_pct = ptclass->cost_pct;
7488 lsend_packet_ruleset_tech_class(dest, &packet);
7499 struct packet_ruleset_tech packet;
7500 struct packet_ruleset_tech_flag fpacket;
7504 const char *flagname;
7505 const char *helptxt;
7507 fpacket.id = i + TECH_USER_1;
7510 if (flagname ==
nullptr) {
7511 fpacket.name[0] =
'\0';
7517 if (helptxt ==
nullptr) {
7518 fpacket.helptxt[0] =
'\0';
7523 lsend_packet_ruleset_tech_flag(dest, &fpacket);
7530 if (a->tclass ==
nullptr) {
7533 packet.tclass = a->tclass->idx;
7537 sz_strlcpy(packet.graphic_str, a->graphic_str);
7538 sz_strlcpy(packet.graphic_alt, a->graphic_alt);
7549 packet.research_reqs[i++] =
7556 packet.research_reqs[i++] =
7566 packet.research_reqs[i++] = *req;
7572 packet.research_reqs_count = i;
7574 packet.root_req = a->require[
AR_ROOT]
7578 packet.flags = a->flags;
7579 packet.cost = a->cost;
7580 packet.num_reqs = a->num_reqs;
7583 lsend_packet_ruleset_tech(dest, &packet);
7596 struct packet_ruleset_building packet;
7600 packet.genus = b->genus;
7603 sz_strlcpy(packet.graphic_str, b->graphic_str);
7604 sz_strlcpy(packet.graphic_alt, b->graphic_alt);
7608 packet.reqs_count = j;
7612 packet.obs_reqs[j++] = *pobs;
7615 packet.obs_count = j;
7616 packet.build_cost = b->build_cost;
7617 packet.upkeep = b->upkeep;
7618 packet.sabotage = b->sabotage;
7619 packet.flags = b->flags;
7621 sz_strlcpy(packet.soundtag_alt, b->soundtag_alt);
7624 lsend_packet_ruleset_building(dest, &packet);
7635 struct packet_ruleset_terrain packet;
7636 struct packet_ruleset_terrain_flag fpacket;
7642 const char *flagname;
7643 const char *helptxt;
7645 fpacket.id = i + TER_USER_1;
7648 if (flagname ==
nullptr) {
7649 fpacket.name[0] =
'\0';
7655 if (helptxt ==
nullptr) {
7656 fpacket.helptxt[0] =
'\0';
7661 lsend_packet_ruleset_terrain_flag(dest, &fpacket);
7669 packet.tclass = pterrain->tclass;
7670 packet.native_to = pterrain->native_to;
7674 sz_strlcpy(packet.graphic_str, pterrain->graphic_str);
7675 sz_strlcpy(packet.graphic_alt, pterrain->graphic_alt);
7677 packet.movement_cost = pterrain->movement_cost;
7678 packet.defense_bonus = pterrain->defense_bonus;
7683 packet.num_resources = 0;
7684 for (r = pterrain->resources; *r; r++) {
7685 packet.resources[packet.num_resources++] =
extra_number(*r);
7690 packet.road_output_incr_pct[o] = pterrain->road_output_incr_pct[o];
7694 packet.base_time = pterrain->base_time;
7695 packet.road_time = pterrain->road_time;
7697 packet.cultivate_time = pterrain->cultivate_time;
7699 packet.plant_time = pterrain->plant_time;
7701 packet.irrigation_result =
7702 (pterrain->irrigation_result
7705 packet.irrigation_food_incr = pterrain->irrigation_food_incr;
7706 packet.irrigation_time = pterrain->irrigation_time;
7708 packet.mining_result =
7709 (pterrain->mining_result ?
terrain_number(pterrain->mining_result)
7711 packet.mining_shield_incr = pterrain->mining_shield_incr;
7712 packet.mining_time = pterrain->mining_time;
7715 (pterrain->animal ==
nullptr ? -1 :
utype_number(pterrain->animal));
7716 packet.transform_result =
7717 (pterrain->transform_result
7720 packet.placing_time = pterrain->placing_time;
7721 packet.pillage_time = pterrain->pillage_time;
7722 packet.transform_time = pterrain->transform_time;
7723 packet.clean_pollution_time = pterrain->clean_pollution_time;
7724 packet.clean_fallout_time = pterrain->clean_fallout_time;
7726 packet.flags = pterrain->flags;
7728 packet.color_red = pterrain->rgb->r;
7729 packet.color_green = pterrain->rgb->g;
7730 packet.color_blue = pterrain->rgb->b;
7734 lsend_packet_ruleset_terrain(dest, &packet);
7744 struct packet_ruleset_resource packet;
7752 packet.output[o] = presource->data.resource->output[o];
7756 lsend_packet_ruleset_resource(dest, &packet);
7767 struct packet_ruleset_extra packet;
7768 struct packet_ruleset_extra_flag fpacket;
7772 const char *flagname;
7773 const char *helptxt;
7775 fpacket.id = i + EF_USER_FLAG_1;
7777 flagname = extra_flag_id_name(extra_flag_id(i + EF_USER_FLAG_1));
7778 if (flagname ==
nullptr) {
7779 fpacket.name[0] =
'\0';
7785 if (helptxt ==
nullptr) {
7786 fpacket.helptxt[0] =
'\0';
7791 lsend_packet_ruleset_extra_flag(dest, &fpacket);
7802 packet.category = e->category;
7805 for (j = 0; j < EC_COUNT; j++) {
7807 BV_SET(packet.causes, j);
7812 for (j = 0; j < ERM_COUNT; j++) {
7814 BV_SET(packet.rmcauses, j);
7818 sz_strlcpy(packet.activity_gfx, e->activity_gfx);
7819 sz_strlcpy(packet.act_gfx_alt, e->act_gfx_alt);
7820 sz_strlcpy(packet.act_gfx_alt2, e->act_gfx_alt2);
7822 sz_strlcpy(packet.rmact_gfx_alt, e->rmact_gfx_alt);
7823 sz_strlcpy(packet.graphic_str, e->graphic_str);
7824 sz_strlcpy(packet.graphic_alt, e->graphic_alt);
7829 packet.reqs_count = j;
7834 packet.rmreqs[j++] = *preq;
7837 packet.rmreqs_count = j;
7839 packet.appearance_chance = e->appearance_chance;
7843 packet.appearance_reqs[j++] = *preq;
7846 packet.appearance_reqs_count = j;
7848 packet.disappearance_chance = e->disappearance_chance;
7852 packet.disappearance_reqs[j++] = *preq;
7855 packet.disappearance_reqs_count = j;
7857 packet.visibility_req = e->visibility_req;
7858 packet.buildable = e->buildable;
7859 packet.generated = e->generated;
7860 packet.build_time = e->build_time;
7861 packet.build_time_factor = e->build_time_factor;
7862 packet.removal_time = e->removal_time;
7863 packet.removal_time_factor = e->removal_time_factor;
7865 packet.defense_bonus = e->defense_bonus;
7866 packet.eus = e->eus;
7868 packet.native_to = e->native_to;
7870 packet.flags = e->flags;
7871 packet.hidden_by = e->hidden_by;
7872 packet.bridged_over = e->bridged_over;
7873 packet.conflicts = e->conflicts;
7877 lsend_packet_ruleset_extra(dest, &packet);
7891 struct packet_ruleset_base packet;
7901 packet.flags = b->
flags;
7903 lsend_packet_ruleset_base(dest, &packet);
7914 struct packet_ruleset_road packet;
7926 packet.first_reqs[j++] = *preq;
7929 packet.first_reqs_count = j;
7942 packet.compat = r->
compat;
7945 packet.flags = r->
flags;
7947 lsend_packet_ruleset_road(dest, &packet);
7958 struct packet_ruleset_goods packet;
7971 packet.reqs_count = j;
7973 packet.from_pct = g->from_pct;
7974 packet.to_pct = g->to_pct;
7975 packet.onetime_pct = g->onetime_pct;
7976 packet.flags = g->flags;
7980 lsend_packet_ruleset_goods(dest, &packet);
7991 struct packet_ruleset_disaster packet;
8005 packet.reqs_count = j;
8007 packet.frequency = d->frequency;
8009 packet.effects = d->effects;
8011 lsend_packet_ruleset_disaster(dest, &packet);
8022 struct packet_ruleset_achievement packet;
8031 packet.type = a->type;
8032 packet.unique = a->unique;
8033 packet.value = a->value;
8035 lsend_packet_ruleset_achievement(dest, &packet);
8045 struct packet_ruleset_action packet;
8055 packet.result = paction->
result;
8066 lsend_packet_ruleset_action(dest, &packet);
8077 struct packet_ruleset_action_enabler packet;
8081 packet.enabled_action = enabler->action;
8086 packet.actor_reqs[counter++] = *req;
8089 packet.actor_reqs_count = counter;
8094 packet.target_reqs[counter++] = *req;
8097 packet.target_reqs_count = counter;
8099 lsend_packet_ruleset_action_enabler(dest, &packet);
8112 struct packet_ruleset_action_auto packet;
8119 packet.cause = aperf->cause;
8124 packet.reqs[counter++] = *req;
8127 packet.reqs_count = counter;
8135 packet.alternatives[counter] = aperf->alternatives[counter];
8137 packet.alternatives_count = counter;
8139 lsend_packet_ruleset_action_auto(dest, &packet);
8150 struct packet_ruleset_trade packet;
8162 lsend_packet_ruleset_trade(dest, &packet);
8172 struct packet_ruleset_government gov;
8173 struct packet_ruleset_government_ruler_title title;
8191 lsend_packet_ruleset_government(dest, &gov);
8206 lsend_packet_ruleset_government_ruler_title(dest, &title);
8218 struct packet_ruleset_nation_sets sets_packet;
8219 struct packet_ruleset_nation_groups groups_packet;
8220 struct packet_ruleset_nation packet;
8233 lsend_packet_ruleset_nation_sets(dest, &sets_packet);
8241 groups_packet.hidden[i] = pgroup->hidden;
8245 lsend_packet_ruleset_nation_groups(dest, &groups_packet);
8247 for (
const auto &n :
nations) {
8249 if (n.translation_domain ==
nullptr) {
8250 packet.translation_domain[0] =
'\0';
8252 sz_strlcpy(packet.translation_domain, n.translation_domain);
8257 sz_strlcpy(packet.graphic_str, n.flag_graphic_str);
8258 sz_strlcpy(packet.graphic_alt, n.flag_graphic_alt);
8268 packet.leader_count = i;
8271 packet.is_playable = n.is_playable;
8272 packet.barbarian_type = n.barb_type;
8292 packet.init_government_id = n.init_government
8297 if (n.init_techs[i] !=
A_LAST) {
8298 packet.init_techs[i] = n.init_techs[i];
8303 packet.init_techs_count = i;
8306 const struct unit_type *t = n.init_units[i];
8313 packet.init_units_count = i;
8317 if (n.init_buildings[i] !=
B_LAST) {
8319 packet.init_buildings[i] = n.init_buildings[i];
8324 packet.init_buildings_count = i;
8326 lsend_packet_ruleset_nation(dest, &packet);
8339 struct packet_ruleset_style packet;
8347 lsend_packet_ruleset_style(dest, &packet);
8357 struct packet_ruleset_clause packet;
8360 for (i = 0; i < CLAUSE_COUNT; i++) {
8364 packet.type = clause_type(i);
8365 packet.enabled = info->
enabled;
8370 packet.giver_reqs[j++] = *preq;
8373 packet.giver_reqs_count = j;
8378 packet.receiver_reqs[j++] = *preq;
8381 packet.receiver_reqs_count = j;
8383 lsend_packet_ruleset_clause(dest, &packet);
8396 struct packet_ruleset_multiplier packet;
8399 packet.start = pmul->start;
8400 packet.stop = pmul->stop;
8401 packet.step = pmul->step;
8402 packet.def = pmul->def;
8403 packet.offset = pmul->offset;
8404 packet.factor = pmul->factor;
8412 packet.reqs[j++] = *preq;
8415 packet.reqs_count = j;
8419 lsend_packet_ruleset_multiplier(dest, &packet);
8430 struct packet_ruleset_city city_p;
8434 city_p.style_id = k;
8439 city_p.reqs[j++] = *preq;
8442 city_p.reqs_count = j;
8452 lsend_packet_ruleset_city(dest, &city_p);
8462 struct packet_ruleset_music packet;
8468 packet.id = pmus->id;
8470 sz_strlcpy(packet.music_peaceful, qUtf8Printable(pmus->music_peaceful));
8471 sz_strlcpy(packet.music_combat, qUtf8Printable(pmus->music_combat));
8476 packet.reqs[j++] = *preq;
8479 packet.reqs_count = j;
8481 lsend_packet_ruleset_music(dest, &packet);
8492 struct packet_ruleset_game misc_p;
8500 for (i = 0; i < misc_p.veteran_levels; i++) {
8510 fc_assert(
sizeof(misc_p.global_init_techs)
8521 misc_p.global_init_techs_count = i;
8533 misc_p.global_init_buildings_count = i;
8543 lsend_packet_ruleset_game(dest, &misc_p);
8552 struct packet_team_name_info team_name_info_p;
8558 if (
nullptr ==
name) {
8566 lsend_packet_team_name_info(dest, &team_name_info_p);
8587 buffer_script, load_luadata)) {
8591 if (alt !=
nullptr) {
8601 if (restore !=
nullptr) {
8607 _(
"Ruleset couldn't be loaded. Keeping previous one."));
8620 buffer_script,
true)) {
8627 _(
"Ruleset couldn't be loaded. Switching to default one."));
8642 if (file !=
nullptr) {
8663 bool buffer_script,
bool load_luadata)
8665 struct section_file *techfile, *unitfile, *buildfile, *govfile, *terrfile;
8666 struct section_file *stylefile, *cityfile, *nationfile, *effectfile,
8671 qInfo(
_(
"Loading rulesets."));
8674 compat_info.
log_cb = logger;
8687 server.playable_nations = 0;
8705 if (techfile ==
nullptr || buildfile ==
nullptr || govfile ==
nullptr
8706 || unitfile ==
nullptr || terrfile ==
nullptr || stylefile ==
nullptr
8707 || cityfile ==
nullptr || nationfile ==
nullptr
8708 || effectfile ==
nullptr || gamefile ==
nullptr) {
8827 if (pret ==
TRI_MAYBE && buffer_script) {
8829 "parsing luadata.txt\n-- of this ruleset.");
8835 if (ok && !buffer_script) {
8874 if (file ==
nullptr) {
8875 qCCritical(ruleset_category,
"Could not load game.ruleset:\n%s",
8927 lsend_packet_rulesets_ready(dest);
int achievement_index(const struct achievement *pach)
Return the achievement index.
int achievement_number(const struct achievement *pach)
Return the achievement id.
#define achievements_iterate_end
#define achievements_iterate(_ach_)
const char * action_max_range_ruleset_var_name(int act)
Return max range ruleset variable name for the action or nullptr if max range can't be set in the rul...
const char * action_ui_name_ruleset_var_name(int act)
Return ui_name ruleset variable name for the action.
const char * action_ui_name_default(int act)
Return default ui_name for the action.
int action_max_range_default(int act)
Return default max range for the action if it is ruleset settable.
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Return actor consuming always ruleset variable name for the action or nullptr if actor consuming alwa...
const char * action_min_range_ruleset_var_name(int act)
Return min range ruleset variable name for the action or nullptr if min range can't be set in the rul...
struct action * action_by_rule_name(const char *name)
Return the action with the given name.
const char * action_target_kind_ruleset_var_name(int act)
Return target kind ruleset variable name for the action or nullptr if min range can't be set in the r...
struct action_enabler * action_enabler_new()
Create a new action enabler.
void action_enabler_add(struct action_enabler *enabler)
Add an action enabler to the current ruleset.
struct action * action_by_number(action_id act_id)
Return the action with the given id.
int action_min_range_default(int act)
Return default min range for the action if it is ruleset settable.
void actions_rs_pre_san_gen()
Generate action related data based on the currently loaded ruleset.
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Returns action auto performer rule slot number num so it can be filled.
#define action_auto_perf_iterate_end
#define action_enablers_iterate_end
#define ACTION_AUTO_MOVED_ADJ
#define action_id_get_sub_target_kind(act_id)
#define ACTION_AUTO_UPKEEP_GOLD
#define ACTION_DISTANCE_UNLIMITED
#define ACTION_AUTO_UPKEEP_SHIELD
#define action_iterate_end
#define action_enablers_iterate(_enabler_)
#define action_iterate(_act_)
#define action_auto_perf_iterate(_act_perf_)
#define ACTION_AUTO_UPKEEP_FOOD
void adv_units_ruleset_init()
Initialise the unit data from the ruleset for the advisors.
#define CALL_FUNC_EACH_AI(_func,...)
bool base_flag_is_retired(enum base_flag_id flag)
Returns TRUE iff the given flag is retired.
Base_type_id base_number(const struct base_type *pbase)
Return the base index.
void base_type_init(struct extra_type *pextra, int idx)
Initialize base_type structures.
bool territory_claiming_base(const struct base_type *pbase)
Does this base type claim territory?
bool BV_ISSET(const BV &bv, int bit)
struct citystyle * city_styles
void city_styles_alloc(int num)
Allocate memory for this amount of city styles.
const char * get_output_identifier(Output_type_id output)
Return an id string for the output type.
const char * city_style_rule_name(const int style)
Return the (untranslated) rule name of the city style.
void city_production_caravan_shields_init()
Initialize the cache of what city production can use shields from caravans.
#define output_type_iterate(output)
#define output_type_iterate_end
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Thaw a connection list.
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Freeze a connection list.
struct clause_info * clause_info_get(enum clause_type type)
Free memory associated with clause infos.
const char * disaster_rule_name(struct disaster_type *pdis)
Return untranslated name of this disaster type.
Disaster_type_id disaster_number(const struct disaster_type *pdis)
Return the disaster id.
Disaster_type_id disaster_index(const struct disaster_type *pdis)
Return the disaster index.
#define disaster_type_iterate(_p)
#define disaster_type_iterate_end
void send_ruleset_cache(struct conn_list *dest)
Send the ruleset cache data over the network.
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Add effect to ruleset cache.
void effect_req_append(struct effect *peffect, struct requirement req)
Append requirement to effect.
#define MAX_DISASTER_TYPES
#define MAX_NUM_BUILDING_LIST
#define EC_NATURAL_DEFENSIVE
#define MAX_CALENDAR_FRAGMENTS
#define MAX_NUM_TECH_CLASSES
#define MAX_NUM_MULTIPLIERS
#define MAX_NUM_UNIT_LIST
#define MAX_ACHIEVEMENT_TYPES
#define MAX_NUM_TECH_LIST
const struct ft_color ftc_warning
void game_ruleset_init()
Initialize the objects which will read from a ruleset.
void game_ruleset_free()
Frees all memory which in objects which are read from a ruleset.
#define RS_DEFAULT_RANSOM_GOLD
#define RS_DEFAULT_GRANARY_FOOD_INI
#define RS_DEFAULT_CIVIL_WAR_UNHAPPY
#define RS_DEFAULT_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_MIN_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_MAX_TECH_UPKEEP_DIVIDER
#define RS_MIN_ILLNESS_POLLUTION_PCT
#define RS_DEFAULT_NUKE_POP_LOSS_PCT
#define RS_MAX_BORDER_RADIUS_SQ_CITY
#define RS_DEFAULT_BASE_POLLUTION
#define RS_MIN_ILLNESS_TRADE_INFECTION_PCT
#define RS_MAX_ILLNESS_BASE_FACTOR
#define RS_DEFAULT_INCITE_TOTAL_FCT
#define RS_DEFAULT_ILLNESS_BASE_FACTOR
#define RS_DEFAULT_NEG_YEAR_LABEL
#define RS_DEFAULT_FORCE_TRADE_ROUTE
#define RS_MIN_NUKE_POP_LOSS_PCT
#define RS_MIN_INCITE_IMPROVEMENT_FCT
#define RS_MIN_BASE_BRIBE_COST
#define RS_MAX_NUKE_POP_LOSS_PCT
#define RS_DEFAULT_INCITE_IMPROVEMENT_FCT
#define RS_MAX_INCITE_IMPROVEMENT_FCT
#define RS_MIN_RANSOM_GOLD
#define RS_ACTION_NO_MAX_DISTANCE
#define RS_DEFAULT_BASE_BRIBE_COST
#define RS_MAX_INCITE_BASE_COST
#define RS_DEFAULT_TECH_UPKEEP_DIVIDER
#define RS_DEFAULT_HAPPY_COST
#define RS_MIN_UPGRADE_VETERAN_LOSS
#define RS_MIN_ILLNESS_MIN_SIZE
#define RS_DEFAULT_ONLY_KILLING_VETERAN
#define RS_DEFAULT_POISON_EMPTIES_FOOD_STOCK
#define RS_DEFAULT_GRANARY_FOOD_INC
#define RS_DEFAULT_ILLNESS_ON
#define RS_MAX_HAPPY_COST
#define GAME_DEFAULT_CELEBRATESIZE
#define RS_MIN_ILLNESS_BASE_FACTOR
#define RS_DEFAULT_STEAL_MAP_REVEALS_CITIES
#define RS_MIN_TECH_UPKEEP_DIVIDER
#define RS_MAX_RANSOM_GOLD
#define RS_MIN_HAPPY_COST
#define RS_MIN_BORDER_RADIUS_SQ_CITY
#define GAME_DEFAULT_RULESETDIR
#define RS_DEFAULT_CIVIL_WAR_CELEB
#define RS_MAX_BASE_TECH_COST
#define RS_DEFAULT_BASE_TECH_COST
#define RS_DEFAULT_USER_ACTION_TARGET_KIND
#define RS_MIN_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_MAX_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_DEFAULT_UPGRADE_VETERAN_LOSS
#define RS_MAX_NUKE_DEFENDER_SURVIVAL_CHANCE_PCT
#define RS_MAX_INCITE_UNIT_FCT
#define RS_MIN_VIS_RADIUS_SQ
#define RS_DEFAULT_CALENDAR_SKIP_0
#define RS_MAX_ILLNESS_MIN_SIZE
#define RS_DEFAULT_CITY_RADIUS_SQ
#define RS_MAX_BORDER_SIZE_EFFECT
#define RS_DEFAULT_BORDER_SIZE_EFFECT
#define RS_MAX_BASE_BRIBE_COST
#define RS_MIN_INCITE_BASE_COST
#define RS_DEFAULT_FORCE_EXPLODE_NUCLEAR
#define RS_DEFAULT_FORCE_CAPTURE_UNITS
#define RS_DEFAULT_PILLAGE_SELECT
#define RS_MIN_CITY_RADIUS_SQ
#define RS_MIN_CITY_CENTER_OUTPUT
#define RS_MAX_GRANARY_FOOD_INC
#define RS_MAX_CITY_CENTER_OUTPUT
#define RS_MAX_CITY_RADIUS_SQ
#define RS_DEFAULT_POS_YEAR_LABEL
#define RS_MIN_INCITE_UNIT_FCT
#define RS_MIN_BORDER_SIZE_EFFECT
#define RS_DEFAULT_VIS_RADIUS_SQ
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY_PERMANENT
#define RS_DEFAULT_TIRED_ATTACK
#define RS_DEFAULT_ACTION_ACTOR_CONSUMING_ALWAYS
#define RS_MAX_ILLNESS_POLLUTION_PCT
#define RS_DEFAULT_ILLNESS_TRADE_INFECTION_PCT
#define RS_DEFAULT_FOOD_COST
#define RS_DEFAULT_INCITE_UNIT_FCT
#define RS_MAX_INCITE_TOTAL_FCT
#define RS_DEFAULT_INCITE_BASE_COST
#define RS_DEFAULT_FORCE_BOMBARD
#define GAME_DEFAULT_ANGRYCITIZEN
#define RS_DEFAULT_CITY_CENTER_OUTPUT
#define RS_MIN_INCITE_TOTAL_FCT
#define RS_DEFAULT_ILLNESS_POLLUTION_PCT
#define RS_MAX_UPGRADE_VETERAN_LOSS
#define RS_MAX_VIS_RADIUS_SQ
#define RS_MIN_GRANARY_FOOD_INC
#define RS_MAX_ILLNESS_TRADE_INFECTION_PCT
#define RS_DEFAULT_ILLNESS_MIN_SIZE
#define RS_MIN_BASE_TECH_COST
#define RS_DEFAULT_BORDER_RADIUS_SQ_CITY
const struct nation_type * ruler_title_nation(const struct ruler_title *pruler_title)
Return the nation of the rule title.
Government_type_id government_count()
Return the number of governments.
const char * government_rule_name(const struct government *pgovern)
Return the (untranslated) rule name of the government.
QHash< const struct nation_type *, struct ruler_title * > * government_ruler_titles(const struct government *pgovern)
Returns all ruler titles for a government type.
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Return the female rule title name.
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Return the male rule title name.
struct government * government_by_rule_name(const char *name)
Returns the government that has the given (untranslated) rule name.
void governments_alloc(int num)
Allocate the governments.
struct ruler_title * government_ruler_title_new(struct government *pgovern, const struct nation_type *pnation, const char *ruler_male_title, const char *ruler_female_title)
Add a new ruler title for the nation.
std::vector< government > governments
Government_type_id government_number(const struct government *pgovern)
Return the government index.
Government_type_id government_index(const struct government *pgovern)
Return the government index.
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
struct impr_type * improvement_by_rule_name(const char *name)
Does a linear search of improvement_types[].name.vernacular Returns nullptr when none match.
void improvement_feature_cache_init()
Cache features of the improvement.
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
Impr_type_id improvement_number(const struct impr_type *pimprove)
Return the improvement index.
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert_ret(condition)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_debug(message,...)
struct terrain_misc terrain_control
int utype_unknown_move_cost(const struct unit_type *utype)
This function calculates the movement cost to unknown tiles.
void init_move_fragments()
Call whenever terrain_control.move_fragments / SINGLE_MOVE changes.
const char * multiplier_rule_name(const struct multiplier *pmul)
Return the (untranslated) rule name of the multiplier.
Multiplier_type_id multiplier_number(const struct multiplier *pmul)
Returns multiplier number.
struct multiplier * multiplier_by_rule_name(const char *name)
Returns multiplier matching rule name, or nullptr if there is no multiplier with such a name.
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Returns multiplier index.
#define multipliers_iterate(_mul_)
#define multipliers_iterate_end
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
static const char * untranslated_name(const struct name_translation *ptrans)
static const char * rule_name_get(const struct name_translation *ptrans)
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
struct nation_set * nation_set_by_number(int id)
Return the nation set with the given index.
void nation_group_set_match(struct nation_group *pgroup, int match)
Set how much the AI will try to select a nation in the same group.
struct nation_type * nation_by_number(const Nation_type_id nation)
Return the nation with the given index.
struct nation_leader * nation_leader_new(struct nation_type *pnation, const char *name, bool is_male)
Create a new leader for the nation.
const char * nation_set_untranslated_name(const struct nation_set *pset)
Return the untranslated name of a nation set (including qualifier, if any).
bool nation_leader_is_male(const struct nation_leader *pleader)
Return the sex of the nation leader.
int nation_set_count()
Return the number of nation sets.
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
std::vector< nation_type > nations
bool is_nation_playable(const struct nation_type *nation)
Return whether a nation is "playable"; i.e., whether a human player can choose this nation.
struct nation_city * nation_city_new(struct nation_type *pnation, const char *name)
Create a new default city for the nation (server only function).
int nation_group_count()
Return the number of nation groups.
struct nation_group * nation_group_new(const char *name)
Add new group into the array of groups.
int nation_set_number(const struct nation_set *pset)
Return the nation set index.
void nation_city_set_terrain_preference(struct nation_city *pncity, const struct terrain *pterrain, enum nation_city_preference prefer)
Set the default nation city preference for the terrain.
struct nation_group * nation_group_by_rule_name(const char *name)
Return the nation group that has the given (untranslated) rule name.
void nation_city_set_river_preference(struct nation_city *pncity, enum nation_city_preference prefer)
Set the default nation city preference about rivers.
bool nation_is_in_set(const struct nation_type *pnation, const struct nation_set *pset)
Check if the given nation is in a given set.
const char * nation_set_rule_name(const struct nation_set *pset)
Return the (untranslated) rule name of a nation set.
const char * nation_set_description(const struct nation_set *pset)
Return the (untranslated) user description of a nation set.
struct nation_set * nation_set_new(const char *set_name, const char *set_rule_name, const char *set_description)
Add new set into the array of nation sets.
struct nation_type * nation_by_rule_name(const char *name)
Returns the nation that has the given (untranslated) rule name (adjective).
Nation_type_id nation_index(const struct nation_type *pnation)
Return the nation index.
const char * nation_leader_name(const struct nation_leader *pleader)
Return the name of the nation leader.
const char * nation_group_untranslated_name(const struct nation_group *pgroup)
Return the untranslated name of a nation group (including qualifier, if any).
const struct nation_leader_list * nation_leaders(const struct nation_type *pnation)
Returns the list the nation leader names.
void nation_group_set_hidden(struct nation_group *pgroup, bool hidden)
Set whether this group should appear in the nation selection UI.
struct nation_set * nation_set_by_rule_name(const char *name)
Return the nation set that has the given (untranslated) rule name.
void nations_alloc(int num)
Allocate space for the given number of nations.
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Returns which kind of barbarians can use this nation.
int nation_group_number(const struct nation_group *pgroup)
Return the nation group index.
#define nation_leader_list_iterate(leaderlist, pleader)
#define nation_sets_iterate_end
#define nation_set_list_iterate_end
#define nation_group_list_iterate(grouplist, pgroup)
#define nation_sets_iterate(NAME_pset)
#define nation_leader_list_iterate_end
#define nation_group_list_iterate_end
#define nation_set_list_iterate(setlist, pset)
#define nation_groups_iterate(NAME_pgroup)
#define nation_groups_iterate_end
void notify_conn(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
See notify_conn_packet - this is just the "non-v" version, with varargs.
void packet_strvec_compute(char str[MAX_LEN_PACKET], QVector< QString > *qstrvec)
struct city_list * cities
void send_nation_availability(struct conn_list *dest, bool nationset_change)
Tell clients which nations can be picked given current server settings.
void playercolor_init()
Initialise the player colors.
void count_playable_nations()
Update the server's cached number of playable nations.
void playercolor_free()
Free the memory allocated for the player color.
void playercolor_add(struct rgbcolor *prgbcolor)
Add a color to the list of all available player colors.
int playercolor_count()
Number of player colors defined.
struct section_file * secfile_load(const QString &filename, bool allow_duplicates)
Create a section file from a file.
const char * secfile_error()
Returns the last error which occurred in a string.
const char * section_name(const struct section *psection)
Returns the section name.
void secfile_destroy(struct section_file *secfile)
Free a section file.
bool entry_bool_get(const struct entry *pentry, bool *value)
Gets an boolean value.
void secfile_check_unused(const struct section_file *secfile)
Print log messages for any entries in the file which have not been looked up – ie,...
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Lookup a integer value in the secfile.
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
Returns the entry at "fullpath" or nullptr if not matched.
int * secfile_lookup_int_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a integer vector in the secfile.
const char * entry_name(const struct entry *pentry)
Returns the name of this entry.
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Lookup a string value in the secfile.
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a string vector in the secfile.
bool entry_str_get(const struct entry *pentry, const char **value)
Gets an string value.
const char * secfile_name(const struct section_file *secfile)
Return the filename the section file was loaded as, or "(anonymous)" if this sectionfile was created ...
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Lookup a boolean value in the secfile.
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Lookup a string value in the secfile.
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
Returns the entry by the name or nullptr if not matched.
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Lookup a integer value in the secfile.
struct entry * section_entry_by_name(const struct section *psection, const QString &name)
Returns the first entry matching the name.
bool entry_int_get(const struct entry *pentry, int *value)
Gets an integer value.
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
Returns the list of sections which match the name prefix.
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
Lookup a boolean value in the secfile.
int secfile_lookup_int_def_min_max(const struct section_file *secfile, int defval, int minval, int maxval, const char *path,...)
Lookup a integer value in the secfile.
enum entry_type entry_type_get(const struct entry *pentry)
Returns the type of this entry or ENTRY_ILLEGAL or error.
#define secfile_lookup_enum_vec(secfile, dim, specenum_type, path,...)
#define section_list_iterate(seclist, psection)
#define secfile_lookup_enum_default(secfile, defval, specenum_type, path, ...)
#define section_list_iterate_end
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
Parse a requirement type and value string into a requirement structure.
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Set the values of a req from serializable integers.
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, const char *path,...)
Lookup an RGB color definition ([colorpath].red, [colorpath].green and [colorpath]....
Road_type_id road_number(const struct road_type *proad)
Return the road id.
void road_integrators_cache_init()
Initialize the road integrators cache.
void road_type_init(struct extra_type *pextra, int idx)
Initialize road_type structures.
int rscompat_check_capabilities(struct section_file *file, const char *filename, struct rscompat_info *info)
Ruleset files should have a capabilities string datafile.options This checks the string and that the ...
const char * rscompat_req_name_3_1(const char *type, const char *old_name)
Replace deprecated requirement type names with currently valid ones.
void rscompat_extra_adjust_3_1(struct rscompat_info *compat, struct extra_type *pextra)
Adjust freeciv-3.0 ruleset extra definitions to freeciv-3.1.
bool rscompat_auto_attack_3_1(struct rscompat_info *compat, struct action_auto_perf *auto_perf, size_t psize, enum unit_type_flag_id *protecor_flag)
Replace deprecated auto_attack configuration.
bool rscompat_old_effect_3_1(const char *type, struct section_file *file, const char *sec_name, struct rscompat_info *compat)
Check if effect name refers to one of the removed effects, and handle it if it does.
bool rscompat_names(struct rscompat_info *info)
Do compatibility things with names before they are referred to.
const char * rscompat_utype_flag_name_3_1(struct rscompat_info *compat, const char *old_type)
Replace deprecated unit type flag names with currently valid ones.
bool rscompat_old_slow_invasions_3_1(struct rscompat_info *compat, bool slow_invasions)
Replace slow_invasions and friends.
void rscompat_postprocess(struct rscompat_info *info)
Do compatibility things after regular ruleset loading.
#define check_cityname(name)
static void ruleset_load_traits(struct trait_limits *out, struct section_file *file, const char *secname, const char *field_prefix)
Load trait values to array.
static bool load_rulesetdir(const char *rsdir, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Loads the rulesets from directory.
#define STYLE_SECTION_PREFIX
static bool load_terrain_names(struct section_file *file, struct rscompat_info *compat)
Load names of terrain types so other rulesets can refer to terrains with their name.
char * get_script_buffer()
Return current script.lua buffer.
struct requirement_vector * lookup_req_list(struct section_file *file, struct rscompat_info *compat, const char *sec, const char *sub, const char *rfor)
Load a requirement list.
static bool load_style_names(struct section_file *file, struct rscompat_info *compat)
Load names of nation styles so other rulesets can refer to styles with their name.
#define MUSICSTYLE_SECTION_PREFIX
static bool load_ruleset_governments(struct section_file *file, struct rscompat_info *compat)
This loads information from given governments.ruleset.
#define MULTIPLIER_SECTION_PREFIX
static struct requirement_vector reqs_list
static void send_ruleset_techs(struct conn_list *dest)
Send the techs ruleset information (all individual advances) to the specified connections.
#define section_strlcpy(dst, src)
static bool load_action_range(struct section_file *file, action_id act)
Load range of an action.
static bool lookup_unit_list(struct section_file *file, const char *prefix, const char *entry, std::array< unit_type *, MAX_NUM_UNIT_LIST > &output, const char *filename)
Lookup a prefix.entry string vector in the file and fill in the array, which should hold MAX_NUM_UNIT...
static void send_ruleset_units(struct conn_list *dest)
Send the units ruleset information (all individual units) to the specified connections.
static void send_ruleset_governments(struct conn_list *dest)
Send the government ruleset information to the specified connections.
static bool load_ruleset_techs(struct section_file *file, struct rscompat_info *compat)
Load technologies related ruleset data.
static void send_ruleset_resources(struct conn_list *dest)
Send the resource ruleset information to the specified connections.
static bool load_ruleset_buildings(struct section_file *file, struct rscompat_info *compat)
Load buildings related ruleset data.
static bool lookup_building_list(struct section_file *file, const char *prefix, const char *entry, int *output, const char *filename)
Lookup a prefix.entry string vector in the file and fill in the array, which should hold MAX_NUM_BUIL...
static void nullcheck_secfile_destroy(struct section_file *file)
Destroy secfile.
static void send_ruleset_clauses(struct conn_list *dest)
Send the clause type ruleset information to the specified connections.
static void send_ruleset_game(struct conn_list *dest)
Send information in packet_ruleset_game (miscellaneous rules) to the specified connections.
static QString valid_ruleset_filename(const char *subdir, const char *name, const char *extension, bool optional)
datafilename() wrapper: tries to match in two ways.
#define NATION_SECTION_PREFIX
static bool load_ruleset_effects(struct section_file *file, struct rscompat_info *compat)
Load effects.ruleset file.
static void send_ruleset_nations(struct conn_list *dest)
Send the nations ruleset information (info on each nation) to the specified connections.
static void send_ruleset_roads(struct conn_list *dest)
Send the road ruleset information (all individual road types) to the specified connections.
char * get_parser_buffer()
Return current parser.lua buffer.
static bool is_on_allowed_list(const char *name, const char **list, size_t len)
Check if a string is in a vector (case-insensitively).
static void send_ruleset_tech_classes(struct conn_list *dest)
Send the techs class information to the specified connections.
static void send_ruleset_action_enablers(struct conn_list *dest)
Send the action enabler ruleset information to the specified connections.
static void send_ruleset_control(struct conn_list *dest)
Send information in packet_ruleset_control (numbers of units etc, and other miscellany) to specified ...
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Loads the rulesets.
#define GOODS_SECTION_PREFIX
#define TERRAIN_SECTION_PREFIX
static struct section_file * openload_ruleset_file(const char *whichset, const char *rsdir)
Do initial section_file_load on a ruleset file.
static void send_ruleset_musics(struct conn_list *dest)
Send the music-style ruleset information (each style) to the specified connections.
static void strvec_store(QVector< QString > *psv, const char *const *vec, size_t size)
Stores the string vector from a normal vector.
#define DISASTER_SECTION_PREFIX
static void send_ruleset_goods(struct conn_list *dest)
Send the goods ruleset information (all individual goods types) to the specified connections.
static const char name_too_long[]
static char(* base_sections)[MAX_SECTION_LABEL]
#define CITYSTYLE_SECTION_PREFIX
static bool lookup_tech(struct section_file *file, struct advance **result, const char *prefix, const char *entry, const char *filename, const char *description)
Lookup a string prefix.entry in the file and return the corresponding advances pointer.
static bool load_game_names(struct section_file *file, struct rscompat_info *compat)
Load names from game.ruleset so other rulesets can refer to objects with their name.
static int secfile_lookup_int_default_min_max(struct section_file *file, int def, int min, int max, const char *path,...) fc__attribute((__format__(__printf__
Print an error message if the value is out of range.
static void send_ruleset_specialists(struct conn_list *dest)
Send the specialists ruleset information (all individual specialist types) to the specified connectio...
#define ADVANCE_SECTION_PREFIX
#define EFFECT_SECTION_PREFIX
static void send_ruleset_action_auto_performers(struct conn_list *dest)
Send action auto performer ruleset information to the specified connections.
static char(* extra_sections)[MAX_SECTION_LABEL]
static char * lookup_string(struct section_file *file, const char *prefix, const char *suffix)
Lookup optional string, returning allocated memory or nullptr.
static bool load_government_names(struct section_file *file, struct rscompat_info *compat)
Load names of governments so other rulesets can refer to governments with their name.
static int char * script_buffer
static void send_ruleset_team_names(struct conn_list *dest)
Send all team names defined in the ruleset file(s) to the specified connections.
static void send_ruleset_cities(struct conn_list *dest)
Send the city-style ruleset information (each style) to the specified connections.
static bool lookup_building(struct section_file *file, const char *prefix, const char *entry, struct impr_type **result, const char *filename, const char *description)
Lookup a string prefix.entry in the file and return the corresponding improvement pointer.
static struct extra_type * lookup_resource(const char *filename, const char *name, const char *jsection)
Look up the resource section name and return its pointer.
#define ACTION_ENABLER_SECTION_PREFIX
#define BASE_SECTION_PREFIX
static enum fc_tristate openload_script_file(const char *whichset, const char *rsdir, char **buffer, bool optional)
Parse script file.
static bool load_building_names(struct section_file *file, struct rscompat_info *compat)
Load names of buildings so other rulesets can refer to buildings with their name.
#define EXTRA_SECTION_PREFIX
void send_rulesets(struct conn_list *dest)
Send all ruleset information to the specified connections.
#define CLAUSE_SECTION_PREFIX
#define UNIT_SECTION_PREFIX
#define ACHIEVEMENT_SECTION_PREFIX
static bool load_ruleset_cities(struct section_file *file, struct rscompat_info *compat)
Load cities.ruleset file.
static bool load_ruleset_styles(struct section_file *file, struct rscompat_info *compat)
Load styles.ruleset file.
static bool load_ruleset_units(struct section_file *file, struct rscompat_info *compat)
Load units related ruleset data.
bool reload_rulesets_settings()
Reload the game settings saved in the ruleset file.
void rulesets_deinit()
Completely deinitialize ruleset system.
static bool lookup_time(const struct section_file *secfile, int *turns, const char *sec_name, const char *property_name, const char *filename, const char *item_name, bool *ok)
Look up a value comparable to activity_count (road_time, etc).
static void send_ruleset_styles(struct conn_list *dest)
Send the nation style ruleset information (each style) to the specified connections.
#define NATION_GROUP_SECTION_PREFIX
static void send_ruleset_disasters(struct conn_list *dest)
Send the disaster ruleset information (all individual disaster types) to the specified connections.
static bool lookup_terrain(struct section_file *file, const char *entry, const char *filename, struct terrain *pthis, struct terrain **result)
Look up the terrain by name and return its pointer.
static bool lookup_tech_list(struct section_file *file, const char *prefix, const char *entry, int *output, const char *filename)
Lookup a prefix.entry string vector in the file and fill in the array, which should hold MAX_NUM_TECH...
#define MAX_SECTION_LABEL
#define BUILDING_SECTION_PREFIX
static bool load_ruleset_game(struct section_file *file, bool act, struct rscompat_info *compat)
Load ruleset file.
static const char * check_leader_names(struct nation_type *pnation)
Check for duplicate leader names in nation.
static bool load_nation_names(struct section_file *file, struct rscompat_info *compat)
Load names of nations so other rulesets can refer to nations with their name.
static void send_ruleset_achievements(struct conn_list *dest)
Send the achievement ruleset information (all individual achievement types) to the specified connecti...
static void send_ruleset_bases(struct conn_list *dest)
Send the base ruleset information (all individual base types) to the specified connections.
static bool load_ruleset_terrain(struct section_file *file, struct rscompat_info *compat)
Load terrain types related ruleset data.
static char(* resource_sections)[MAX_SECTION_LABEL]
static bool load_action_actor_consuming_always(struct section_file *file, action_id act)
Load if the action always consumes the actor.
static bool load_tech_names(struct section_file *file, struct rscompat_info *compat)
Load names of technologies so other rulesets can refer to techs with their name.
#define SPECIALIST_SECTION_PREFIX
static bool lookup_cbonus_list(struct rscompat_info *compat, struct combat_bonus_list *list, struct section_file *file, const char *sec, const char *sub)
Load combat bonus list.
static bool load_action_kind(struct section_file *file, action_id act)
Load kind of an action.
static struct section_file * openload_luadata_file(const char *rsdir)
Load optional luadata.txt.
static void send_ruleset_multipliers(struct conn_list *dest)
Send the multiplier ruleset information to the specified connections.
static void send_ruleset_actions(struct conn_list *dest)
Send action ruleset information to the specified connections.
static bool load_city_name_list(struct section_file *file, struct nation_type *pnation, const char *secfile_str1, const char *secfile_str2, const char **allowed_terrains, size_t atcount)
This function loads a city name list from a section file.
static struct government * lookup_government(struct section_file *file, const char *entry, const char *filename, struct government *fallback)
Lookup entry in the file and return the corresponding government index.
static bool load_action_auto_uflag_block(struct section_file *file, struct action_auto_perf *auto_perf, const char *uflags_path, const char *filename)
Load a list of unit type flags that must be absent from the actor unit if an action auto performer sh...
static bool load_ruleset_nations(struct section_file *file, struct rscompat_info *compat)
Load nations.ruleset file.
static bool load_action_auto_actions(struct section_file *file, struct action_auto_perf *auto_perf, const char *actions_path, const char *filename)
Load the list of actions an action auto performer should try.
static void send_ruleset_unit_classes(struct conn_list *dest)
Send the units ruleset information (all individual unit classes) to the specified connections.
#define TECH_CLASS_SECTION_PREFIX
#define RESOURCE_SECTION_PREFIX
static bool lookup_unit_type(struct section_file *file, const char *prefix, const char *entry, const struct unit_type **result, const char *filename, const char *description)
Lookup a string prefix.entry in the file and set result to the corresponding unit_type.
static void send_ruleset_extras(struct conn_list *dest)
Send the extra ruleset information (all individual extra types) to the specified connections.
#define rs_sanity_veteran(_path, _entry, _i, _condition, _action)
static QVector< QString > * lookup_strvec(struct section_file *file, const char *prefix, const char *suffix)
Lookup optional string vector, returning allocated memory or nullptr.
static char(* road_sections)[MAX_SECTION_LABEL]
static void send_ruleset_terrain(struct conn_list *dest)
Send the terrain ruleset information (terrain_control, and the individual terrain types) to the speci...
#define GOVERNMENT_SECTION_PREFIX
static bool load_unit_names(struct section_file *file, struct rscompat_info *compat)
Load names of units so other rulesets can refer to units with their name.
static void send_ruleset_trade_routes(struct conn_list *dest)
Send the trade route types ruleset information (all individual trade route types) to the specified co...
static void notify_ruleset_fallback(const char *msg)
Make it clear to everyone that requested ruleset has not been loaded.
static void send_ruleset_buildings(struct conn_list *dest)
Send the buildings ruleset information (all individual improvements and wonders) to the specified con...
#define UNIT_CLASS_SECTION_PREFIX
static bool ruleset_load_names(struct name_translation *pname, const char *domain, struct section_file *file, const char *sec_name)
Load "name" and (optionally) "rule_name" into a struct name_translation.
#define ROAD_SECTION_PREFIX
static char(* terrain_sections)[MAX_SECTION_LABEL]
static bool load_action_range_max(struct section_file *file, action_id act)
Load max range of an action.
static bool load_muuk_as_action_auto(struct section_file *file, struct action_auto_perf *auto_perf, const char *item, const char *filename)
Load missing unit upkeep ruleset settings as action auto performers.
static bool load_action_ui_name(struct section_file *file, int act, const char *entry_name)
Load ui_name of one action.
#define NATION_SET_SECTION_PREFIX
static bool load_ruleset_veteran(struct section_file *file, const char *path, struct veteran_system **vsystem, char *err, size_t err_len, bool compat)
Load veteran levels.
#define RS_DEFAULT_TECH_TRADE_LOSS_HOLES
#define RS_DEFAULT_TECH_COST_STYLE
#define RS_DEFAULT_EXTRA_APPEARANCE
#define RS_DEFAULT_TECH_PARASITE_HOLES
#define GAME_DEFAULT_ACH_VALUE
#define RS_DEFAULT_TECH_TRADE_HOLES
#define RS_DEFAULT_CULTURE_VIC_POINTS
#define RS_DEFAULT_CULTURE_MIGRATION_PML
void(* rs_conversion_logger)(const char *msg)
#define RS_DEFAULT_TECH_LOSS_HOLES
#define RS_DEFAULT_HISTORY_INTEREST_PML
#define RS_DEFAULT_TECH_UPKEEP_STYLE
#define RS_DEFAULT_PYTHAGOREAN_DIAGONAL
#define RS_DEFAULT_TECH_STEAL_HOLES
#define GAME_DEFAULT_ACH_UNIQUE
#define RS_DEFAULT_MUUK_FOOD_WIPE
#define RS_DEFAULT_MUUK_GOLD_WIPE
#define RS_DEFAULT_MUUK_SHIELD_WIPE
#define RS_DEFAULT_INITIAL_DIPLOMATIC_STATE
#define RS_DEFAULT_GOLD_UPKEEP_STYLE
#define GAME_DEFAULT_NATIONALITY
#define GAME_DEFAULT_ADDTOSIZE
#define RS_DEFAULT_EXTRA_DISAPPEARANCE
#define GAME_DEFAULT_VISION_REVEAL_TILES
#define RS_DEFAULT_CULTURE_VIC_LEAD
#define RS_DEFAULT_TECH_LEAKAGE
#define GAME_DEFAULT_CHANGEABLE_BUDGET
#define GAME_DEFAULT_DISASTER_FREQ
#define GAME_DEFAULT_CONVERT_SPEED
static struct compatibility compat[]
bool script_server_init()
Initialize the scripting state.
void script_server_free()
Free the scripting data.
bool script_server_load_file(const char *filename, char **buf)
Load script to a buffer.
bool script_server_do_file(struct connection *caller, const char *filename)
Parse and execute the script at filename in the same instance as the ruleset.
bool settings_ruleset(struct section_file *file, const char *section, bool act)
Load game settings from ruleset file 'game.ruleset'.
const QStringList & get_data_dirs()
Returns a list of data directory paths, in the order in which they should be searched.
bool check_strlen(const char *str, size_t len, const char *errmsg)
Check the length of the given string.
QString fileinfoname(const QStringList &dirs, const QString &filename)
Returns a filename to access the specified file from a directory by searching all specified directori...
void remove_leading_trailing_spaces(char *s)
Removes leading and trailing spaces in string pointed to by 's'.
const char * specialist_rule_name(const struct specialist *sp)
Return the (untranslated) rule name of the specialist type.
struct specialist * specialist_by_number(const Specialist_type_id id)
Return the specialist pointer for the given number.
#define specialist_type_iterate_end
#define specialist_type_iterate(sp)
#define DEFAULT_SPECIALIST
const char * aifill(int amount)
Fill or remove players to meet the given aifill.
void update_nations_with_startpos()
Update information about which nations have start positions on the map.
struct requirement_vector reqs
enum action_auto_perf_cause cause
action_id alternatives[MAX_NUM_ACTIONS]
struct requirement_vector actor_reqs
struct requirement_vector target_reqs
bool actor_consuming_always
enum action_result result
char ui_name[MAX_LEN_NAME]
enum action_actor_kind actor_kind
enum action_target_kind target_kind
struct advance * require[AR_SIZE]
enum base_gui_type gui_type
char citizens_graphic[MAX_LEN_NAME]
char graphic_alt[MAX_LEN_NAME]
char graphic[MAX_LEN_NAME]
char citizens_graphic_alt[MAX_LEN_NAME]
struct civ_game::@28::@32 server
struct rgbcolor * plr_bg_color
struct packet_ruleset_control control
int global_init_techs[MAX_NUM_TECH_LIST]
struct packet_game_info info
int global_init_buildings[MAX_NUM_BUILDING_LIST]
char * ruleset_description
struct civ_game::@27 rgame
char * ruleset_capabilities
struct veteran_system * veteran
struct packet_calendar_info calendar
struct government * default_government
struct government * government_during_revolution
struct civ_map::@39::@41 server
struct requirement_vector receiver_reqs
struct requirement_vector giver_reqs
enum unit_type_flag_id flag
char graphic_str[MAX_LEN_NAME]
char graphic_alt[MAX_LEN_NAME]
struct requirement_vector obsolete_by
char soundtag_alt[MAX_LEN_NAME]
struct requirement_vector reqs
struct name_translation name
QVector< QString > * helptext
char soundtag[MAX_LEN_NAME]
struct requirement_vector reqs
Functions for handling the nations.
struct name_translation noun_plural
struct name_translation adjective
struct nation_type::@48::@50 server
enum barbarian_type barb_type
struct requirement_vector first_reqs
enum road_move_mode move_mode
int tile_incr_const[O_LAST]
rs_conversion_logger log_cb
struct requirement_vector reqs
char graphic_alt[MAX_LEN_NAME]
char graphic_str[MAX_LEN_NAME]
struct name_translation name
QVector< QString > * helptext
struct name_translation abbreviation
enum traderoute_bonus_type bonus_type
enum traderoute_illegal_cancelling cancelling
struct name_translation name
struct veteran_level * definitions
struct nation_style * style_by_rule_name(const char *name)
Returns style matching rule name or nullptr if there is no style with such name.
struct music_style * music_style_by_number(int id)
Return music style of given id.
void styles_alloc(int count)
Initialise styles structures.
struct nation_style * style_by_number(int id)
Return style of given id.
int style_number(const struct nation_style *pstyle)
Return the style id.
void music_styles_alloc(int count)
Initialise music styles structures.
int style_index(const struct nation_style *pstyle)
Return the style index.
#define music_styles_iterate(_p)
#define music_styles_iterate_end
#define styles_iterate(_p)
#define styles_iterate_end
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
size_t fc_strlcat(char *dest, const char *src, size_t n)
fc_strlcat() provides utf-8 version of (non-standard) function strlcat() It is intended as more user-...
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
#define sz_strlcpy(dest, src)
int fc__attribute((nonnull(1, 3)))
const char * team_slot_defined_name(const struct team_slot *tslot)
Returns the name defined in the ruleset for this slot.
int team_slot_index(const struct team_slot *tslot)
Returns the index of the team slots.
int team_slot_count()
Returns the total number of team slots (including used slots).
struct team_slot * team_slot_by_number(int team_id)
Return the possibly unused and uninitialized team slot.
void team_slot_set_defined_name(struct team_slot *tslot, const char *team_name)
Set the name defined in the ruleset for this slot.
#define team_slots_iterate_end
#define team_slots_iterate(_tslot)
struct tech_class * tech_class_by_rule_name(const char *name)
Does a linear search of tech_classes[].name.vernacular Returns nullptr when none match.
void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt)
Sets user defined name for tech flag.
struct advance * valid_advance(struct advance *padvance)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
struct advance * advance_by_rule_name(const char *name)
Does a linear search of advances[].name.vernacular Returns nullptr when none match.
const char * advance_rule_name(const struct advance *padvance)
Return the (untranslated) rule name of the advance/technology.
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
void techs_precalc_data()
Function to precalculate needed data for technologies.
const char * tech_flag_helptxt(enum tech_flag_id id)
Return the (untranslated) helptxt of the user tech flag.
const char * tech_flag_id_name_cb(enum tech_flag_id flag)
Tech flag name callback, called from specenum code.
Tech_type_id advance_count()
Return the number of advances/technologies.
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
#define tech_class_index(_ptclass_)
#define tech_class_iterate_end
#define MAX_NUM_USER_TECH_FLAGS
#define advance_iterate(_start, _p)
#define tech_class_iterate(_p)
#define advance_iterate_end
Terrain_type_id terrain_count()
Return the number of terrains.
struct terrain * terrain_by_number(const Terrain_type_id type)
Return the terrain for the given terrain index.
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Terrain flag name callback, called from specenum code.
struct resource_type * resource_type_init(struct extra_type *pextra)
Initialize resource_type structure.
struct terrain * terrain_by_rule_name(const char *name)
Return the terrain type matching the name, or T_UNKNOWN if none matches.
Terrain_type_id terrain_index(const struct terrain *pterrain)
Return the terrain index.
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Return the (untranslated) helptxt of the user terrain flag.
void set_user_terrain_flag_name(enum terrain_flag_id id, const char *name, const char *helptxt)
Sets user defined name for terrain flag.
Terrain_type_id terrain_number(const struct terrain *pterrain)
Return the terrain index.
#define terrain_type_iterate(_p)
#define MAX_RESOURCE_TYPES
#define TERRAIN_UNKNOWN_IDENTIFIER
#define terrain_type_iterate_end
#define RESOURCE_NONE_IDENTIFIER
#define RESOURCE_NULL_IDENTIFIER
#define MAX_NUM_USER_TER_FLAGS
Q_LOGGING_CATEGORY(tileset_category, "freeciv.tileset")
Functions for handling the tilespec files which describe the files and contents of tilesets.
const char * goods_rule_name(struct goods_type *pgood)
Return untranslated name of this goods type.
enum traderoute_illegal_cancelling traderoute_cancelling_type_by_name(const char *name)
Get traderoute cancelling type by name.
Goods_type_id goods_number(const struct goods_type *pgood)
Return the goods id.
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Get trade route settings related to type.
Goods_type_id goods_index(const struct goods_type *pgood)
Return the goods index.
enum trade_route_type trade_route_type_by_name(const char *name)
Get trade route type by name.
#define goods_type_iterate_end
#define goods_type_iterate(_p)
#define TRAIT_DEFAULT_VALUE
void set_unit_class_caches(struct unit_class *pclass)
Set caches for unit class.
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Return the (untranslated) help text of the user unit class flag.
const char * utype_rule_name(const struct unit_type *punittype)
Return the (untranslated) rule name of the unit type.
bool utype_has_role(const struct unit_type *punittype, int role)
Return whether the given unit type has the role.
Unit_type_id utype_count()
Return the number of unit types.
void set_unit_type_caches(struct unit_type *ptype)
Set caches for unit types.
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Return the (untranslated) helptxt of the user unit flag.
struct unit_class * unit_class_by_rule_name(const char *s)
Returns the unit class that has the given (untranslated) rule name.
struct veteran_system * veteran_system_new(int count)
Allocate new veteran system structure with given veteran level count.
void veteran_system_definition(struct veteran_system *vsystem, int level, const char *vlist_name, int vlist_power, int vlist_move, int vlist_raise, int vlist_wraise)
Fill veteran level in given veteran system with given information.
int utype_veteran_levels(const struct unit_type *punittype)
Return veteran levels of the given unit type.
void role_unit_precalcs()
Initialize; it is safe to call this multiple times (e.g., if units have changed due to rulesets in cl...
struct unit_type * unit_type_by_rule_name(const char *name)
Returns the unit type that has the given (untranslated) rule name.
Unit_type_id utype_number(const struct unit_type *punittype)
Return the unit type index.
Unit_type_id utype_index(const struct unit_type *punittype)
Return the unit type index.
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Sets user defined name for unit class flag.
const char * uclass_rule_name(const struct unit_class *pclass)
Return the (untranslated) rule name of the unit class.
Unit_Class_id uclass_number(const struct unit_class *pclass)
Return the unit_class index.
void unit_type_action_cache_init()
Cache what unit types may be allowed do what actions, both at all and when certain properties are tru...
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Sets user defined name for unit flag.
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Return veteran level properties of given unit in given veterancy level.
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
#define combat_bonus_list_iterate_end
#define combat_bonus_list_iterate(bonuslist, pbonus)
#define unit_class_iterate(_p)
#define MAX_NUM_USER_UNIT_FLAGS
static bool utype_has_flag(const struct unit_type *punittype, int flag)
#define UTYF_LAST_USER_FLAG
#define unit_type_iterate(_p)
#define uclass_index(_c_)
#define unit_class_iterate_end
#define unit_type_iterate_end
#define MAX_NUM_USER_UCLASS_FLAGS