Freeciv-3.2: /fast/freeciv/nightly/S3_2/server/rscompat.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
rscompat.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* ANSI */
19#ifdef HAVE_STRING_H
20#include <string.h>
21#endif
22
23/* utility */
24#include "capability.h"
25#include "log.h"
26#include "registry.h"
27
28/* common */
29#include "actions.h"
30#include "effects.h"
31#include "fc_types.h"
32#include "game.h"
33#include "movement.h"
34#include "requirements.h"
35#include "unittype.h"
36
37/* server */
38#include "rssanity.h"
39#include "ruleset.h"
40#include "settings.h"
41
42#include "rscompat.h"
43
44#define enough_new_user_flags(_new_flags_, _name_, \
45 _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_) \
46FC_STATIC_ASSERT((ARRAY_SIZE(_new_flags_) \
47 <= _LAST_USER_FLAG_ - _LAST_USER_FLAG_PREV_), \
48 not_enough_new_##_name_##_user_flags)
49
50#define UTYF_LAST_USER_FLAG_3_0 UTYF_USER_FLAG_40
51#define UCF_LAST_USER_FLAG_3_0 UCF_USER_FLAG_8
52#define TER_LAST_USER_FLAG_3_0 TER_USER_8
53
54/**********************************************************************/
57 void rscompat_init_info(struct rscompat_info *info)
58{
59 memset(info, 0, sizeof(*info));
60}
61
62/**********************************************************************/
66 int rscompat_check_capabilities(struct section_file *file,
67 const char *filename,
68 const struct rscompat_info *info)
69{
70 const char *datafile_options;
71 bool ok = FALSE;
72 int format;
73
74 if (!(datafile_options = secfile_lookup_str(file, "datafile.options"))) {
75 log_fatal("\"%s\": ruleset capability problem:", filename);
76 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
77
78 return 0;
79 }
80
81 if (info->compat_mode) {
82 /* Check alternative capstr first, so that when we do the main capstr check,
83 * we already know that failures there are fatal (error message correct, can return
84 * immediately) */
85
86 if (has_capabilities(RULESET_COMPAT_CAP, datafile_options)
87 && has_capabilities(datafile_options, RULESET_COMPAT_CAP)) {
88 ok = TRUE;
89 }
90 }
91
92 if (!ok) {
93 if (!has_capabilities(RULESET_CAPABILITIES, datafile_options)) {
94 log_fatal("\"%s\": ruleset datafile appears incompatible:", filename);
95 log_fatal(" datafile options: %s", datafile_options);
96 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
97 ruleset_error(NULL, LOG_ERROR, "Capability problem");
98
99 return 0;
100 }
101 if (!has_capabilities(datafile_options, RULESET_CAPABILITIES)) {
102 log_fatal("\"%s\": ruleset datafile claims required option(s)"
103 " that we don't support:", filename);
104 log_fatal(" datafile options: %s", datafile_options);
105 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
106 ruleset_error(NULL, LOG_ERROR, "Capability problem");
107
108 return 0;
109 }
110 }
111
112 if (!secfile_lookup_int(file, &format, "datafile.format_version")) {
113 log_error("\"%s\": lacking legal format_version field", filename);
114 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
115
116 return 0;
117 } else if (format == 0) {
118 log_error("\"%s\": Illegal format_version value", filename);
119 ruleset_error(NULL, LOG_ERROR, "Format version error");
120 }
121
122 return format;
123}
124/**********************************************************************/
131 bool rscompat_check_cap_and_version(struct section_file *file,
132 const char *filename,
133 const struct rscompat_info *info)
134{
135 int format_version;
136
137 fc_assert_ret_val(info->version > 0, FALSE);
138
139 format_version = rscompat_check_capabilities(file, filename, info);
140 if (format_version <= 0) {
141 /* Already logged in rscompat_check_capabilities */
142 return FALSE;
143 }
144
145 if (format_version != info->version) {
146 log_fatal("\"%s\": ruleset datafile format version differs from"
147 " other ruleset datafile(s):", filename);
148 log_fatal(" datafile format version: %d", format_version);
149 log_fatal(" expected format version: %d", info->version);
150 ruleset_error(NULL, LOG_ERROR, "Inconsistent format versions");
151
152 return FALSE;
153 }
154
155 return TRUE;
156}
157
158/**********************************************************************/
165static bool
166rscompat_enabler_add_obligatory_hard_reqs(struct action_enabler *ae)
167{
168 struct req_vec_problem *problem;
169
170 struct action *paction = enabler_get_action(ae);
171 /* Some changes requires starting to process an action's enablers from
172 * the beginning. */
173 bool needs_restart = FALSE;
174
175 while ((problem = action_enabler_suggest_repair(ae)) != NULL) {
176 /* A hard obligatory requirement is missing. */
177
178 int i;
179
180 if (problem->num_suggested_solutions == 0) {
181 /* Didn't get any suggestions about how to solve this. */
182
183 log_error("While adding hard obligatory reqs to action enabler"
184 " for %s: %s"
185 " Don't know how to fix it."
186 " Dropping it.",
187 action_rule_name(paction), problem->description);
188 ae->ruledit_disabled = TRUE;
189
190 req_vec_problem_free(problem);
191 return TRUE;
192 }
193
194 /* Sanity check. */
195 fc_assert_ret_val(problem->num_suggested_solutions > 0,
196 needs_restart);
197
198 /* Only append is supported for upgrade */
199 for (i = 0; i < problem->num_suggested_solutions; i++) {
200 if (problem->suggested_solutions[i].operation != RVCO_APPEND) {
201 /* A problem that isn't caused by missing obligatory hard
202 * requirements has been detected.
203 *
204 * Probably an old requirement that contradicted a hard requirement
205 * that wasn't documented by making it obligatory. In that case all
206 * suggested solutions has been applied to the enabler creating a
207 * new copy for each possible fulfillment of the new obligatory hard
208 * requirement.
209 *
210 * If another copy of the original enabler has survived this isn't
211 * an error. It probably isn't event an indication of a potential
212 * problem.
213 *
214 * If no possible solution survives the enabler was never in use
215 * because the action it self would have blocked it. In that case
216 * this is an error. */
217
218 log_warn("While adding hard obligatory reqs to action enabler"
219 " for %s: %s"
220 " Dropping it.",
221 action_rule_name(paction), problem->description);
222 ae->ruledit_disabled = TRUE;
223 req_vec_problem_free(problem);
224 return TRUE;
225 }
226 }
227
228 for (i = 0; i < problem->num_suggested_solutions; i++) {
229 struct action_enabler *new_enabler;
230
231 /* There can be more than one suggestion to apply. In that case both
232 * are applied to their own copy. The original should therefore be
233 * kept for now. */
234 new_enabler = action_enabler_copy(ae);
235
236 /* Apply the solution. */
237 if (!req_vec_change_apply(&problem->suggested_solutions[i],
238 action_enabler_vector_by_number,
239 new_enabler)) {
240 log_error("While adding hard obligatory reqs to action enabler"
241 " for %s: %s"
242 "Failed to apply solution %s."
243 " Dropping it.",
244 action_rule_name(paction), problem->description,
245 req_vec_change_translation(
246 &problem->suggested_solutions[i],
247 action_enabler_vector_by_number_name));
248 new_enabler->ruledit_disabled = TRUE;
249 req_vec_problem_free(problem);
250 return TRUE;
251 }
252
253 if (problem->num_suggested_solutions - 1 == i) {
254 /* The last modification is to the original enabler. */
255 ae->action = new_enabler->action;
256 ae->ruledit_disabled = new_enabler->ruledit_disabled;
257 requirement_vector_copy(&ae->actor_reqs,
258 &new_enabler->actor_reqs);
259 requirement_vector_copy(&ae->target_reqs,
260 &new_enabler->target_reqs);
261 FC_FREE(new_enabler);
262 } else {
263 /* Register the new enabler */
264 action_enabler_add(new_enabler);
265
266 /* This changes the number of action enablers. */
267 needs_restart = TRUE;
268 }
269 }
270
271 req_vec_problem_free(problem);
272
273 if (needs_restart) {
274 /* May need to apply future upgrades to the copies too. */
275 return TRUE;
276 }
277 }
278
279 return needs_restart;
280}
281
282/**********************************************************************/
286 void rscompat_enablers_add_obligatory_hard_reqs(void)
287{
288 log_normal("action enablers: adding obligatory hard requirements.");
289 log_warn("More than one way to fulfill a new obligatory hard requirement"
290 " may exist."
291 " In that case the enabler is copied so each alternative"
292 " solution is applied to a copy of the enabler."
293 " If an action enabler becomes self contradicting after applying"
294 " a solution it is dropped."
295 " Note that other copies of the original enabler may have"
296 " survived even if one copy is dropped.");
297
298 action_iterate(act_id) {
299 bool restart_enablers_for_action;
300
301 do {
302 restart_enablers_for_action = FALSE;
303 action_enabler_list_iterate(action_enablers_for_action(act_id), ae) {
304 if (ae->ruledit_disabled) {
305 /* Ignore disabled enablers */
306 continue;
307 }
308 if (rscompat_enabler_add_obligatory_hard_reqs(ae)) {
309 /* Something important, probably the number of action enablers
310 * for this action, changed. Start over again on this action's
311 * enablers. */
312 restart_enablers_for_action = TRUE;
313 break;
314 }
315 } action_enabler_list_iterate_end;
316 } while (restart_enablers_for_action);
317 } action_iterate_end;
318}
319
320/**********************************************************************/
330 bool rscompat_names(struct rscompat_info *info)
331{
332 /* No errors encountered. */
333 return TRUE;
334}
335
336/**********************************************************************/
339 static bool effect_list_compat_cb(struct effect *peffect, void *data)
340{
341 struct rscompat_info *info = (struct rscompat_info *)data;
342
343 if (info->version < RSFORMAT_3_2) {
344 if (peffect->type == EFT_GROWTH_FOOD) {
345 /* Equivalent Shrink_Food effect for each old Growth_Food */
346 effect_copy(peffect, EFT_SHRINK_FOOD);
347 } else if (peffect->type == EFT_ACTION_SUCCESS_MOVE_COST) {
348 requirement_vector_iterate(&(peffect->reqs), preq) {
349 if (preq->source.kind == VUT_ACTION
350 && preq->source.value.action == action_by_number(ACTION_ATTACK)) {
351 if (preq->present) {
352 /* Specifically for this action type - create a new effect to OR */
353 struct effect *neffect = effect_copy(peffect, EFT_ACTION_SUCCESS_MOVE_COST);
354
355 requirement_vector_iterate(&(neffect->reqs), nreq) {
356 if (nreq->source.kind == VUT_ACTION
357 && nreq->source.value.action == action_by_number(ACTION_ATTACK)) {
358 nreq->source.value.action = action_by_number(ACTION_COLLECT_RANSOM);
359 }
360 } requirement_vector_iterate_end;
361 } else {
362 /* Specifically prevent with this action type - add a requirement to AND */
363 requirement_vector_append(&(peffect->reqs),
364 req_from_str("Action", "Local",
365 FALSE, FALSE, FALSE,
366 "Collect Ransom"));
367 }
368 break;
369 }
370 } requirement_vector_iterate_end;
371 }
372 }
373
374 /* Go to the next effect. */
375 return TRUE;
376}
377
378/**********************************************************************/
381 void rscompat_postprocess(struct rscompat_info *info)
382{
383 if (!info->compat_mode) {
384 /* There isn't anything here that should be done outside of compat
385 * mode. */
386 return;
387 }
388
389 /* Upgrade existing effects. Done before new effects are added to prevent
390 * the new effects from being upgraded by accident. */
391 iterate_effect_cache(effect_list_compat_cb, info);
392
393 if (info->version < RSFORMAT_3_2) {
394 struct effect *peffect;
395
396 /* Nuke blast radius has moved to the ruleset. */
397 action_iterate(act_id) {
398 const struct action *paction = action_by_number(act_id);
399
400 if (!action_has_result(paction, ACTRES_NUKE)
401 && !action_has_result(paction, ACTRES_NUKE_UNITS)
402 && !action_has_result(paction, ACTRES_SPY_NUKE)) {
403 /* Not relevant. */
404 continue;
405 }
406
407 peffect = effect_new(EFT_NUKE_BLAST_RADIUS_1_SQ, 2, NULL);
408 effect_req_append(peffect, req_from_str("Action", "Local",
409 FALSE, TRUE, FALSE,
410 action_rule_name(paction)));
411 } action_iterate_end;
412
413 /* That Attack and Bombard can't destroy a city
414 * has moved to the ruleset. */
415 peffect = effect_new(EFT_UNIT_NO_LOSE_POP,
416 effect_value_will_make_positive(
417 EFT_UNIT_NO_LOSE_POP),
418 NULL);
419 effect_req_append(peffect, req_from_str("MinSize", "City", FALSE, FALSE,
420 FALSE, "2"));
421
422 action_enablers_iterate(ae) {
423 /* "Attack" is split to regular attack and "Collect Ransom" */
424 if (ae->action == ACTION_ATTACK) {
425 struct action_enabler *enabler = action_enabler_copy(ae);
426
427 enabler->action = ACTION_COLLECT_RANSOM;
428
429 action_enabler_add(enabler);
430 }
431 } action_enablers_iterate_end;
432 }
433
434 /* Make sure that all action enablers added or modified by the
435 * compatibility post processing fulfills all hard action requirements. */
436 rscompat_enablers_add_obligatory_hard_reqs();
437
438 /* The ruleset may need adjustments it didn't need before compatibility
439 * post processing.
440 *
441 * If this isn't done a user of ruleset compatibility that ends up using
442 * the rules risks bad rules. A user that saves the ruleset rather than
443 * using it risks an unexpected change on the next load and save. */
444 autoadjust_ruleset_data();
445}
446
447/**********************************************************************/
450 enum impr_genus_id rscompat_genus_3_2(struct rscompat_info *compat,
451 const bv_impr_flags flags,
452 enum impr_genus_id old_genus)
453{
454 if (compat->compat_mode && compat->version < RSFORMAT_3_2) {
455 if (BV_ISSET(flags, IF_GOLD) && IG_SPECIAL == old_genus) {
456 return IG_CONVERT;
457 }
458 }
459
460 return old_genus;
461}
462
463/**********************************************************************/
466 const char *rscompat_req_range_3_2(struct rscompat_info *compat,
467 const char *type,
468 const char *old_range)
469{
470 if (compat->compat_mode && compat->version < RSFORMAT_3_2) {
471 /* Requirement types that refer to the target tile and now use the
472 * "Tile" range instead of the "Local" range */
473 if (!fc_strcasecmp(req_range_name(REQ_RANGE_LOCAL), old_range)
474 && (!fc_strcasecmp(universals_n_name(VUT_TERRAIN), type)
475 || !fc_strcasecmp(universals_n_name(VUT_TERRAINCLASS), type)
476 || !fc_strcasecmp(universals_n_name(VUT_TERRAINALTER), type)
477 || !fc_strcasecmp(universals_n_name(VUT_CITYTILE), type)
478 || !fc_strcasecmp(universals_n_name(VUT_TERRFLAG), type)
479 || !fc_strcasecmp(universals_n_name(VUT_ROADFLAG), type)
480 || !fc_strcasecmp(universals_n_name(VUT_EXTRA), type)
481 || !fc_strcasecmp(universals_n_name(VUT_MAXTILEUNITS), type)
482 || !fc_strcasecmp(universals_n_name(VUT_EXTRAFLAG), type))) {
483 return req_range_name(REQ_RANGE_TILE);
484 }
485 }
486
487 return old_range;
488}
489
490/**********************************************************************/
493 void rscompat_req_adjust_3_2(const struct rscompat_info *compat,
494 const char **ptype, const char **pname,
495 bool *ppresent, const char *sec_name)
496{
497 char buf[1024];
498
499 if (compat->compat_mode && compat->version < RSFORMAT_3_2) {
500 /* Recreate old "alltemperate" and "singlepole" ServerSetting
501 * requirements with MinLatitude and MaxLatitude. */
502 if (!fc_strcasecmp(universals_n_name(VUT_SERVERSETTING), *ptype)) {
503 if (!fc_strcasecmp("alltemperate", *pname)) {
504 /* alltemperate implies no latitudes != 500
505 * !alltemperate implies latitudes 0 to 1000
506 * ~> alltemperate enabled iff no latitude >= 750
507 * (other numbers in [501,1000] would work as well)
508 * (no latitude <= some number in [0, 499] would work as well) */
509 *ptype = universals_n_name(VUT_MINLATITUDE);
510 *pname = "750";
511 *ppresent = !(*ppresent);
512
513 if (compat->log_cb != NULL) {
514 /* Inform the user that there are different solutions */
515 fc_snprintf(buf, sizeof(buf),
516 "Replaced 'alltemperate' server setting requirement "
517 "in %s with a MinLatitude requirement. Other "
518 "equivalent requirements are possible; make sure it "
519 "makes sense.", sec_name);
520 compat->log_cb(buf);
521 }
522 } else if (!fc_strcasecmp("singlepole", *pname)) {
523 /* Assume we're updating a sane ruleset, i.e. singlepole reqs only
524 * possible/relevant when alltemperate is already disabled.
525 * singlepole implies no latitudes < 0
526 * !singlepole implies latitudes -1000 to -1 (given !alltemperate)
527 * ~> singlepole enabled iff no latitude <= -500
528 * (other numbers in [-1000,-1] would work as well) */
529 *ptype = universals_n_name(VUT_MAXLATITUDE);
530 *pname = "-500";
531 *ppresent = !(*ppresent);
532
533 if (compat->log_cb != NULL) {
534 /* Inform the user that there are different solutions */
535 fc_snprintf(buf, sizeof(buf),
536 "Replaced 'singlepole' server setting requirement "
537 "in %s with a MaxLatitude requirement. Other "
538 "equivalent requirements are possible; make sure it "
539 "makes sense.", sec_name);
540 compat->log_cb(buf);
541 }
542 }
543 }
544
545 /* Former Topology values WrapX and WrapY now Wrap values. */
546 if (!fc_strcasecmp(universals_n_name(VUT_TOPO), *ptype)
547 && (!fc_strcasecmp("WrapX", *pname)
548 || !fc_strcasecmp("WrapY", *pname))) {
549 *ptype = universals_n_name(VUT_WRAP);
550 }
551 }
552}
553
554/**********************************************************************/
559 int add_user_extra_flags_3_2(int start)
560{
561 int i = 0;
562
563 set_user_extra_flag_name(EF_USER_FLAG_1 + start + i++,
564 "CleanAsFallout", NULL);
565
566 return i;
567}
568
569/**********************************************************************/
572 const char *rscompat_extra_rmcause_3_2(struct extra_type *pextra,
573 const char *old_name)
574{
575 const char *retname = old_name;
576
577 if (!fc_strcasecmp("CleanPollution", old_name)) {
578 retname = "Clean";
579 }
580
581 if (!fc_strcasecmp("CleanFallout", old_name)) {
582 /* Don't give this flag to extras that have been using
583 * removal time not tied to terrain, so it won't get
584 * overridden by "ActivityTime" effects we also add. */
585 if (pextra->removal_time == 0) {
586 BV_SET(pextra->flags,
587 extra_flag_id_by_name("CleanAsFallout", fc_strcasecmp));
588 }
589 retname = "Clean";
590 }
591
592 return retname;
593}
594
595/**********************************************************************/
598 void rscompat_extra_adjust_3_2(struct extra_type *pextra)
599{
600 /* Huts were not allowed on polar regions
601 * (defined as "Frozen" - but that was just workaround we don't want to reproduce) */
602 if (is_extra_caused_by(pextra, EC_HUT)) {
603 requirement_vector_append(&pextra->reqs,
604 req_from_str("MaxLatitude", "Tile",
605 FALSE, TRUE, FALSE,
606 "980"));
607 requirement_vector_append(&pextra->reqs,
608 req_from_str("MinLatitude", "Tile",
609 FALSE, TRUE, FALSE,
610 "-980"));
611 }
612}
613
614/**********************************************************************/
618 bool rscompat_setting_needs_special_handling(const char *name)
619{
620 /* Replaced by 'northlatitude' and 'southlatitude' */
621 if (!fc_strcasecmp("alltemperate", name)
622 || !fc_strcasecmp("singlepole", name)) {
623 return TRUE;
624 }
625
626 return FALSE;
627}
628
629/**********************************************************************/
632 void rscompat_settings_do_special_handling(struct section_file *file,
633 const char *section, void (*setdef)(struct setting *pset))
634{
635 /* Replace 'alltemperate' and 'singlepole' with appropriate
636 * 'northlatitude' and 'southlatitude' settings */
637 {
638 bool has_either = FALSE, locks_either = FALSE;
639 bool alltemperate = FALSE, singlepole = FALSE;
640 const char *name;
641 int j;
642
643 for (j = 0; (name = secfile_lookup_str_default(file, NULL,
644 "%s.set%d.name",
645 section, j)); j++) {
646 bool *pval;
647
648 if (!fc_strcasecmp("alltemperate", name)) {
649 pval = &alltemperate;
650 } else if (!fc_strcasecmp("singlepole", name)) {
651 pval = &singlepole;
652 } else {
653 /* neither of the settings we care for */
654 continue;
655 }
656
657 has_either = TRUE;
658
659 if (!secfile_lookup_bool(file, pval, "%s.set%d.value", section, j)) {
660 log_error("Can't read value for setting '%s': %s", name,
661 secfile_error());
662 }
663
664 if (secfile_lookup_bool_default(file, FALSE,
665 "%s.set%d.lock", section, j)) {
666 locks_either = TRUE;
667 }
668 }
669
670 if (has_either) {
671 int north_latitude = alltemperate ? 500 : 1000;
672 int south_latitude = alltemperate ? 500 : (singlepole ? 0 : -1000);
673 struct setting *pset;
674 char reject_msg[256], buf[256];
675
676#define SET_INT_SETTING(name, value, lock) \
677 pset = setting_by_name(name); \
678 fc_assert(pset != NULL && setting_type(pset) == SST_INT); \
679 \
680 if (setting_int_set(pset, value, NULL, reject_msg, \
681 sizeof(reject_msg))) { \
682 log_normal(_("Ruleset: '%s' has been set to %s."), \
683 setting_name(pset), \
684 setting_value_name(pset, TRUE, buf, sizeof(buf))); \
685 } else { \
686 log_error("%s", reject_msg); \
687 } \
688 \
689 setdef(pset); \
690 \
691 if (lock) { \
692 setting_ruleset_lock_set(pset); \
693 log_normal(_("Ruleset: '%s' has been locked by the ruleset."), \
694 setting_name(pset)); \
695 }
696
697 SET_INT_SETTING("northlatitude", north_latitude, locks_either);
698 SET_INT_SETTING("southlatitude", south_latitude, locks_either);
699
700#undef SET_INT_SETTING
701 }
702 }
703}
704
705/**********************************************************************/
708 bool rscompat_terrain_extra_rmtime_3_2(struct section_file *file,
709 const char *tsection,
710 struct terrain *pterrain)
711{
712 int pol_time = 3; /* Old default */
713 int fal_time = 3; /* Old default */
714 const char *filename = secfile_name(file);
715 bool ok = TRUE;
716
717 lookup_time(file, &pol_time,
718 tsection, "clean_pollution_time", filename, NULL, &ok);
719 lookup_time(file, &fal_time,
720 tsection, "clean_fallout_time", filename, NULL, &ok);
721
722 if (pol_time == fal_time) {
723 extra_type_iterate(pextra) {
724 pterrain->extra_removal_times[extra_index(pextra)] = pol_time;
725 } extra_type_iterate_end;
726 } else {
727 struct effect *peffect;
728
729 extra_type_iterate(pextra) {
730 pterrain->extra_removal_times[extra_index(pextra)] = pol_time;
731 } extra_type_iterate_end;
732
733 peffect = effect_new(EFT_ACTIVITY_TIME, fal_time, NULL);
734 effect_req_append(peffect, req_from_str("ExtraFlag", "Local",
735 FALSE, TRUE, TRUE,
736 "CleanAsFallout"));
737 effect_req_append(peffect, req_from_str("Terrain", "Tile",
738 FALSE, TRUE, TRUE,
739 terrain_rule_name(pterrain)));
740 }
741
742 return ok;
743}
744
745/**********************************************************************/
748 const char *rscompat_action_rule_name_3_2(struct rscompat_info *compat,
749 const char *orig)
750{
751 if (compat->compat_mode && compat->version < RSFORMAT_3_2
752 && (!fc_strcasecmp("Clean Pollution", orig)
753 || !fc_strcasecmp("Clean Fallout", orig))) {
754 return "Clean";
755 }
756
757 return orig;
758}
759
760/**********************************************************************/
763 void rscompat_action_enabler_adjust_3_2(struct rscompat_info *compat,
764 struct action_enabler *enabler,
765 const char *orig_name)
766{
767 if (!fc_strcasecmp("CleanAsFallout", orig_name)) {
768 requirement_vector_append(&enabler->target_reqs,
769 req_from_str("ExtraFlag", "Local",
770 FALSE, TRUE, TRUE,
771 "CleanAsFallout"));
772 }
773}
774
775/**********************************************************************/
778 const char *rscompat_action_ui_name_3_2(struct rscompat_info *compat,
779 int act_id)
780{
781 if (compat->compat_mode && compat->version < RSFORMAT_3_2) {
782 if (act_id == ACTION_TRANSPORT_DEBOARD) {
783 return "ui_name_transport_alight";
784 } else if (act_id == ACTION_ROAD) {
785 return "ui_name_road";
786 }
787 }
788
789 return NULL;
790}
action_enabler_suggest_repair
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2670
action_enabler_vector_by_number_name
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:2847
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1968
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2273
action_enabler_copy
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2258
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2306
action_enabler_vector_by_number
struct requirement_vector * action_enabler_vector_by_number(const void *enabler, req_vec_num_in_item number)
Definition actions.c:2823
actions.h
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:517
enabler_get_action
#define enabler_get_action(_enabler_)
Definition actions.h:431
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:429
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:439
action_iterate_end
#define action_iterate_end
Definition actions.h:463
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:511
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:437
action_iterate
#define action_iterate(_act_)
Definition actions.h:459
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
has_capabilities
bool has_capabilities(const char *us, const char *them)
Definition capability.c:86
capability.h
incite_cost
char * incite_cost
Definition comments.c:74
iterate_effect_cache
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1323
effect_new
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:186
effect_copy
struct effect * effect_copy(struct effect *old, enum effect_type override_type)
Definition effects.c:246
effect_req_append
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:266
effect_value_will_make_positive
int effect_value_will_make_positive(enum effect_type type)
Definition effects.c:582
effects.h
set_user_extra_flag_name
void set_user_extra_flag_name(enum extra_flag_id id, const char *name, const char *helptxt)
Definition extras.c:933
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:203
extra_index
#define extra_index(_e_)
Definition extras.h:183
fc_types.h
game.h
type
GType type
Definition repodlgs.c:1313
name
const char * name
Definition inputfile.c:127
log.h
log_warn
#define log_warn(message,...)
Definition log.h:105
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_fatal
#define log_fatal(message,...)
Definition log.h:100
log_normal
#define log_normal(message,...)
Definition log.h:107
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
log_error
#define log_error(message,...)
Definition log.h:103
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
movement.h
registry.h
secfile_error
const char * secfile_error(void)
Definition section_file.c:36
secfile_lookup_int
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Definition registry_ini.c:1975
secfile_lookup_str
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:2175
secfile_lookup_bool_default
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Definition registry_ini.c:1900
secfile_name
const char * secfile_name(const struct section_file *secfile)
Definition registry_ini.c:943
secfile_lookup_str_default
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Definition registry_ini.c:2205
secfile_lookup_bool
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
Definition registry_ini.c:1875
req_vec_change_apply
bool req_vec_change_apply(const struct req_vec_change *modification, requirement_vector_by_number getter, const void *parent_item)
Definition requirements.c:6085
req_vec_change_translation
const char * req_vec_change_translation(const struct req_vec_change *change, const requirement_vector_namer namer)
Definition requirements.c:6012
req_from_str
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
Definition requirements.c:1037
req_vec_problem_free
void req_vec_problem_free(struct req_vec_problem *issue)
Definition requirements.c:6182
requirements.h
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
rscompat_settings_do_special_handling
void rscompat_settings_do_special_handling(struct section_file *file, const char *section, void(*setdef)(struct setting *pset))
Definition rscompat.c:632
rscompat_req_range_3_2
const char * rscompat_req_range_3_2(struct rscompat_info *compat, const char *type, const char *old_range)
Definition rscompat.c:466
add_user_extra_flags_3_2
int add_user_extra_flags_3_2(int start)
Definition rscompat.c:559
SET_INT_SETTING
#define SET_INT_SETTING(name, value, lock)
rscompat_action_ui_name_3_2
const char * rscompat_action_ui_name_3_2(struct rscompat_info *compat, int act_id)
Definition rscompat.c:778
rscompat_enabler_add_obligatory_hard_reqs
static bool rscompat_enabler_add_obligatory_hard_reqs(struct action_enabler *ae)
Definition rscompat.c:166
rscompat_terrain_extra_rmtime_3_2
bool rscompat_terrain_extra_rmtime_3_2(struct section_file *file, const char *tsection, struct terrain *pterrain)
Definition rscompat.c:708
rscompat_names
bool rscompat_names(struct rscompat_info *info)
Definition rscompat.c:330
rscompat_setting_needs_special_handling
bool rscompat_setting_needs_special_handling(const char *name)
Definition rscompat.c:618
rscompat_postprocess
void rscompat_postprocess(struct rscompat_info *info)
Definition rscompat.c:381
rscompat_check_capabilities
int rscompat_check_capabilities(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:66
rscompat_extra_adjust_3_2
void rscompat_extra_adjust_3_2(struct extra_type *pextra)
Definition rscompat.c:598
rscompat_enablers_add_obligatory_hard_reqs
void rscompat_enablers_add_obligatory_hard_reqs(void)
Definition rscompat.c:286
rscompat_action_rule_name_3_2
const char * rscompat_action_rule_name_3_2(struct rscompat_info *compat, const char *orig)
Definition rscompat.c:748
rscompat_req_adjust_3_2
void rscompat_req_adjust_3_2(const struct rscompat_info *compat, const char **ptype, const char **pname, bool *ppresent, const char *sec_name)
Definition rscompat.c:493
effect_list_compat_cb
static bool effect_list_compat_cb(struct effect *peffect, void *data)
Definition rscompat.c:339
rscompat_genus_3_2
enum impr_genus_id rscompat_genus_3_2(struct rscompat_info *compat, const bv_impr_flags flags, enum impr_genus_id old_genus)
Definition rscompat.c:450
rscompat_action_enabler_adjust_3_2
void rscompat_action_enabler_adjust_3_2(struct rscompat_info *compat, struct action_enabler *enabler, const char *orig_name)
Definition rscompat.c:763
rscompat_extra_rmcause_3_2
const char * rscompat_extra_rmcause_3_2(struct extra_type *pextra, const char *old_name)
Definition rscompat.c:572
rscompat_init_info
void rscompat_init_info(struct rscompat_info *info)
Definition rscompat.c:57
rscompat_check_cap_and_version
bool rscompat_check_cap_and_version(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:131
rscompat.h
lookup_time
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)
Definition ruleset.c:1264
RULESET_COMPAT_CAP
#define RULESET_COMPAT_CAP
Definition rscompat.h:27
autoadjust_ruleset_data
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1541
rssanity.h
ruleset.h
ruleset_error
#define ruleset_error(logger, level, format,...)
Definition ruleset.h:57
RSFORMAT_3_2
#define RSFORMAT_3_2
Definition ruleset.h:36
RULESET_CAPABILITIES
#define RULESET_CAPABILITIES
Definition ruleset.h:24
compat
static struct compatibility compat[]
Definition savecompat.c:110
settings.h
action_enabler
Definition actions.h:419
action
Definition actions.h:360
compatibility::version
int version
Definition savecompat.c:93
effect
Definition effects.h:365
extra_type
Definition extras.h:88
extra_type::flags
bv_extra_flags flags
Definition extras.h:132
extra_type::removal_time
int removal_time
Definition extras.h:120
extra_type::reqs
struct requirement_vector reqs
Definition extras.h:106
req_vec_problem
Definition requirements.h:295
rscompat_info
Definition rscompat.h:30
rscompat_info::version
int version
Definition rscompat.h:33
rscompat_info::compat_mode
bool compat_mode
Definition rscompat.h:31
section_file
Definition section_file.h:36
section
Definition section_file.h:28
setting
Definition settings.c:92
terrain
Definition terrain.h:182
terrain::extra_removal_times
int extra_removal_times[MAX_EXTRA_TYPES]
Definition terrain.h:235
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
terrain_rule_name
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
unittype.h