Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/rscompat.c Source File

Freeciv-3.1

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 "game.h"
32#include "movement.h"
33#include "requirements.h"
34#include "unittype.h"
35
36/* server */
37#include "rssanity.h"
38#include "ruleset.h"
39#include "settings.h"
40
41#include "rscompat.h"
42
43#define enough_new_user_flags(_new_flags_, _name_, \
44 _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_) \
45FC_STATIC_ASSERT((ARRAY_SIZE(_new_flags_) \
46 <= _LAST_USER_FLAG_ - _LAST_USER_FLAG_PREV_), \
47 not_enough_new_##_name_##_user_flags)
48
49#define UTYF_LAST_USER_FLAG_3_0 UTYF_USER_FLAG_40
50#define UCF_LAST_USER_FLAG_3_0 UCF_USER_FLAG_8
51#define TER_LAST_USER_FLAG_3_0 TER_USER_8
52
53/**********************************************************************/
56 void rscompat_init_info(struct rscompat_info *info)
57{
58 memset(info, 0, sizeof(*info));
59}
60
61/**********************************************************************/
65 int rscompat_check_capabilities(struct section_file *file,
66 const char *filename,
67 const struct rscompat_info *info)
68{
69 const char *datafile_options;
70 bool ok = FALSE;
71 int format;
72
73 if (!(datafile_options = secfile_lookup_str(file, "datafile.options"))) {
74 log_fatal("\"%s\": ruleset capability problem:", filename);
75 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
76
77 return 0;
78 }
79
80 if (info->compat_mode) {
81 /* Check alternative capstr first, so that when we do the main capstr check,
82 * we already know that failures there are fatal (error message correct, can return
83 * immediately) */
84
85 if (has_capabilities(RULESET_COMPAT_CAP, datafile_options)
86 && has_capabilities(datafile_options, RULESET_COMPAT_CAP)) {
87 ok = TRUE;
88 }
89 }
90
91 if (!ok) {
92 if (!has_capabilities(RULESET_CAPABILITIES, datafile_options)) {
93 log_fatal("\"%s\": ruleset datafile appears incompatible:", filename);
94 log_fatal(" datafile options: %s", datafile_options);
95 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
96 ruleset_error(NULL, LOG_ERROR, "Capability problem");
97
98 return 0;
99 }
100 if (!has_capabilities(datafile_options, RULESET_CAPABILITIES)) {
101 log_fatal("\"%s\": ruleset datafile claims required option(s)"
102 " that we don't support:", filename);
103 log_fatal(" datafile options: %s", datafile_options);
104 log_fatal(" supported options: %s", RULESET_CAPABILITIES);
105 ruleset_error(NULL, LOG_ERROR, "Capability problem");
106
107 return 0;
108 }
109 }
110
111 if (!secfile_lookup_int(file, &format, "datafile.format_version")) {
112 log_error("\"%s\": lacking legal format_version field", filename);
113 ruleset_error(NULL, LOG_ERROR, "%s", secfile_error());
114
115 return 0;
116 } else if (format == 0) {
117 log_error("\"%s\": Illegal format_version value", filename);
118 ruleset_error(NULL, LOG_ERROR, "Format version error");
119 }
120
121 return format;
122}
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/**********************************************************************/
164static bool
165rscompat_enabler_add_obligatory_hard_reqs(struct action_enabler *ae)
166{
167 struct req_vec_problem *problem;
168
169 struct action *paction = action_by_number(ae->action);
170 /* Some changes requires starting to process an action's enablers from
171 * the beginning. */
172 bool needs_restart = FALSE;
173
174 while ((problem = action_enabler_suggest_repair(ae)) != NULL) {
175 /* A hard obligatory requirement is missing. */
176
177 int i;
178
179 if (problem->num_suggested_solutions == 0) {
180 /* Didn't get any suggestions about how to solve this. */
181
182 log_error("While adding hard obligatory reqs to action enabler"
183 " for %s: %s"
184 " Don't know how to fix it."
185 " Dropping it.",
186 action_rule_name(paction), problem->description);
187 ae->ruledit_disabled = TRUE;
188
189 req_vec_problem_free(problem);
190 return TRUE;
191 }
192
193 /* Sanity check. */
194 fc_assert_ret_val(problem->num_suggested_solutions > 0,
195 needs_restart);
196
197 /* Only append is supported for upgrade */
198 for (i = 0; i < problem->num_suggested_solutions; i++) {
199 if (problem->suggested_solutions[i].operation != RVCO_APPEND) {
200 /* A problem that isn't caused by missing obligatory hard
201 * requirements has been detected.
202 *
203 * Probably an old requirement that contradicted a hard requirement
204 * that wasn't documented by making it obligatory. In that case all
205 * suggested solutions has been applied to the enabler creating a
206 * new copy for each possible fulfillment of the new obligatory hard
207 * requirement.
208 *
209 * If another copy of the original enabler has survived this isn't
210 * an error. It probably isn't event an indication of a potential
211 * problem.
212 *
213 * If no possible solution survives the enabler was never in use
214 * because the action it self would have blocked it. In that case
215 * this is an error. */
216
217 log_warn("While adding hard obligatory reqs to action enabler"
218 " for %s: %s"
219 " Dropping it.",
220 action_rule_name(paction), problem->description);
221 ae->ruledit_disabled = TRUE;
222 req_vec_problem_free(problem);
223 return TRUE;
224 }
225 }
226
227 for (i = 0; i < problem->num_suggested_solutions; i++) {
228 struct action_enabler *new_enabler;
229
230 /* There can be more than one suggestion to apply. In that case both
231 * are applied to their own copy. The original should therefore be
232 * kept for now. */
233 new_enabler = action_enabler_copy(ae);
234
235 /* Apply the solution. */
236 if (!req_vec_change_apply(&problem->suggested_solutions[i],
237 action_enabler_vector_by_number,
238 new_enabler)) {
239 log_error("While adding hard obligatory reqs to action enabler"
240 " for %s: %s"
241 "Failed to apply solution %s."
242 " Dropping it.",
243 action_rule_name(paction), problem->description,
244 req_vec_change_translation(
245 &problem->suggested_solutions[i],
246 action_enabler_vector_by_number_name));
247 new_enabler->ruledit_disabled = TRUE;
248 req_vec_problem_free(problem);
249 return TRUE;
250 }
251
252 if (problem->num_suggested_solutions - 1 == i) {
253 /* The last modification is to the original enabler. */
254 ae->action = new_enabler->action;
255 ae->ruledit_disabled = new_enabler->ruledit_disabled;
256 requirement_vector_copy(&ae->actor_reqs,
257 &new_enabler->actor_reqs);
258 requirement_vector_copy(&ae->target_reqs,
259 &new_enabler->target_reqs);
260 FC_FREE(new_enabler);
261 } else {
262 /* Register the new enabler */
263 action_enabler_add(new_enabler);
264
265 /* This changes the number of action enablers. */
266 needs_restart = TRUE;
267 }
268 }
269
270 req_vec_problem_free(problem);
271
272 if (needs_restart) {
273 /* May need to apply future upgrades to the copies too. */
274 return TRUE;
275 }
276 }
277
278 return needs_restart;
279}
280
281/**********************************************************************/
285 void rscompat_enablers_add_obligatory_hard_reqs(void)
286{
287 log_normal("action enablers: adding obligatory hard requirements.");
288 log_warn("More than one way to fulfill a new obligatory hard requirement"
289 " may exist."
290 " In that case the enabler is copied so each alternative"
291 " solution is applied to a copy of the enabler."
292 " If an action enabler becomes self contradicting after applying"
293 " a solution it is dropped."
294 " Note that other copies of the original enabler may have"
295 " survived even if one copy is dropped.");
296
297 action_iterate(act_id) {
298 bool restart_enablers_for_action;
299
300 do {
301 restart_enablers_for_action = FALSE;
302 action_enabler_list_iterate(action_enablers_for_action(act_id), ae) {
303 if (ae->ruledit_disabled) {
304 /* Ignore disabled enablers */
305 continue;
306 }
307 if (rscompat_enabler_add_obligatory_hard_reqs(ae)) {
308 /* Something important, probably the number of action enablers
309 * for this action, changed. Start over again on this action's
310 * enablers. */
311 restart_enablers_for_action = TRUE;
312 break;
313 }
314 } action_enabler_list_iterate_end;
315 } while (restart_enablers_for_action);
316 } action_iterate_end;
317}
318
319/**********************************************************************/
323 static int first_free_unit_type_user_flag(void)
324{
325 int flag;
326
327 /* Find the first unused user defined unit type flag. */
328 for (flag = 0; flag < MAX_NUM_USER_UNIT_FLAGS; flag++) {
329 if (unit_type_flag_id_name_cb(flag + UTYF_USER_FLAG_1) == NULL) {
330 return flag;
331 }
332 }
333
334 /* All unit type user flags are taken. */
335 return MAX_NUM_USER_UNIT_FLAGS;
336}
337
338/**********************************************************************/
342 static int first_free_unit_class_user_flag(void)
343{
344 int flag;
345
346 /* Find the first unused user defined unit class flag. */
347 for (flag = 0; flag < MAX_NUM_USER_UCLASS_FLAGS; flag++) {
348 if (unit_class_flag_id_name_cb(flag + UCF_USER_FLAG_1) == NULL) {
349 return flag;
350 }
351 }
352
353 /* All unit class user flags are taken. */
354 return MAX_NUM_USER_UCLASS_FLAGS;
355}
356
357/**********************************************************************/
361 static int first_free_terrain_user_flag(void)
362{
363 int flag;
364
365 /* Find the first unused user defined terrain flag. */
366 for (flag = 0; flag < MAX_NUM_USER_TER_FLAGS; flag++) {
367 if (terrain_flag_id_name_cb(flag + TER_USER_1) == NULL) {
368 return flag;
369 }
370 }
371
372 /* All terrain user flags are taken. */
373 return MAX_NUM_USER_TER_FLAGS;
374}
375
376/**********************************************************************/
386 bool rscompat_names(struct rscompat_info *info)
387{
388 if (info->version < RSFORMAT_3_1) {
389 /* Some unit type flags moved to the ruleset between 3.0 and 3.1.
390 * Add them back as user flags.
391 * XXX: ruleset might not need all of these, and may have enough
392 * flags of its own that these additional ones prevent conversion. */
393 const struct {
394 const char *name;
395 const char *helptxt;
396 } new_flags_31[] = {
397 { N_("BeachLander"), N_("Won't lose all movement when moving from"
398 " non-native terrain to native terrain.") },
399 { N_("Cant_Fortify"), NULL },
400 { N_("OneAttack"), NULL },
401 };
402 enough_new_user_flags(new_flags_31, unit_type,
403 UTYF_LAST_USER_FLAG, UTYF_LAST_USER_FLAG_3_0);
404
405 /* Some unit class flags moved to the ruleset between 3.0 and 3.1.
406 * Add them back as user flags.
407 * XXX: ruleset might not need all of these, and may have enough
408 * flags of its own that these additional ones prevent conversion. */
409 const struct {
410 const char *name;
411 const char *helptxt;
412 } new_class_flags_31[] = {
413 { N_("Missile"), N_("Unit is destroyed when it attacks") },
414 { N_("CanPillage"), N_("Can pillage tile improvements.") },
415 { N_("CanFortify"), N_("Gets a 50% defensive bonus while"
416 " in cities.") },
417 { N_("HutNothing"), N_("Does nothing to huts.") },
418 };
419 enough_new_user_flags(new_class_flags_31, unit_class,
420 UCF_LAST_USER_FLAG, UCF_LAST_USER_FLAG_3_0);
421
422 int first_free;
423 int i;
424
425 /* Unit type flags. */
426 first_free = first_free_unit_type_user_flag() + UTYF_USER_FLAG_1;
427
428 for (i = 0; i < ARRAY_SIZE(new_flags_31); i++) {
429 if (UTYF_USER_FLAG_1 + MAX_NUM_USER_UNIT_FLAGS <= first_free + i) {
430 /* Can't add the user unit type flags. */
431 ruleset_error(NULL, LOG_ERROR,
432 "Can't upgrade the ruleset. Not enough free unit type "
433 "user flags to add user flags for the unit type flags "
434 "that used to be hardcoded.");
435 return FALSE;
436 }
437 /* Shouldn't be possible for valid old ruleset to have flag names that
438 * clash with these ones */
439 if (unit_type_flag_id_by_name(new_flags_31[i].name, fc_strcasecmp)
440 != unit_type_flag_id_invalid()) {
441 ruleset_error(NULL, LOG_ERROR,
442 "Ruleset had illegal user unit type flag '%s'",
443 new_flags_31[i].name);
444 return FALSE;
445 }
446 set_user_unit_type_flag_name(first_free + i,
447 new_flags_31[i].name,
448 new_flags_31[i].helptxt);
449 }
450
451 /* Unit type class flags. */
452 first_free = first_free_unit_class_user_flag() + UCF_USER_FLAG_1;
453
454 for (i = 0; i < ARRAY_SIZE(new_class_flags_31); i++) {
455 if (UCF_USER_FLAG_1 + MAX_NUM_USER_UCLASS_FLAGS <= first_free + i) {
456 /* Can't add the user unit type class flags. */
457 ruleset_error(NULL, LOG_ERROR,
458 "Can't upgrade the ruleset. Not enough free unit "
459 "type class user flags to add user flags for the "
460 "unit type class flags that used to be hardcoded.");
461 return FALSE;
462 }
463 /* Shouldn't be possible for valid old ruleset to have flag names that
464 * clash with these ones */
465 if (unit_class_flag_id_by_name(new_class_flags_31[i].name,
466 fc_strcasecmp)
467 != unit_class_flag_id_invalid()) {
468 ruleset_error(NULL, LOG_ERROR,
469 "Ruleset had illegal user unit class flag '%s'",
470 new_class_flags_31[i].name);
471 return FALSE;
472 }
473 set_user_unit_class_flag_name(first_free + i,
474 new_class_flags_31[i].name,
475 new_class_flags_31[i].helptxt);
476 }
477 }
478
479 if (info->version < RSFORMAT_3_1) {
480 /* Some terrain flags moved to the ruleset between 3.0 and 3.1.
481 * Add them back as user flags.
482 * XXX: ruleset might not need all of these, and may have enough
483 * flags of its own that these additional ones prevent conversion. */
484 const struct {
485 const char *name;
486 const char *helptxt;
487 } new_flags_31[] = {
488 { N_("NoFortify"), N_("No units can fortify on this terrain.") },
489 };
490 enough_new_user_flags(new_flags_31, terrain,
491 TER_USER_LAST, TER_LAST_USER_FLAG_3_0);
492
493 int first_free;
494 int i;
495
496 /* Terrain flags. */
497 first_free = first_free_terrain_user_flag() + TER_USER_1;
498
499 for (i = 0; i < ARRAY_SIZE(new_flags_31); i++) {
500 if (TER_USER_1 + MAX_NUM_USER_TER_FLAGS <= first_free + i) {
501 /* Can't add the user terrain flags. */
502 ruleset_error(NULL, LOG_ERROR,
503 "Can't upgrade the ruleset. Not enough free terrain "
504 "user flags to add user flags for the terrain flags "
505 "that used to be hardcoded.");
506 return FALSE;
507 }
508 /* Shouldn't be possible for valid old ruleset to have flag names that
509 * clash with these ones */
510 if (terrain_flag_id_by_name(new_flags_31[i].name, fc_strcasecmp)
511 != terrain_flag_id_invalid()) {
512 ruleset_error(NULL, LOG_ERROR,
513 "Ruleset had illegal user terrain flag '%s'",
514 new_flags_31[i].name);
515 return FALSE;
516 }
517 set_user_terrain_flag_name(first_free + i,
518 new_flags_31[i].name,
519 new_flags_31[i].helptxt);
520 }
521 }
522
523 /* No errors encountered. */
524 return TRUE;
525}
526
527/**********************************************************************/
531 static void split_action_name_update(struct action *original,
532 struct action *copy,
533 const char *name_modification)
534{
535 fc_snprintf(copy->ui_name, MAX_LEN_NAME,
536 name_modification, original->ui_name);
537}
538
539/**********************************************************************/
551 static bool effect_handle_split_universal(struct effect *peffect,
552 struct universal original,
553 struct universal separated)
554{
555 if (universal_is_mentioned_by_requirements(&peffect->reqs, &original)) {
556 /* Copy the old effect. */
557 struct effect *peffect_copy = effect_copy(peffect);
558
559 /* Replace the original requirement with the separated requirement. */
560 return universal_replace_in_req_vec(&peffect_copy->reqs,
561 &original, &separated);
562 }
563
564 return FALSE;
565}
566
567/**********************************************************************/
570 static bool effect_list_compat_cb(struct effect *peffect, void *data)
571{
572 struct rscompat_info *info = (struct rscompat_info *)data;
573
574 if (info->version < RSFORMAT_3_1) {
575 /* Attack has been split in regular "Attack" and "Suicide Attack". */
576 effect_handle_split_universal(peffect,
577 universal_by_number(VUT_ACTION, ACTION_ATTACK),
578 universal_by_number(VUT_ACTION, ACTION_SUICIDE_ATTACK));
579
580 /* "Nuke City" and "Nuke Units" has been split from "Explode Nuclear".
581 * "Explode Nuclear" is now only about exploding at the current tile. */
582 effect_handle_split_universal(peffect,
583 universal_by_number(VUT_ACTION, ACTION_NUKE),
584 universal_by_number(VUT_ACTION, ACTION_NUKE_CITY));
585 effect_handle_split_universal(peffect,
586 universal_by_number(VUT_ACTION, ACTION_NUKE),
587 universal_by_number(VUT_ACTION, ACTION_NUKE_UNITS));
588
589 /* Production or building targeted actions have been split in one action
590 * for each target. */
591 effect_handle_split_universal(peffect,
592 universal_by_number(VUT_ACTION, ACTION_SPY_TARGETED_SABOTAGE_CITY),
593 universal_by_number(VUT_ACTION, ACTION_SPY_SABOTAGE_CITY_PRODUCTION));
594 effect_handle_split_universal(peffect,
595 universal_by_number(VUT_ACTION, ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC),
596 universal_by_number(VUT_ACTION, ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC));
597
598 if (peffect->type == EFT_ILLEGAL_ACTION_MOVE_COST) {
599 /* Boarding a transporter became action enabler controlled in
600 * Freeciv 3.1. Old hard coded rules had no punishment for trying to
601 * do this when it is illegal according to the rules. */
602 effect_req_append(peffect, req_from_str("Action", "Local", FALSE,
603 FALSE, FALSE,
604 "Transport Board"));
605 effect_req_append(peffect, req_from_str("Action", "Local", FALSE,
606 FALSE, FALSE,
607 "Transport Embark"));
608
609 /* Disembarking became action enabler controlled in Freeciv 3.1. Old
610 * hard coded rules had no punishment for trying to do those when it
611 * is illegal according to the rules. */
612 effect_req_append(peffect, req_from_str("Action", "Local", FALSE,
613 FALSE, FALSE,
614 "Transport Disembark"));
615 effect_req_append(peffect, req_from_str("Action", "Local", FALSE,
616 FALSE, FALSE,
617 "Transport Disembark 2"));
618 }
619
620 /* "Paradrop Unit" has been split by side effects. */
621 effect_handle_split_universal(peffect,
622 universal_by_number(VUT_ACTION, ACTION_PARADROP),
623 universal_by_number(VUT_ACTION, ACTION_PARADROP_CONQUER));
624 effect_handle_split_universal(peffect,
625 universal_by_number(VUT_ACTION, ACTION_PARADROP),
626 universal_by_number(VUT_ACTION, ACTION_PARADROP_ENTER));
627 effect_handle_split_universal(peffect,
628 universal_by_number(VUT_ACTION, ACTION_PARADROP),
629 universal_by_number(VUT_ACTION, ACTION_PARADROP_ENTER_CONQUER));
630 effect_handle_split_universal(peffect,
631 universal_by_number(VUT_ACTION, ACTION_PARADROP),
632 universal_by_number(VUT_ACTION, ACTION_PARADROP_FRIGHTEN));
633 effect_handle_split_universal(peffect,
634 universal_by_number(VUT_ACTION, ACTION_PARADROP),
635 universal_by_number(VUT_ACTION, ACTION_PARADROP_FRIGHTEN_CONQUER));
636 }
637
638 /* Go to the next effect. */
639 return TRUE;
640}
641
642/**********************************************************************/
645 static void paratroopers_mr_sub_to_effect(struct unit_type *putype,
646 struct action *paction)
647{
648 struct effect *peffect;
649
650 /* Subtract the value via the Action_Success_Actor_Move_Cost effect */
651 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
652 putype->rscompat_cache.paratroopers_mr_sub,
653 NULL);
654
655 /* The reduction only applies to this action. */
656 effect_req_append(peffect,
657 req_from_str("Action", "Local", FALSE, TRUE, FALSE,
658 action_rule_name(paction)));
659
660 /* The reduction only applies to this unit type. */
661 effect_req_append(peffect,
662 req_from_str("UnitType", "Local", FALSE, TRUE, FALSE,
663 utype_rule_name(putype)));
664}
665
666/**********************************************************************/
670 static bool ete_is_target_req(struct requirement *preq)
671{
672 switch (preq->source.kind) {
673 /* World range only - listed in actor reqs */
674 case VUT_MINYEAR:
675 case VUT_TOPO:
676 case VUT_MINCALFRAG:
677 case VUT_SERVERSETTING:
678 return FALSE;
679
680 /* Actor ones */
681 case VUT_ADVANCE:
682 case VUT_GOVERNMENT:
683 case VUT_NATION:
684 case VUT_UTYPE:
685 case VUT_UTFLAG:
686 case VUT_UCLASS:
687 case VUT_UCFLAG:
688 case VUT_AI_LEVEL:
689 case VUT_NATIONALITY:
690 case VUT_TECHFLAG:
691 case VUT_ACHIEVEMENT:
692 case VUT_DIPLREL:
693 case VUT_STYLE:
694 case VUT_MINCULTURE:
695 case VUT_UNITSTATE:
696 case VUT_MINMOVES:
697 case VUT_MINVETERAN:
698 case VUT_MINHP:
699 case VUT_NATIONGROUP:
700 case VUT_ACTION:
701 case VUT_MINTECHS:
702 case VUT_ACTIVITY:
703 case VUT_DIPLREL_UNITANY: /* ? */
704 case VUT_DIPLREL_UNITANY_O: /* ? */
705 return FALSE;
706
707 /* Target ones */
708 case VUT_IMPROVEMENT:
709 case VUT_TERRAIN:
710 case VUT_MINSIZE:
711 case VUT_TERRAINCLASS:
712 case VUT_TERRAINALTER:
713 case VUT_CITYTILE:
714 case VUT_TERRFLAG:
715 case VUT_ROADFLAG:
716 case VUT_EXTRA:
717 case VUT_MAXTILEUNITS:
718 case VUT_EXTRAFLAG:
719 case VUT_CITYSTATUS:
720 case VUT_MINFOREIGNPCT:
721 case VUT_DIPLREL_TILE: /* ? */
722 case VUT_DIPLREL_TILE_O: /* ? */
723 return TRUE;
724
725 /* Ones that are actor reqs at some range, target reqs at another range */
726 case VUT_AGE:
727 if (preq->range == REQ_RANGE_CITY) {
728 return TRUE;
729 }
730 return FALSE;
731
732 /* Ones that make equally little sense both as actor and target req */
733 case VUT_NONE:
734 case VUT_OTYPE:
735 case VUT_SPECIALIST:
736 case VUT_GOOD:
737 case VUT_IMPR_GENUS:
738 return FALSE;
739 case VUT_COUNT:
740 fc_assert(preq->source.kind != VUT_COUNT);
741 return FALSE;
742 }
743
744 fc_assert(FALSE);
745
746 return FALSE;
747}
748
749/**********************************************************************/
752 static void effect_to_enabler(action_id action, struct section_file *file,
753 const char *sec_name, struct rscompat_info *compat,
754 const char *type)
755{
756 int value = secfile_lookup_int_default(file, 1, "%s.value", sec_name);
757 char buf[1024];
758
759 if (value > 0) {
760 /* It was an enabling effect. Add enabler */
761 struct action_enabler *enabler;
762 struct requirement_vector *reqs;
763 struct requirement settler_req;
764
765 enabler = action_enabler_new();
766 enabler->action = action;
767
768 reqs = lookup_req_list(file, compat, sec_name, "reqs", "old effect");
769
770 requirement_vector_iterate(reqs, preq) {
771 if (ete_is_target_req(preq)) {
772 requirement_vector_append(&enabler->target_reqs, *preq);
773 } else {
774 requirement_vector_append(&enabler->actor_reqs, *preq);
775 }
776 } requirement_vector_iterate_end;
777
778 settler_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, FALSE, TRUE, FALSE,
779 UTYF_SETTLERS);
780 requirement_vector_append(&enabler->actor_reqs, settler_req);
781
782 /* Add the enabler to the ruleset. */
783 action_enabler_add(enabler);
784
785 if (compat->log_cb != NULL) {
786 fc_snprintf(buf, sizeof(buf),
787 "Converted effect %s in %s to an action enabler. Make sure requirements "
788 "are correctly divided to actor and target requirements.",
789 type, sec_name);
790 compat->log_cb(buf);
791 }
792 } else if (value < 0) {
793 if (compat->log_cb != NULL) {
794 fc_snprintf(buf, sizeof(buf),
795 "%s effect with negative value in %s can't be automatically converted "
796 "to an action enabler. Do that manually.", type, sec_name);
797 compat->log_cb(buf);
798 }
799 }
800}
801
802/**********************************************************************/
806 bool rscompat_old_effect_3_1(const char *type, struct section_file *file,
807 const char *sec_name, struct rscompat_info *compat)
808{
809 if (compat->version < RSFORMAT_3_1) {
810 if (!fc_strcasecmp(type, "Transform_Possible")) {
811 effect_to_enabler(ACTION_TRANSFORM_TERRAIN, file, sec_name, compat, type);
812 return TRUE;
813 }
814 if (!fc_strcasecmp(type, "Irrig_TF_Possible")) {
815 effect_to_enabler(ACTION_CULTIVATE, file, sec_name, compat, type);
816 return TRUE;
817 }
818 if (!fc_strcasecmp(type, "Mining_TF_Possible")) {
819 effect_to_enabler(ACTION_PLANT, file, sec_name, compat, type);
820 return TRUE;
821 }
822 if (!fc_strcasecmp(type, "Mining_Possible")) {
823 effect_to_enabler(ACTION_MINE, file, sec_name, compat, type);
824 return TRUE;
825 }
826 if (!fc_strcasecmp(type, "Irrig_Possible")) {
827 effect_to_enabler(ACTION_IRRIGATE, file, sec_name, compat, type);
828 return TRUE;
829 }
830 }
831
832 return FALSE;
833}
834
835/**********************************************************************/
839 void rscompat_adjust_pre_sanity(struct rscompat_info *info)
840{
841 if (!info->compat_mode) {
842 /* There isn't anything here that should be done outside of compat
843 * mode. */
844 return;
845 }
846
847 if (info->version < RSFORMAT_3_1) {
848 improvement_iterate(pimprove) {
849 if (pimprove->upkeep != 0 && is_wonder(pimprove)) {
850 pimprove->upkeep = 0;
851 }
852 } improvement_iterate_end;
853 }
854}
855
856/**********************************************************************/
859 void rscompat_postprocess(struct rscompat_info *info)
860{
861 if (!info->compat_mode) {
862 /* There isn't anything here that should be done outside of compat
863 * mode. */
864 return;
865 }
866
867 /* Upgrade existing effects. Done before new effects are added to prevent
868 * the new effects from being upgraded by accident. */
869 iterate_effect_cache(effect_list_compat_cb, info);
870
871 if (info->version < RSFORMAT_3_1) {
872 struct effect *peffect;
873
874 /* Post successful action move fragment loss for "Bombard"
875 * has moved to the ruleset. */
876 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
877 MAX_MOVE_FRAGS, NULL);
878
879 /* The reduction only applies to "Bombard". */
880 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
881 TRUE, "Bombard"));
882
883 /* Post successful action move fragment loss for "Heal Unit"
884 * has moved to the ruleset. */
885 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
886 MAX_MOVE_FRAGS, NULL);
887
888 /* The reduction only applies to "Heal Unit". */
889 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
890 TRUE, "Heal Unit"));
891
892 /* Post successful action move fragment loss for "Expel Unit"
893 * has moved to the ruleset. */
894 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
895 SINGLE_MOVE, NULL);
896
897 /* The reduction only applies to "Expel Unit". */
898 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
899 TRUE, "Expel Unit"));
900
901 /* Post successful action move fragment loss for "Capture Units"
902 * has moved to the ruleset. */
903 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
904 SINGLE_MOVE, NULL);
905
906 /* The reduction only applies to "Capture Units". */
907 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
908 TRUE, "Capture Units"));
909
910 /* Post successful action move fragment loss for "Establish Embassy"
911 * has moved to the ruleset. */
912 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
913 1, NULL);
914
915 /* The reduction only applies to "Establish Embassy". */
916 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
917 TRUE, "Establish Embassy"));
918
919 /* Post successful action move fragment loss for "Investigate City"
920 * has moved to the ruleset. */
921 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
922 1, NULL);
923
924 /* The reduction only applies to "Investigate City". */
925 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
926 TRUE, "Investigate City"));
927
928 /* Post successful action move fragment loss for targets of "Expel Unit"
929 * has moved to the ruleset. */
930 peffect = effect_new(EFT_ACTION_SUCCESS_TARGET_MOVE_COST,
931 MAX_MOVE_FRAGS, NULL);
932
933 /* The reduction only applies to "Expel Unit". */
934 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
935 TRUE, "Expel Unit"));
936
937 /* Post successful action move fragment loss for "OneAttack"
938 * has moved to the ruleset. */
939 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
940 MAX_MOVE_FRAGS, NULL);
941 /* The reduction only applies to "Attack". */
942 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
943 TRUE, "Attack"));
944 /* The reduction only applies to "OneAttack". */
945 effect_req_append(peffect, req_from_str("UnitFlag", "Local", FALSE, TRUE,
946 TRUE, "OneAttack"));
947
948 action_by_result_iterate(paction, ACTRES_ATTACK) {
949 if (paction->actor_consuming_always) {
950 /* Not relevant. */
951 continue;
952 }
953
954 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
955 SINGLE_MOVE, NULL);
956 /* The reduction only applies to this action. */
957 effect_req_append(peffect, req_from_str("Action", "Local",
958 FALSE, TRUE, TRUE,
959 action_rule_name(paction)));
960 /* The reduction doesn't apply to "OneAttack". */
961 effect_req_append(peffect, req_from_str("UnitFlag", "Local",
962 FALSE, FALSE, TRUE,
963 "OneAttack"));
964 } action_by_result_iterate_end;
965
966 /* Post successful action move fragment loss for spy post action escape
967 * has moved to the ruleset. */
968 action_iterate(act_id) {
969 struct action *paction = action_by_number(act_id);
970
971 if (paction->actor.is_unit.moves_actor != MAK_ESCAPE
972 || paction->actor_consuming_always) {
973 /* Not relevant. */
974 continue;
975 }
976
977 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
978 MAX_MOVE_FRAGS, NULL);
979 /* The reduction only applies to this action. */
980 effect_req_append(peffect, req_from_str("Action", "Local",
981 FALSE, TRUE, TRUE,
982 action_rule_name(paction)));
983 } action_iterate_end;
984
985 /* Post successful action move fragment loss for targets of
986 * "Paradrop Unit" has moved to the Action_Success_Actor_Move_Cost
987 * effect. */
988 unit_type_iterate(putype) {
989 if (!utype_can_do_action(putype, ACTION_PARADROP)) {
990 /* Not relevant */
991 continue;
992 }
993
994 if (putype->rscompat_cache.paratroopers_mr_sub == 0) {
995 /* Not relevant */
996 continue;
997 }
998
999 action_by_result_iterate(paction, ACTRES_PARADROP) {
1000 paratroopers_mr_sub_to_effect(putype, paction);
1001 } action_by_result_iterate_end;
1002 action_by_result_iterate(paction, ACTRES_PARADROP_CONQUER) {
1003 paratroopers_mr_sub_to_effect(putype, paction);
1004 } action_by_result_iterate_end;
1005 } unit_type_iterate_end;
1006
1007 /* Fortifying rules have been unhardcoded to effects. */
1008 peffect = effect_new(EFT_FORTIFY_DEFENSE_BONUS, 50, NULL);
1009
1010 /* Unit actually fortified. This does not need checks for unit class or
1011 * type flags for unit's ability to fortify as it would not be fortified
1012 * if it can't. */
1013 effect_req_append(peffect, req_from_str("Activity", "Local", FALSE, TRUE,
1014 FALSE, "Fortified"));
1015
1016 /* Fortify bonus in cities */
1017 peffect = effect_new(EFT_FORTIFY_DEFENSE_BONUS, 50, NULL);
1018
1019 /* City center */
1020 effect_req_append(peffect, req_from_str("CityTile", "Local", FALSE, TRUE,
1021 FALSE, "Center"));
1022 /* Not cumulative with regular fortified bonus */
1023 effect_req_append(peffect, req_from_str("Activity", "Local", FALSE, FALSE,
1024 FALSE, "Fortified"));
1025 /* Unit flags */
1026 effect_req_append(peffect, req_from_str("UnitClassFlag", "Local", FALSE, TRUE,
1027 FALSE, "CanFortify"));
1028 effect_req_append(peffect, req_from_str("UnitFlag", "Local", FALSE, FALSE,
1029 FALSE, "Cant_Fortify"));
1030
1031 /* The probability that "Steal Maps" and "Steal Maps Escape" steals the
1032 * map of a tile has moved to the ruleset. */
1033 effect_new(EFT_MAPS_STOLEN_PCT, -50, NULL);
1034
1035 /* The rule that "Recycle Unit"'s unit shield value is 50% has moved to
1036 * the ruleset. */
1037 peffect = effect_new(EFT_UNIT_SHIELD_VALUE_PCT, -50, NULL);
1038 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
1039 FALSE, "Recycle Unit"));
1040
1041 /* The rule that "Upgrade Unit"'s current unit shield value is 50% when
1042 * calculating unit upgrade price has moved to the ruleset. */
1043 peffect = effect_new(EFT_UNIT_SHIELD_VALUE_PCT, -50, NULL);
1044 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
1045 FALSE, "Upgrade Unit"));
1046
1047 /* The rule that "Heal Unit" heals up to 25% has moved to the
1048 * ruleset. */
1049 peffect = effect_new(EFT_HEAL_UNIT_PCT, -75, NULL);
1050 effect_req_append(peffect, req_from_str("Action", "Local", FALSE, TRUE,
1051 FALSE, "Heal Unit"));
1052
1053 /* The rule that unit in a city has at least 1/3 of its HP in the
1054 * beginning of the new turn has moved to the ruleset. */
1055 peffect = effect_new(EFT_MIN_HP_PCT, 33, NULL);
1056 effect_req_append(peffect, req_from_str("CityTile", "Local", FALSE, TRUE,
1057 FALSE, "Center"));
1058
1059 /* The base unit regeneration rule is in ruleset now. */
1060 peffect = effect_new(EFT_HP_REGEN_2, 10, NULL);
1061 /* Does not apply to any unit class with HP loss */
1062 unit_class_iterate(pclass) {
1063 if (pclass->hp_loss_pct) {
1064 effect_req_append(peffect, req_from_str("UnitClass", "Local", FALSE,
1065 FALSE, FALSE,
1066 uclass_rule_name(pclass)));
1067 }
1068 } unit_class_iterate_end;
1069
1070 /* The rule that fortified unit regenerates extra 10% has been moved
1071 * to the ruleset. */
1072 peffect = effect_new(EFT_HP_REGEN_2, 10, NULL);
1073 effect_req_append(peffect, req_from_str("Activity", "Local", FALSE, TRUE,
1074 FALSE, "Fortified"));
1075
1076 /* Help ruleset authors specify the new arguments to unit_move() and
1077 * unit_teleport() by introducing boolean effects */
1078 log_normal(_("Preparing user effects to help you port edit.unit_move()"
1079 " and edit.unit_teleport() Lua calls."));
1080 log_normal(_("It is safe to delete the effects if you don't use"
1081 " unit_move() or unit_teleport() or if you want to fill"
1082 " in the new parameters with your own values."));
1083 log_normal(_("Use effects.unit_bonus() and effects.unit_vs_tile_bonus()"
1084 " to get the value of the user effects"
1085 " if you wish to use them."));
1086
1087 /* EFT_USER_EFFECT_1 is if a unit may occupy a city */
1088 log_normal(_("User_Effect_1 is now if a unit can conquer a city."));
1089 peffect = effect_new(EFT_USER_EFFECT_1, 1, NULL);
1090 effect_req_append(peffect,
1091 req_from_str("UnitClassFlag", "Local",
1092 FALSE, TRUE, FALSE, "CanOccupyCity"));
1093 effect_req_append(peffect,
1094 req_from_str("UnitFlag", "Local",
1095 FALSE, FALSE, FALSE, "NonMil"));
1096 effect_req_append(peffect,
1097 req_from_str("DiplRel", "Local",
1098 FALSE, TRUE, FALSE, "War"));
1099 nations_iterate(pnation) {
1100 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
1101 effect_req_append(peffect,
1102 req_from_str("Nation", "Player",
1103 FALSE, FALSE, FALSE,
1104 nation_rule_name(pnation)));
1105 }
1106 } nations_iterate_end;
1107
1108 /* EFT_USER_EFFECT_2 is if a unit may occupy an extra */
1109 log_normal(_("User_Effect_2 is now if a unit can conquer an extra."));
1110 peffect = effect_new(EFT_USER_EFFECT_2, 1, NULL);
1111 effect_req_append(peffect,
1112 req_from_str("DiplRel", "Local",
1113 FALSE, TRUE, FALSE, "War"));
1114
1115 peffect = effect_new(EFT_USER_EFFECT_2, 1, NULL);
1116 effect_req_append(peffect,
1117 req_from_str("CityTile", "Local",
1118 FALSE, FALSE, FALSE, "Extras Owned"));
1119
1120 /* EFT_USER_EFFECT_3 is if a unit may enter a hut */
1121 log_normal(_("User_Effect_3 is now if a unit can enter a hut."));
1122 peffect = effect_new(EFT_USER_EFFECT_3, 1, NULL);
1123 effect_req_append(peffect,
1124 req_from_str("UnitClassFlag", "Local",
1125 FALSE, FALSE, FALSE, "HutFrighten"));
1126 effect_req_append(peffect,
1127 req_from_str("UnitClassFlag", "Local",
1128 FALSE, FALSE, FALSE, "HutNothing"));
1129
1130 /* EFT_USER_EFFECT_4 is if a unit may frighten a hut */
1131 log_normal(_("User_Effect_4 is now if a unit can frighten a hut."));
1132 peffect = effect_new(EFT_USER_EFFECT_4, 1, NULL);
1133 effect_req_append(peffect,
1134 req_from_str("UnitClassFlag", "Local",
1135 FALSE, TRUE, FALSE, "HutFrighten"));
1136 effect_req_append(peffect,
1137 req_from_str("UnitClassFlag", "Local",
1138 FALSE, FALSE, FALSE, "HutNothing"));
1139 }
1140
1141 if (info->version < RSFORMAT_3_1) {
1142 /* New enablers */
1143 struct action_enabler *enabler;
1144 struct requirement e_req;
1145 struct action *paction;
1146
1147 paction = action_by_number(ACTION_NUKE_CITY);
1148 paction->target_kind = ATK_CITY;
1149 paction->actor_consuming_always = TRUE;
1150 paction->min_distance = 1;
1151 paction->max_distance = RS_DEFAULT_ACTION_MAX_RANGE;
1152
1153 paction = action_by_number(ACTION_NUKE);
1154 paction->actor_consuming_always = TRUE;
1155 paction->min_distance = 0;
1156
1157 paction = action_by_number(ACTION_NUKE_UNITS);
1158 paction->actor_consuming_always = TRUE;
1159 paction->min_distance = 1;
1160
1161 paction = action_by_number(ACTION_FOUND_CITY);
1162 paction->actor_consuming_always = TRUE;
1163
1164 enabler = action_enabler_new();
1165 enabler->action = ACTION_PILLAGE;
1166 e_req = req_from_str("UnitClassFlag", "Local", FALSE, TRUE, FALSE,
1167 "CanPillage");
1168 requirement_vector_append(&enabler->actor_reqs, e_req);
1169 action_enabler_add(enabler);
1170
1171 enabler = action_enabler_new();
1172 enabler->action = ACTION_CLEAN_FALLOUT;
1173 e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, FALSE, TRUE, FALSE,
1174 UTYF_SETTLERS);
1175 requirement_vector_append(&enabler->actor_reqs, e_req);
1176 action_enabler_add(enabler);
1177
1178 enabler = action_enabler_new();
1179 enabler->action = ACTION_CLEAN_POLLUTION;
1180 e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, FALSE, TRUE, FALSE,
1181 UTYF_SETTLERS);
1182 requirement_vector_append(&enabler->actor_reqs, e_req);
1183 action_enabler_add(enabler);
1184
1185 enabler = action_enabler_new();
1186 enabler->action = ACTION_FORTIFY;
1187 e_req = req_from_str("UnitClassFlag", "Local", FALSE, TRUE, TRUE,
1188 "CanFortify");
1189 requirement_vector_append(&enabler->actor_reqs, e_req);
1190 e_req = req_from_str("UnitFlag", "Local", FALSE, FALSE, TRUE,
1191 "Cant_Fortify");
1192 requirement_vector_append(&enabler->actor_reqs, e_req);
1193 e_req = req_from_str("TerrainFlag", "Local", FALSE, FALSE, TRUE,
1194 "NoFortify");
1195 requirement_vector_append(&enabler->actor_reqs, e_req);
1196 action_enabler_add(enabler);
1197
1198 enabler = action_enabler_new();
1199 enabler->action = ACTION_FORTIFY;
1200 e_req = req_from_str("UnitClassFlag", "Local", FALSE, TRUE, TRUE,
1201 "CanFortify");
1202 requirement_vector_append(&enabler->actor_reqs, e_req);
1203 e_req = req_from_str("UnitFlag", "Local", FALSE, FALSE, TRUE,
1204 "Cant_Fortify");
1205 requirement_vector_append(&enabler->actor_reqs, e_req);
1206 e_req = req_from_str("CityTile", "Local", FALSE, TRUE, TRUE,
1207 "Center");
1208 requirement_vector_append(&enabler->actor_reqs, e_req);
1209 action_enabler_add(enabler);
1210
1211 enabler = action_enabler_new();
1212 enabler->action = ACTION_ROAD;
1213 e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, FALSE, TRUE, FALSE,
1214 UTYF_SETTLERS);
1215 requirement_vector_append(&enabler->actor_reqs, e_req);
1216 action_enabler_add(enabler);
1217
1218 enabler = action_enabler_new();
1219 enabler->action = ACTION_CONVERT;
1220 action_enabler_add(enabler);
1221
1222 enabler = action_enabler_new();
1223 enabler->action = ACTION_BASE;
1224 e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, FALSE, TRUE, FALSE,
1225 UTYF_SETTLERS);
1226 requirement_vector_append(&enabler->actor_reqs, e_req);
1227 action_enabler_add(enabler);
1228
1229 enabler = action_enabler_new();
1230 enabler->action = ACTION_TRANSPORT_ALIGHT;
1231 action_enabler_add(enabler);
1232
1233 enabler = action_enabler_new();
1234 enabler->action = ACTION_TRANSPORT_BOARD;
1235 action_enabler_add(enabler);
1236
1237 enabler = action_enabler_new();
1238 enabler->action = ACTION_TRANSPORT_EMBARK;
1239 action_enabler_add(enabler);
1240
1241 enabler = action_enabler_new();
1242 enabler->action = ACTION_TRANSPORT_UNLOAD;
1243 action_enabler_add(enabler);
1244
1245 /* Assume the player knows that the unit is able to move */
1246 paction = action_by_number(ACTION_UNIT_MOVE);
1247 paction->quiet = TRUE;
1248
1249 enabler = action_enabler_new();
1250 enabler->action = ACTION_UNIT_MOVE;
1251 e_req = req_from_values(VUT_MINMOVES, REQ_RANGE_LOCAL,
1252 FALSE, TRUE, FALSE, 1);
1253 requirement_vector_append(&enabler->actor_reqs, e_req);
1254 e_req = req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
1255 FALSE, FALSE, FALSE,
1256 USP_TRANSPORTED);
1257 requirement_vector_append(&enabler->actor_reqs, e_req);
1258 action_enabler_add(enabler);
1259
1260 /* Update action enablers. */
1261 rscompat_enablers_add_obligatory_hard_reqs();
1262 action_enablers_iterate(ae) {
1263 /* "Attack" is split in a unit consuming and a non unit consuming
1264 * version. */
1265 if (ae->action == ACTION_ATTACK) {
1266 /* The old rule is represented with two action enablers. */
1267 enabler = action_enabler_copy(ae);
1268
1269 /* One allows regular attacks. */
1270 requirement_vector_append(&ae->actor_reqs,
1271 req_from_str("UnitClassFlag", "Local",
1272 FALSE, FALSE, TRUE,
1273 "Missile"));
1274
1275 /* The other allows suicide attacks. */
1276 enabler->action = ACTION_SUICIDE_ATTACK;
1277 requirement_vector_append(&enabler->actor_reqs,
1278 req_from_str("UnitClassFlag", "Local",
1279 FALSE, TRUE, TRUE,
1280 "Missile"));
1281
1282 /* Add after the action was changed. */
1283 action_enabler_add(enabler);
1284 }
1285
1286 /* "Explode Nuclear"'s adjacent tile attack is split to "Nuke City"
1287 * and "Nuke Units". */
1288 if (ae->action == ACTION_NUKE) {
1289 /* The old rule is represented with three action enablers:
1290 * 1) "Explode Nuclear" against the actors own tile.
1291 * 2) "Nuke City" against adjacent enemy cities.
1292 * 3) "Nuke Units" against adjacent enemy unit stacks. */
1293
1294 struct action_enabler *city;
1295 struct action_enabler *units;
1296
1297 /* Against city targets. */
1298 city = action_enabler_copy(ae);
1299 city->action = ACTION_NUKE_CITY;
1300
1301 /* Against unit stack targets. */
1302 units = action_enabler_copy(ae);
1303 units->action = ACTION_NUKE_UNITS;
1304
1305 /* "Explode Nuclear" required this to target an adjacent tile. */
1306 /* While this isn't a real move (because of enemy city/units) at
1307 * target tile it pretends to be one. */
1308 requirement_vector_append(&city->actor_reqs,
1309 req_from_values(VUT_MINMOVES,
1310 REQ_RANGE_LOCAL,
1311 FALSE, TRUE, FALSE, 1));
1312 requirement_vector_append(&units->actor_reqs,
1313 req_from_values(VUT_MINMOVES,
1314 REQ_RANGE_LOCAL,
1315 FALSE, TRUE, FALSE, 1));
1316
1317 /* Be slightly stricter about the relationship to target unit stacks
1318 * than "Explode Nuclear" was before it would target an adjacent
1319 * tile. I think the intention was that you shouldn't nuke your
1320 * friends and allies. */
1321 requirement_vector_append(&city->actor_reqs,
1322 req_from_values(VUT_DIPLREL,
1323 REQ_RANGE_LOCAL,
1324 FALSE, TRUE, FALSE,
1325 DS_WAR));
1326 requirement_vector_append(&units->actor_reqs,
1327 req_from_values(VUT_DIPLREL,
1328 REQ_RANGE_LOCAL,
1329 FALSE, TRUE, FALSE,
1330 DS_WAR));
1331
1332 /* Only display one nuke action at once. */
1333 requirement_vector_append(&units->target_reqs,
1334 req_from_values(VUT_CITYTILE,
1335 REQ_RANGE_LOCAL,
1336 FALSE, FALSE, FALSE,
1337 CITYT_CENTER));
1338
1339 /* Add after the action was changed. */
1340 action_enabler_add(city);
1341 action_enabler_add(units);
1342 }
1343
1344 /* "Targeted Sabotage City" is split in a production targeted and a
1345 * building targeted version. */
1346 if (ae->action == ACTION_SPY_TARGETED_SABOTAGE_CITY) {
1347 /* The old rule is represented with two action enablers. */
1348 enabler = action_enabler_copy(ae);
1349
1350 enabler->action = ACTION_SPY_SABOTAGE_CITY_PRODUCTION;
1351
1352 /* Add after the action was changed. */
1353 action_enabler_add(enabler);
1354 }
1355
1356 /* "Targeted Sabotage City Escape" is split in a production targeted
1357 * and a building targeted version. */
1358 if (ae->action == ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC) {
1359 /* The old rule is represented with two action enablers. */
1360 enabler = action_enabler_copy(ae);
1361
1362 enabler->action = ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC;
1363
1364 /* Add after the action was changed. */
1365 action_enabler_add(enabler);
1366 }
1367 } action_enablers_iterate_end;
1368
1369 /* The paratroopers_mr_req field has moved to the enabler for the
1370 * "Paradrop Unit" action. */
1371 {
1372 bool generic_in_use = FALSE;
1373 struct action_enabler_list *ae_custom = action_enabler_list_new();
1374
1375 action_enabler_list_iterate(
1376 action_enablers_for_action(ACTION_PARADROP), ae) {
1377 unit_type_iterate(putype) {
1378 if (!requirement_fulfilled_by_unit_type(putype,
1379 &(ae->actor_reqs))) {
1380 /* This action enabler isn't for this unit type at all. */
1381 continue;
1382 }
1383
1384 requirement_vector_iterate(&ae->actor_reqs, preq) {
1385 if (preq->source.kind == VUT_MINMOVES) {
1386 if (!preq->present) {
1387 /* A max move fragments req has been found. Is it too
1388 * large? */
1389 if (preq->source.value.minmoves
1390 < putype->rscompat_cache.paratroopers_mr_req) {
1391 /* Avoid self contradiciton */
1392 continue;
1393 }
1394 }
1395 }
1396 } requirement_vector_iterate_end;
1397
1398 if (putype->rscompat_cache.paratroopers_mr_req > 0) {
1399 /* This unit type needs a custom enabler */
1400
1401 enabler = action_enabler_copy(ae);
1402
1403 /* This enabler is specific to the unit type */
1404 e_req = req_from_values(VUT_UTYPE,
1405 REQ_RANGE_LOCAL,
1406 FALSE, TRUE, FALSE,
1407 utype_number(putype));
1408 requirement_vector_append(&enabler->actor_reqs, e_req);
1409
1410 /* Add the minimum amout of move fragments */
1411 e_req = req_from_values(VUT_MINMOVES,
1412 REQ_RANGE_LOCAL,
1413 FALSE, TRUE, FALSE,
1414 putype->rscompat_cache
1415 .paratroopers_mr_req);
1416 requirement_vector_append(&enabler->actor_reqs, e_req);
1417
1418 action_enabler_list_append(ae_custom, enabler);
1419
1420 log_debug("paratroopers_mr_req upgrade: %s uses custom enabler",
1421 utype_rule_name(putype));
1422 } else {
1423 /* The old one works just fine */
1424
1425 generic_in_use = TRUE;
1426
1427 log_debug("paratroopers_mr_req upgrade: %s uses generic enabler",
1428 utype_rule_name(putype));
1429 }
1430 } unit_type_iterate_end;
1431
1432 if (!generic_in_use) {
1433 /* The generic enabler isn't in use any more */
1434 action_enabler_remove(ae);
1435 }
1436 } action_enabler_list_iterate_end;
1437
1438 action_enabler_list_iterate(ae_custom, ae) {
1439 /* Append the custom enablers. */
1440 action_enabler_add(ae);
1441 } action_enabler_list_iterate_end;
1442
1443 action_enabler_list_destroy(ae_custom);
1444 }
1445
1446 /* Enable all clause types */
1447 {
1448 int i;
1449
1450 for (i = 0; i < CLAUSE_COUNT; i++) {
1451 struct clause_info *cinfo = clause_info_get(i);
1452
1453 cinfo->enabled = TRUE;
1454 }
1455 }
1456
1457 /* Used to live in unit_move() and new in 3.1 so they should be non
1458 * controversial enough. */
1459 action_iterate(act_id) {
1460 if (action_id_has_result_safe(act_id, ACTRES_TRANSPORT_DISEMBARK)
1461 || action_id_has_result_safe(act_id, ACTRES_CONQUER_EXTRAS)
1462 || action_id_has_result_safe(act_id, ACTRES_HUT_ENTER)
1463 || action_id_has_result_safe(act_id, ACTRES_HUT_FRIGHTEN)) {
1464 BV_SET(action_by_number(ACTION_UNIT_MOVE)->blocked_by, act_id);
1465 }
1466 } action_iterate_end;
1467
1468 {
1469 struct action_auto_perf *auto_perf;
1470 int pos;
1471
1472 /* The forced post successful action move action list has moved to the
1473 * ruleset. */
1474
1475 /* "Bribe Unit" */
1476 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_POST_BRIBE);
1477 auto_perf->alternatives[0] = ACTION_TRANSPORT_EMBARK;
1478 auto_perf->alternatives[1] = ACTION_TRANSPORT_EMBARK2;
1479 auto_perf->alternatives[2] = ACTION_TRANSPORT_EMBARK3;
1480 auto_perf->alternatives[3] = ACTION_TRANSPORT_DISEMBARK1;
1481 auto_perf->alternatives[4] = ACTION_TRANSPORT_DISEMBARK2;
1482 auto_perf->alternatives[5] = ACTION_TRANSPORT_DISEMBARK3;
1483 auto_perf->alternatives[6] = ACTION_TRANSPORT_DISEMBARK4;
1484 auto_perf->alternatives[7] = ACTION_CONQUER_EXTRAS;
1485 auto_perf->alternatives[8] = ACTION_CONQUER_EXTRAS2;
1486 auto_perf->alternatives[9] = ACTION_CONQUER_EXTRAS3;
1487 auto_perf->alternatives[10] = ACTION_CONQUER_EXTRAS4;
1488 auto_perf->alternatives[11] = ACTION_HUT_ENTER;
1489 auto_perf->alternatives[12] = ACTION_HUT_ENTER2;
1490 auto_perf->alternatives[13] = ACTION_HUT_ENTER3;
1491 auto_perf->alternatives[14] = ACTION_HUT_ENTER4;
1492 auto_perf->alternatives[15] = ACTION_HUT_FRIGHTEN;
1493 auto_perf->alternatives[16] = ACTION_HUT_FRIGHTEN2;
1494 auto_perf->alternatives[17] = ACTION_HUT_FRIGHTEN3;
1495 auto_perf->alternatives[18] = ACTION_HUT_FRIGHTEN4;
1496 auto_perf->alternatives[19] = ACTION_UNIT_MOVE;
1497 auto_perf->alternatives[20] = ACTION_UNIT_MOVE2;
1498 auto_perf->alternatives[21] = ACTION_UNIT_MOVE3;
1499 action_list_end(auto_perf->alternatives, 22);
1500
1501 /* "Attack" */
1502 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_POST_ATTACK);
1503 auto_perf->alternatives[0] = ACTION_CONQUER_CITY;
1504 auto_perf->alternatives[1] = ACTION_CONQUER_CITY2;
1505 auto_perf->alternatives[2] = ACTION_CONQUER_CITY3;
1506 auto_perf->alternatives[3] = ACTION_CONQUER_CITY4;
1507 auto_perf->alternatives[4] = ACTION_TRANSPORT_DISEMBARK1;
1508 auto_perf->alternatives[5] = ACTION_TRANSPORT_DISEMBARK2;
1509 auto_perf->alternatives[6] = ACTION_TRANSPORT_DISEMBARK3;
1510 auto_perf->alternatives[7] = ACTION_TRANSPORT_DISEMBARK4;
1511 auto_perf->alternatives[8] = ACTION_CONQUER_EXTRAS;
1512 auto_perf->alternatives[9] = ACTION_CONQUER_EXTRAS2;
1513 auto_perf->alternatives[10] = ACTION_CONQUER_EXTRAS3;
1514 auto_perf->alternatives[11] = ACTION_CONQUER_EXTRAS4;
1515 auto_perf->alternatives[12] = ACTION_HUT_ENTER;
1516 auto_perf->alternatives[13] = ACTION_HUT_ENTER2;
1517 auto_perf->alternatives[14] = ACTION_HUT_ENTER3;
1518 auto_perf->alternatives[15] = ACTION_HUT_ENTER4;
1519 auto_perf->alternatives[16] = ACTION_HUT_FRIGHTEN;
1520 auto_perf->alternatives[17] = ACTION_HUT_FRIGHTEN2;
1521 auto_perf->alternatives[18] = ACTION_HUT_FRIGHTEN3;
1522 auto_perf->alternatives[19] = ACTION_HUT_FRIGHTEN4;
1523 auto_perf->alternatives[20] = ACTION_UNIT_MOVE;
1524 auto_perf->alternatives[21] = ACTION_UNIT_MOVE2;
1525 auto_perf->alternatives[22] = ACTION_UNIT_MOVE3;
1526 action_list_end(auto_perf->alternatives, 23);
1527
1528
1529 /* The city that made the unit's current tile native is gone.
1530 * Evaluated against an adjacent tile. */
1531 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_ESCAPE_CITY);
1532 auto_perf->alternatives[0] = ACTION_TRANSPORT_EMBARK;
1533 auto_perf->alternatives[1] = ACTION_TRANSPORT_EMBARK2;
1534 auto_perf->alternatives[2] = ACTION_TRANSPORT_EMBARK3;
1535 auto_perf->alternatives[3] = ACTION_HUT_ENTER;
1536 auto_perf->alternatives[4] = ACTION_HUT_ENTER2;
1537 auto_perf->alternatives[5] = ACTION_HUT_ENTER3;
1538 auto_perf->alternatives[6] = ACTION_HUT_ENTER4;
1539 auto_perf->alternatives[7] = ACTION_HUT_FRIGHTEN;
1540 auto_perf->alternatives[8] = ACTION_HUT_FRIGHTEN2;
1541 auto_perf->alternatives[9] = ACTION_HUT_FRIGHTEN3;
1542 auto_perf->alternatives[10] = ACTION_HUT_FRIGHTEN4;
1543 auto_perf->alternatives[11] = ACTION_UNIT_MOVE;
1544 auto_perf->alternatives[12] = ACTION_UNIT_MOVE2;
1545 auto_perf->alternatives[13] = ACTION_UNIT_MOVE3;
1546 action_list_end(auto_perf->alternatives, 14);
1547
1548
1549 /* The unit's stack has been defeated and is scheduled for execution
1550 * but the unit has the CanEscape unit type flag.
1551 * Evaluated against an adjacent tile. */
1552 pos = 0;
1553 auto_perf = action_auto_perf_slot_number(ACTION_AUTO_ESCAPE_STACK);
1554 action_list_add_all_by_result(auto_perf->alternatives, &pos,
1555 ACTRES_TRANSPORT_EMBARK);
1556 action_list_add_all_by_result(auto_perf->alternatives, &pos,
1557 ACTRES_CONQUER_EXTRAS);
1558 action_list_add_all_by_result(auto_perf->alternatives, &pos,
1559 ACTRES_HUT_ENTER);
1560 action_list_add_all_by_result(auto_perf->alternatives, &pos,
1561 ACTRES_HUT_FRIGHTEN);
1562 action_list_add_all_by_result(auto_perf->alternatives, &pos,
1563 ACTRES_UNIT_MOVE);
1564 action_list_end(auto_perf->alternatives, pos);
1565 }
1566
1567 /* diplchance setting control over initial dice roll odds has moved to
1568 * the ruleset. */
1569 action_iterate(act_id) {
1570 struct action *act = action_by_number(act_id);
1571
1572 if (action_has_result_safe(act, ACTRES_SPY_SPREAD_PLAGUE)
1573 || action_has_result_safe(act, ACTRES_SPY_STEAL_TECH)
1574 || action_has_result_safe(act, ACTRES_SPY_TARGETED_STEAL_TECH)
1575 || action_has_result_safe(act, ACTRES_SPY_INCITE_CITY)
1576 || action_has_result_safe(act, ACTRES_SPY_SABOTAGE_CITY)
1577 || action_has_result_safe(act, ACTRES_SPY_TARGETED_SABOTAGE_CITY)
1578 || action_has_result_safe(act,
1579 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION)
1580 || action_has_result_safe(act, ACTRES_SPY_STEAL_GOLD)
1581 || action_has_result_safe(act, ACTRES_STEAL_MAPS)
1582 || action_has_result_safe(act, ACTRES_SPY_NUKE)) {
1583 BV_SET(game.info.diplchance_initial_odds, act->id);
1584 }
1585 } action_iterate_end;
1586
1587
1588 /* "Paradrop Unit" has been split by side effects. */
1589 split_action_name_update(action_by_number(ACTION_PARADROP),
1590 action_by_number(ACTION_PARADROP_CONQUER),
1591 "Contested %s");
1592 split_action_name_update(action_by_number(ACTION_PARADROP),
1593 action_by_number(ACTION_PARADROP_ENTER),
1594 "Enter Hut %s");
1595 split_action_name_update(action_by_number(ACTION_PARADROP),
1596 action_by_number(
1597 ACTION_PARADROP_ENTER_CONQUER),
1598 "Enter Hut Contested %s");
1599 split_action_name_update(action_by_number(ACTION_PARADROP),
1600 action_by_number(ACTION_PARADROP_FRIGHTEN),
1601 "Frighten Hut %s");
1602 split_action_name_update(action_by_number(ACTION_PARADROP),
1603 action_by_number(
1604 ACTION_PARADROP_FRIGHTEN_CONQUER),
1605 "Frighten Hut Contested %s");
1606
1607 action_enabler_list_iterate(
1608 action_enablers_for_action(ACTION_PARADROP), ae) {
1609 struct action_enabler *edit;
1610
1611 action_by_result_iterate(para_action, ACTRES_PARADROP_CONQUER) {
1612 /* Conquer City and/or owned Extra during war if one is there */
1613 edit = action_enabler_copy(ae);
1614 edit->action = para_action->id;
1615 e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
1616 FALSE, TRUE, TRUE, DS_WAR);
1617 requirement_vector_append(&edit->actor_reqs, e_req);
1618 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1619 FALSE, TRUE, TRUE, CITYT_CLAIMED);
1620 if (!is_req_in_vec(&e_req, &ae->target_reqs)) {
1621 requirement_vector_append(&edit->target_reqs, e_req);
1622 }
1623 e_req = req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
1624 FALSE, TRUE, TRUE,
1625 UCF_CAN_OCCUPY_CITY);
1626 requirement_vector_append(&edit->actor_reqs, e_req);
1627 e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
1628 FALSE, FALSE, TRUE,
1629 UTYF_CIVILIAN);
1630 requirement_vector_append(&edit->actor_reqs, e_req);
1631 action_enabler_add(edit);
1632
1633 /* Conquer owned Extra during war if there */
1634 edit = action_enabler_copy(ae);
1635 edit->action = para_action->id;
1636 e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
1637 FALSE, TRUE, TRUE, DS_WAR);
1638 requirement_vector_append(&edit->actor_reqs, e_req);
1639 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1640 FALSE, TRUE, TRUE, CITYT_CLAIMED);
1641 if (!is_req_in_vec(&e_req, &ae->target_reqs)) {
1642 requirement_vector_append(&edit->target_reqs, e_req);
1643 }
1644 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1645 FALSE, FALSE, TRUE, CITYT_CENTER);
1646 requirement_vector_append(&edit->target_reqs, e_req);
1647 action_enabler_add(edit);
1648
1649 /* Unowned Extra conquest */
1650 extra_type_by_cause_iterate(EC_BASE, pextra) {
1651 if (!territory_claiming_base(extra_base_get(pextra))) {
1652 /* Only territory claiming bases can be conquered in 3.0 */
1653 continue;
1654 }
1655
1656 edit = action_enabler_copy(ae);
1657 edit->action = para_action->id;
1658 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1659 FALSE, FALSE, TRUE, CITYT_CLAIMED);
1660 if (!is_req_in_vec(&e_req, &ae->target_reqs)) {
1661 requirement_vector_append(&edit->target_reqs, e_req);
1662 }
1663 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1664 FALSE, FALSE, TRUE, CITYT_CENTER);
1665 requirement_vector_append(&edit->target_reqs, e_req);
1666 e_req = req_from_values(VUT_EXTRA, REQ_RANGE_LOCAL,
1667 FALSE, TRUE, TRUE, pextra->id);
1668 requirement_vector_append(&edit->target_reqs, e_req);
1669 action_enabler_add(edit);
1670 } extra_type_by_cause_iterate_end;
1671 } action_by_result_iterate_end;
1672
1673 action_by_result_iterate(para_action, ACTRES_PARADROP) {
1674 if (para_action->id == ACTION_PARADROP) {
1675 /* Use when not at war and against unclaimed tiles. */
1676 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1677 FALSE, FALSE, TRUE, CITYT_CLAIMED);
1678 if (is_req_in_vec(&e_req, &ae->target_reqs)) {
1679 /* Use Conquer version for unowned Extras */
1680 extra_type_by_cause_iterate(EC_BASE, pextra) {
1681 if (!territory_claiming_base(extra_base_get(pextra))) {
1682 /* Only territory claiming bases can be conquered in 3.0 */
1683 continue;
1684 }
1685
1686 e_req = req_from_values(VUT_EXTRA, REQ_RANGE_LOCAL,
1687 FALSE, FALSE, TRUE, pextra->id);
1688 requirement_vector_append(&ae->target_reqs, e_req);
1689 } extra_type_by_cause_iterate_end;
1690 } else {
1691 /* Use Conquer version during war. */
1692 e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
1693 FALSE, FALSE, TRUE, DS_WAR);
1694 requirement_vector_append(&ae->actor_reqs, e_req);
1695 }
1696 } else {
1697 /* !War req requirement added before the copy. */
1698 edit = action_enabler_copy(ae);
1699 edit->action = para_action->id;
1700 action_enabler_add(edit);
1701 }
1702 } action_by_result_iterate_end;
1703 } action_enabler_list_iterate_end;
1704
1705 /* The non hut popping version is only legal when hut_behavior is
1706 * "Nothing". */
1707 action_enablers_iterate(ae) {
1708 if (ae->action != ACTION_PARADROP
1709 && ae->action != ACTION_PARADROP_CONQUER) {
1710 /* Not relevant. */
1711 continue;
1712 }
1713
1714 e_req = req_from_str("UnitClassFlag", "local",
1715 FALSE, TRUE, FALSE, "HutNothing");
1716 requirement_vector_append(&ae->actor_reqs, e_req);
1717 } action_enablers_iterate_end;
1718 }
1719
1720 if (info->version < RSFORMAT_3_1) {
1721 enum unit_class_flag_id nothing
1722 = unit_class_flag_id_by_name("HutNothing", fc_strcasecmp);
1723
1724 unit_class_iterate(uc) {
1725 if (uc->rscompat_cache_from_3_0.hut_behavior == HUT_NOTHING) {
1726 BV_SET(uc->flags, nothing);
1727 } else if (uc->rscompat_cache_from_3_0.hut_behavior == HUT_FRIGHTEN) {
1728 BV_SET(uc->flags, UCF_HUT_FRIGHTEN);
1729 }
1730 } unit_class_iterate_end;
1731 }
1732
1733 /* Make sure that all action enablers added or modified by the
1734 * compatibility post processing fulfills all hard action requirements. */
1735 rscompat_enablers_add_obligatory_hard_reqs();
1736
1737 /* The ruleset may need adjustments it didn't need before compatibility
1738 * post processing.
1739 *
1740 * If this isn't done a user of ruleset compatibility that ends up using
1741 * the rules risks bad rules. A user that saves the ruleset rather than
1742 * using it risks an unexpected change on the next load and save. */
1743 autoadjust_ruleset_data();
1744}
1745
1746/**********************************************************************/
1749 bool rscompat_auto_attack_3_1(struct rscompat_info *compat,
1750 struct action_auto_perf *auto_perf,
1751 size_t psize,
1752 enum unit_type_flag_id *protecor_flag)
1753{
1754 int i;
1755
1756 if (compat->version < RSFORMAT_3_1) {
1757 /* Auto attack happens during war. */
1758 requirement_vector_append(&auto_perf->reqs,
1759 req_from_values(VUT_DIPLREL,
1760 REQ_RANGE_LOCAL,
1761 FALSE, TRUE, TRUE, DS_WAR));
1762
1763 /* Needs a movement point to auto attack. */
1764 requirement_vector_append(&auto_perf->reqs,
1765 req_from_values(VUT_MINMOVES,
1766 REQ_RANGE_LOCAL,
1767 FALSE, TRUE, TRUE, 1));
1768
1769 for (i = 0; i < psize; i++) {
1770 /* Add each protecor_flag as a !present requirement. */
1771 requirement_vector_append(&auto_perf->reqs,
1772 req_from_values(VUT_UTFLAG,
1773 REQ_RANGE_LOCAL,
1774 FALSE, FALSE, TRUE,
1775 protecor_flag[i]));
1776 }
1777
1778 auto_perf->alternatives[0] = ACTION_CAPTURE_UNITS;
1779 auto_perf->alternatives[1] = ACTION_BOMBARD;
1780 auto_perf->alternatives[2] = ACTION_ATTACK;
1781 auto_perf->alternatives[3] = ACTION_SUICIDE_ATTACK;
1782 }
1783
1784 return TRUE;
1785}
1786
1787/**********************************************************************/
1790 static bool slow_invasion_enablers(action_id action_orig,
1791 action_id action_copy)
1792{
1793 struct action_enabler_list *to_upgrade;
1794
1795 struct action_enabler *enabler;
1796 struct requirement e_req;
1797
1798 /* Upgrade exisiting action enablers */
1799 to_upgrade = action_enabler_list_copy(
1800 action_enablers_for_action(action_orig));
1801
1802 action_enabler_list_iterate(to_upgrade, ae) {
1803 /* City center counts as native. */
1804 enabler = action_enabler_copy(ae);
1805 e_req = req_from_values(VUT_CITYTILE,
1806 REQ_RANGE_LOCAL,
1807 FALSE, TRUE, TRUE,
1808 CITYT_CENTER);
1809 requirement_vector_append(&enabler->actor_reqs, e_req);
1810 action_enabler_add(enabler);
1811 } action_enabler_list_iterate_end;
1812
1813 action_enabler_list_iterate(to_upgrade, ae) {
1814 /* No TerrainSpeed sees everything as native. */
1815 enabler = action_enabler_copy(ae);
1816 e_req = req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
1817 FALSE, FALSE, TRUE,
1818 UCF_TERRAIN_SPEED);
1819 requirement_vector_append(&enabler->actor_reqs, e_req);
1820 action_enabler_add(enabler);
1821 } action_enabler_list_iterate_end;
1822
1823 action_enabler_list_iterate(to_upgrade, ae) {
1824 /* "BeachLander" sees everything as native. */
1825 enabler = action_enabler_copy(ae);
1826 e_req = req_from_str("UnitFlag", "Local",
1827 FALSE, TRUE, TRUE,
1828 "BeachLander");
1829 requirement_vector_append(&enabler->actor_reqs, e_req);
1830 action_enabler_add(enabler);
1831 } action_enabler_list_iterate_end;
1832
1833 action_enabler_list_iterate(to_upgrade, ae) {
1834 /* Use the action_copy for acting from non native. */
1835 enabler = action_enabler_copy(ae);
1836 enabler->action = action_copy;
1837
1838 /* Native terrain is native. */
1839 e_req = req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
1840 FALSE, FALSE, TRUE, USP_NATIVE_TILE);
1841 requirement_vector_append(&enabler->actor_reqs, e_req);
1842
1843 /* City is native. */
1844 e_req = req_from_values(VUT_CITYTILE,
1845 REQ_RANGE_LOCAL,
1846 FALSE, FALSE, TRUE,
1847 CITYT_CENTER);
1848 requirement_vector_append(&enabler->actor_reqs, e_req);
1849
1850 /* No TerrainSpeed sees everything as native. */
1851 e_req = req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
1852 FALSE, TRUE, TRUE,
1853 UCF_TERRAIN_SPEED);
1854 requirement_vector_append(&enabler->actor_reqs, e_req);
1855
1856 /* "BeachLander" sees everything as native. */
1857 e_req = req_from_str("UnitFlag", "Local",
1858 FALSE, FALSE, TRUE,
1859 "BeachLander");
1860 requirement_vector_append(&enabler->actor_reqs, e_req);
1861
1862 action_enabler_add(enabler);
1863 } action_enabler_list_iterate_end;
1864
1865 action_enabler_list_iterate(to_upgrade, ae) {
1866 /* Use for acting from native terrain so acting from
1867 * non native terain is handled by action_copy. */
1868 e_req = req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
1869 FALSE, TRUE, TRUE, USP_NATIVE_TILE);
1870 requirement_vector_append(&ae->actor_reqs, e_req);
1871 } action_enabler_list_iterate_end;
1872
1873 action_enabler_list_destroy(to_upgrade);
1874
1875 return TRUE;
1876}
1877
1878/**********************************************************************/
1881 static bool slow_invasion_effects(const char *action_rule_name)
1882{
1883 struct effect *peffect;
1884
1885 /* Take movement for action from non native terrain */
1886 peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST,
1887 MAX_MOVE_FRAGS, NULL);
1888 /* The reduction only applies to this action. */
1889 effect_req_append(peffect, req_from_str("Action", "Local",
1890 FALSE, TRUE, TRUE,
1891 action_rule_name));
1892 /* No reduction here unless disembarking to native terrain. */
1893 effect_req_append(peffect, req_from_values(VUT_UNITSTATE,
1894 REQ_RANGE_LOCAL,
1895 FALSE, TRUE, TRUE,
1896 USP_NATIVE_TILE));
1897 /* Doesn't apply to non TerrainSpeed. */
1898 effect_req_append(peffect, req_from_str("UnitClassFlag", "Local",
1899 FALSE, TRUE, FALSE,
1900 "TerrainSpeed"));
1901
1902 return TRUE;
1903}
1904
1905/**********************************************************************/
1908 bool rscompat_old_slow_invasions_3_1(struct rscompat_info *compat,
1909 bool slow_invasions)
1910{
1911 if (compat->version < RSFORMAT_3_1 && compat->version < RSFORMAT_3_1) {
1912 /* BeachLander and slow_invasions has moved to the ruleset. Use a "fake
1913 * generalized" Transport Disembark, Conquer City, Enter Hut and
1914 * Frighten Hut to handle it. */
1915
1916 struct action_enabler *enabler;
1917 struct requirement e_req;
1918
1919 enabler = action_enabler_new();
1920 enabler->action = ACTION_TRANSPORT_DISEMBARK1;
1921 action_enabler_add(enabler);
1922
1923 enabler = action_enabler_new();
1924 enabler->action = ACTION_CONQUER_EXTRAS;
1925 e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
1926 FALSE, TRUE, TRUE, DS_WAR);
1927 requirement_vector_append(&enabler->actor_reqs, e_req);
1928 action_enabler_add(enabler);
1929
1930 enabler = action_enabler_new();
1931 enabler->action = ACTION_CONQUER_EXTRAS;
1932 e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
1933 FALSE, FALSE, TRUE,
1934 CITYT_EXTRAS_OWNED);
1935 requirement_vector_append(&enabler->target_reqs, e_req);
1936 action_enabler_add(enabler);
1937
1938 /* Hut entry and frightening is enabler controlled in 3.1. They can
1939 * involve disembarking. */
1940 enabler = action_enabler_new();
1941 enabler->action = ACTION_HUT_ENTER;
1942 e_req = req_from_str("UnitClassFlag", "Local", FALSE, FALSE, FALSE,
1943 "HutNothing");
1944 requirement_vector_append(&enabler->actor_reqs, e_req);
1945 action_enabler_add(enabler);
1946
1947 enabler = action_enabler_new();
1948 enabler->action = ACTION_HUT_FRIGHTEN;
1949 e_req = req_from_str("UnitClassFlag", "Local", FALSE, FALSE, FALSE,
1950 "HutNothing");
1951 requirement_vector_append(&enabler->actor_reqs, e_req);
1952 action_enabler_add(enabler);
1953
1954 if (slow_invasions) {
1955 /* Make disembarking from non native terrain a different action. */
1956
1957 struct action *paction;
1958
1959 /* Add the enablers */
1960 /* The city conquest enablers are really from 3.0 */
1961 slow_invasion_enablers(ACTION_CONQUER_CITY, ACTION_CONQUER_CITY2);
1962
1963 /* Enablers for entering and frightening huts and for disembarking
1964 * were added in a slow invasion neutral way.
1965 * Make them slow invasion friendly. */
1966 slow_invasion_enablers(ACTION_TRANSPORT_DISEMBARK1,
1967 ACTION_TRANSPORT_DISEMBARK2);
1968 slow_invasion_enablers(ACTION_CONQUER_EXTRAS, ACTION_CONQUER_EXTRAS2);
1969 slow_invasion_enablers(ACTION_HUT_ENTER, ACTION_HUT_ENTER2);
1970 slow_invasion_enablers(ACTION_HUT_FRIGHTEN, ACTION_HUT_FRIGHTEN2);
1971
1972 /* Add the actions */
1973
1974 /* Use "Transport Disembark 2" for disembarking from non native. */
1975 paction = action_by_number(ACTION_TRANSPORT_DISEMBARK2);
1976 /* "Transport Disembark" and "Transport Disembark 2" won't appear in
1977 * the same action selection dialog given their opposite
1978 * requirements. */
1979 paction->quiet = TRUE;
1980 /* Make what is happening clear. */
1981 /* TRANS: _Disembark from non native (100% chance of success). */
1982 sz_strlcpy(paction->ui_name, N_("%sDisembark from non native%s"));
1983
1984
1985 /* Use "Conquer City 2" for conquring from non native. */
1986 paction = action_by_number(ACTION_CONQUER_CITY2);
1987 /* "Conquer City" and "Conquer City 2" won't appear in
1988 * the same action selection dialog given their opposite
1989 * requirements. */
1990 paction->quiet = TRUE;
1991 /* Make what is happening clear. */
1992 /* TRANS: _Conquer City from non native (100% chance of success). */
1993 sz_strlcpy(paction->ui_name, N_("%sConquer City from non native%s"));
1994
1995
1996 /* Use "Conquer Extras 2" for conquring from non native. */
1997 paction = action_by_number(ACTION_CONQUER_EXTRAS2);
1998 /* "Conquer Extras" and "Conquer Extras 2" won't appear in
1999 * the same action selection dialog given their opposite
2000 * requirements. */
2001 paction->quiet = TRUE;
2002 /* Make what is happening clear. */
2003 /* TRANS: _Enter Hut from non native (100% chance of success). */
2004 sz_strlcpy(paction->ui_name, N_("%sConquer Extras from non native%s"));
2005
2006
2007 /* Use "Enter Hut 2" for conquring from non native. */
2008 paction = action_by_number(ACTION_HUT_ENTER2);
2009 /* "Enter Hut" and "Enter Hut 2" won't appear in
2010 * the same action selection dialog given their opposite
2011 * requirements. */
2012 paction->quiet = TRUE;
2013 /* Make what is happening clear. */
2014 /* TRANS: _Enter Hut from non native (100% chance of success). */
2015 sz_strlcpy(paction->ui_name, N_("%sEnter Hut from non native%s"));
2016
2017 /* Use "Frighten Hut 2" for conquring from non native. */
2018 paction = action_by_number(ACTION_HUT_FRIGHTEN2);
2019 /* "Frighten Hut" and "Frighten Hut 2" won't appear in
2020 * the same action selection dialog given their opposite
2021 * requirements. */
2022 paction->quiet = TRUE;
2023 /* Make what is happening clear. */
2024 /* TRANS: _Frighten Hut from non native (100% chance of success). */
2025 sz_strlcpy(paction->ui_name, N_("%sFrighten Hut from non native%s"));
2026
2027 /* Take movement for disembarking, conquering and hut popping to
2028 * native terrain from non native terrain */
2029 slow_invasion_effects("Transport Disembark 2");
2030 slow_invasion_effects("Conquer City 2");
2031 slow_invasion_effects("Conquer Extras 2");
2032 slow_invasion_effects("Enter Hut 2");
2033 slow_invasion_effects("Frighten Hut 2");
2034 }
2035 }
2036
2037 return TRUE;
2038}
2039
2040/**********************************************************************/
2043 const char *rscompat_req_type_name_3_1(const char *old_type)
2044{
2045 if (!fc_strcasecmp("BaseFlag", old_type)) {
2046 /* Remaining BaseFlag has been turned to an extra flag */
2047 return "ExtraFlag";
2048 }
2049
2050 return old_type;
2051}
2052
2053/**********************************************************************/
2059 const char *rscompat_req_name_3_1(const char *type,
2060 const char *old_name)
2061{
2062 if (!fc_strcasecmp("DiplRel", type)
2063 && !fc_strcasecmp("Is foreign", old_name)) {
2064 return "Foreign";
2065 }
2066
2067 if (!fc_strcasecmp("AI", type)
2068 && !fc_strcasecmp("Handicapped", old_name)) {
2069 return "Restricted";
2070 }
2071
2072 return old_name;
2073}
2074
2075/**********************************************************************/
2079 void rscompat_req_vec_adjust_3_1(struct rscompat_info *compat,
2080 struct requirement_vector *preqs,
2081 int *reqs_count,
2082 const char *filename, const char *sec,
2083 const char *sub, const char *rfor)
2084{
2085 char buf[1024];
2086
2087 /* Add a missing 'alltemperate' server setting requirement to any vector
2088 * including a 'singlepole' requirement.
2089 * See also sanity_check_req_vec_singlepole() in rssanity.c
2090 *
2091 * Note that this *does* change the semantics of the given vector, so we
2092 * must inform the user of this change. */
2093 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2094 /* heuristic: the only non-conjunctive requirement vectors are
2095 * improvement obsoletion requirements */
2096 bool conjunctive = BOOL_VAL(fc_strcasecmp(sub, "obsolete_by"));
2097 bool need_alltemperate_req = FALSE;
2098 /* "wrong" here only applies when we do in fact have a
2099 * 'singlepole' requirement */
2100 bool has_wrong_alltemperate_req = FALSE;
2101
2102 requirement_vector_iterate(preqs, preq) {
2103 server_setting_id id;
2104 struct setting *pset;
2105
2106 if (preq->source.kind != VUT_SERVERSETTING) {
2107 continue;
2108 }
2109
2110 id = ssetv_setting_get(preq->source.value.ssetval);
2111 fc_assert_ret(server_setting_exists(id));
2112 pset = setting_by_number(id);
2113
2114 if (pset == setting_by_name("singlepole")) {
2115 need_alltemperate_req = TRUE;
2116 } else if (pset == setting_by_name("alltemperate")) {
2117 if (XOR(conjunctive, preq->present)) {
2118 need_alltemperate_req = FALSE;
2119 break;
2120 } else {
2121 has_wrong_alltemperate_req = TRUE;
2122 }
2123 }
2124 } requirement_vector_iterate_end;
2125
2126 if (need_alltemperate_req) {
2127 if (has_wrong_alltemperate_req) {
2128 /* Can't do anything here - already a nonsensical situation */
2129 if (compat->log_cb != NULL) {
2130 fc_snprintf(buf, sizeof(buf),
2131 "%s: Cannot update requirement vector %s.%s (for %s)"
2132 " where a 'singlepole' requirement is only relevant"
2133 " when 'alltemperate' is already active. Fix this"
2134 " manually: drop the 'singlepole' requirement, or"
2135 " flip the 'alltemperate' requirement.",
2136 filename, sec, sub, rfor);
2137 compat->log_cb(buf);
2138 }
2139 } else {
2140 struct requirement new_req = req_from_values(VUT_SERVERSETTING,
2141 REQ_RANGE_WORLD, FALSE, !conjunctive, FALSE,
2142 ssetv_by_rule_name("alltemperate"));
2143
2144 requirement_vector_append(preqs, new_req);
2145 (*reqs_count)++;
2146
2147 if (compat->log_cb != NULL) {
2148 fc_snprintf(buf, sizeof(buf),
2149 "%s: Added 'alltemperate' server setting requirement to"
2150 " requirement vector %s.%s (for %s) so that current"
2151 " 'singlepole' requirement is only relevant when"
2152 " 'alltemperate' is disabled. This likely changes the"
2153 " semantics; make sure the new rules are sensible.",
2154 filename, sec, sub, rfor);
2155 compat->log_cb(buf);
2156 }
2157 }
2158 }
2159 }
2160}
2161
2162/**********************************************************************/
2165 const char *rscompat_utype_flag_name_3_1(struct rscompat_info *compat,
2166 const char *old_type)
2167{
2168 if (compat->compat_mode) {
2169 }
2170
2171 return old_type;
2172}
2173
2174/**********************************************************************/
2177 const char *rscompat_combat_bonus_name_3_1(struct rscompat_info *compat,
2178 const char *old_type)
2179{
2180 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2181 if (!fc_strcasecmp("Firepower1", old_type)) {
2182 return combat_bonus_type_name(CBONUS_LOW_FIREPOWER);
2183 }
2184 }
2185
2186 return old_type;
2187}
2188
2189/**********************************************************************/
2192 void rscompat_uclass_flags_3_1(struct rscompat_info *compat,
2193 struct unit_class *pclass)
2194{
2195 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2196 /* Old hardcoded behavior was like all units having NonNatBombardTgt */
2197 BV_SET(pclass->flags, UCF_NONNAT_BOMBARD_TGT);
2198 }
2199}
2200
2201/**********************************************************************/
2204 void rscompat_extra_adjust_3_1(struct rscompat_info *compat,
2205 struct extra_type *pextra)
2206{
2207 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2208
2209 /* Give remove cause ERM_ENTER for huts */
2210 if (is_extra_caused_by(pextra, EC_HUT)) {
2211 pextra->rmcauses |= (1 << ERM_ENTER);
2212 extra_to_removed_by_list(pextra, ERM_ENTER);
2213 }
2214 }
2215}
2216
2217/**********************************************************************/
2220 enum road_gui_type rscompat_road_gui_type_3_1(struct road_type *proad)
2221{
2222 switch (proad->compat) {
2223 case ROCO_ROAD:
2224 return ROAD_GUI_ROAD;
2225 case ROCO_RAILROAD:
2226 return ROAD_GUI_RAILROAD;
2227 case ROCO_RIVER:
2228 case ROCO_NONE:
2229 break;
2230 }
2231
2232 return ROAD_GUI_OTHER;
2233}
2234
2235/**********************************************************************/
2238 const char *rscompat_action_ui_name_S3_1(struct rscompat_info *compat,
2239 int act_id)
2240{
2241 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2242 if (act_id == ACTION_DISBAND_UNIT_RECOVER) {
2243 return "ui_name_recycle_unit";
2244 }
2245 }
2246
2247 return NULL;
2248}
2249
2250/**********************************************************************/
2253 const char *rscompat_action_max_range_name_S3_1(struct rscompat_info *compat,
2254 int act_id)
2255{
2256 if (compat->compat_mode && compat->version < RSFORMAT_3_1) {
2257 if (act_id == ACTION_DISBAND_UNIT_RECOVER) {
2258 return "recycle_unit_max_range";
2259 }
2260 }
2261
2262 return NULL;
2263}
action_auto_perf_slot_number
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:7355
action_enabler_suggest_repair
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2838
action_list_end
void action_list_end(action_id *act_list, int size)
Definition actions.c:7403
action_enabler_vector_by_number_name
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:3015
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
action_list_add_all_by_result
void action_list_add_all_by_result(action_id *act_list, int *position, enum action_result result)
Definition actions.c:7420
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2442
action_enabler_new
struct action_enabler * action_enabler_new(void)
Definition actions.c:2396
action_enabler_remove
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:2459
action_enabler_copy
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2427
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
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:2991
actions.h
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:488
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:526
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
ACTION_AUTO_ESCAPE_STACK
#define ACTION_AUTO_ESCAPE_STACK
Definition actions.h:621
ACTION_AUTO_ESCAPE_CITY
#define ACTION_AUTO_ESCAPE_CITY
Definition actions.h:620
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:457
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:492
ACTION_AUTO_POST_BRIBE
#define ACTION_AUTO_POST_BRIBE
Definition actions.h:618
action_iterate_end
#define action_iterate_end
Definition actions.h:472
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
action_has_result_safe
#define action_has_result_safe(paction, result)
Definition actions.h:666
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
action_iterate
#define action_iterate(_act_)
Definition actions.h:467
ACTION_AUTO_POST_ATTACK
#define ACTION_AUTO_POST_ATTACK
Definition actions.h:619
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:668
territory_claiming_base
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
has_capabilities
bool has_capabilities(const char *us, const char *them)
Definition capability.c:86
capability.h
clause_info_get
struct clause_info * clause_info_get(enum clause_type type)
Definition diptreaty.c:273
id
int int id
Definition editgui_g.h:28
reqs
struct @21::@22 reqs
iterate_effect_cache
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1245
effect_copy
struct effect * effect_copy(struct effect *old)
Definition effects.c:214
effect_new
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:179
effect_req_append
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:229
effects.h
extra_to_removed_by_list
void extra_to_removed_by_list(struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:316
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:196
extra_base_get
#define extra_base_get(_e_)
Definition extras.h:184
extra_type_by_cause_iterate_end
#define extra_type_by_cause_iterate_end
Definition extras.h:315
extra_type_by_cause_iterate
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:309
ROCO_RAILROAD
@ ROCO_RAILROAD
Definition fc_types.h:1105
ROCO_NONE
@ ROCO_NONE
Definition fc_types.h:1105
ROCO_RIVER
@ ROCO_RIVER
Definition fc_types.h:1105
ROCO_ROAD
@ ROCO_ROAD
Definition fc_types.h:1105
server_setting_id
int server_setting_id
Definition fc_types.h:924
action_id
int action_id
Definition fc_types.h:359
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
_
#define _(String)
Definition fcintl.h:67
N_
#define N_(String)
Definition fcintl.h:69
game
struct civ_game game
Definition game.c:57
game.h
RS_DEFAULT_ACTION_MAX_RANGE
#define RS_DEFAULT_ACTION_MAX_RANGE
Definition game.h:863
pos
static struct tile * pos
Definition finddlg.c:53
type
GType type
Definition repodlgs.c:1312
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:341
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:211
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:205
name
const char * name
Definition inputfile.c:127
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_warn
#define log_warn(message,...)
Definition log.h:105
fc_assert
#define fc_assert(condition)
Definition log.h:176
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_debug
#define log_debug(message,...)
Definition log.h:115
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
SINGLE_MOVE
#define SINGLE_MOVE
Definition movement.h:24
MAX_MOVE_FRAGS
#define MAX_MOVE_FRAGS
Definition movement.h:27
nation_rule_name
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:137
nation_barbarian_type
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:210
nations_iterate_end
#define nations_iterate_end
Definition nation.h:335
nations_iterate
#define nations_iterate(NAME_pnation)
Definition nation.h:332
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:1912
secfile_lookup_str
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:2112
secfile_lookup_int_default
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Definition registry_ini.c:1937
is_req_in_vec
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:4649
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:4897
req_vec_change_translation
const char * req_vec_change_translation(const struct req_vec_change *change, const requirement_vector_namer namer)
Definition requirements.c:4824
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:938
req_from_values
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Definition requirements.c:1249
universal_replace_in_req_vec
bool universal_replace_in_req_vec(struct requirement_vector *reqs, const struct universal *to_replace, const struct universal *replacement)
Definition requirements.c:5838
req_vec_problem_free
void req_vec_problem_free(struct req_vec_problem *issue)
Definition requirements.c:4994
universal_by_number
struct universal universal_by_number(const enum universals_n kind, const int value)
Definition requirements.c:567
universal_is_mentioned_by_requirements
bool universal_is_mentioned_by_requirements(const struct requirement_vector *reqs, const struct universal *psource)
Definition requirements.c:5858
requirements.h
requirement_fulfilled_by_unit_type
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition requirements.h:418
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
rscompat_action_ui_name_S3_1
const char * rscompat_action_ui_name_S3_1(struct rscompat_info *compat, int act_id)
Definition rscompat.c:2238
UTYF_LAST_USER_FLAG_3_0
#define UTYF_LAST_USER_FLAG_3_0
Definition rscompat.c:49
first_free_unit_class_user_flag
static int first_free_unit_class_user_flag(void)
Definition rscompat.c:342
slow_invasion_enablers
static bool slow_invasion_enablers(action_id action_orig, action_id action_copy)
Definition rscompat.c:1790
TER_LAST_USER_FLAG_3_0
#define TER_LAST_USER_FLAG_3_0
Definition rscompat.c:51
ete_is_target_req
static bool ete_is_target_req(struct requirement *preq)
Definition rscompat.c:670
rscompat_adjust_pre_sanity
void rscompat_adjust_pre_sanity(struct rscompat_info *info)
Definition rscompat.c:839
rscompat_road_gui_type_3_1
enum road_gui_type rscompat_road_gui_type_3_1(struct road_type *proad)
Definition rscompat.c:2220
rscompat_extra_adjust_3_1
void rscompat_extra_adjust_3_1(struct rscompat_info *compat, struct extra_type *pextra)
Definition rscompat.c:2204
rscompat_enabler_add_obligatory_hard_reqs
static bool rscompat_enabler_add_obligatory_hard_reqs(struct action_enabler *ae)
Definition rscompat.c:165
rscompat_uclass_flags_3_1
void rscompat_uclass_flags_3_1(struct rscompat_info *compat, struct unit_class *pclass)
Definition rscompat.c:2192
rscompat_req_name_3_1
const char * rscompat_req_name_3_1(const char *type, const char *old_name)
Definition rscompat.c:2059
rscompat_auto_attack_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)
Definition rscompat.c:1749
rscompat_old_effect_3_1
bool rscompat_old_effect_3_1(const char *type, struct section_file *file, const char *sec_name, struct rscompat_info *compat)
Definition rscompat.c:806
split_action_name_update
static void split_action_name_update(struct action *original, struct action *copy, const char *name_modification)
Definition rscompat.c:531
rscompat_names
bool rscompat_names(struct rscompat_info *info)
Definition rscompat.c:386
rscompat_utype_flag_name_3_1
const char * rscompat_utype_flag_name_3_1(struct rscompat_info *compat, const char *old_type)
Definition rscompat.c:2165
rscompat_req_vec_adjust_3_1
void rscompat_req_vec_adjust_3_1(struct rscompat_info *compat, struct requirement_vector *preqs, int *reqs_count, const char *filename, const char *sec, const char *sub, const char *rfor)
Definition rscompat.c:2079
paratroopers_mr_sub_to_effect
static void paratroopers_mr_sub_to_effect(struct unit_type *putype, struct action *paction)
Definition rscompat.c:645
first_free_terrain_user_flag
static int first_free_terrain_user_flag(void)
Definition rscompat.c:361
rscompat_old_slow_invasions_3_1
bool rscompat_old_slow_invasions_3_1(struct rscompat_info *compat, bool slow_invasions)
Definition rscompat.c:1908
rscompat_postprocess
void rscompat_postprocess(struct rscompat_info *info)
Definition rscompat.c:859
rscompat_check_capabilities
int rscompat_check_capabilities(struct section_file *file, const char *filename, const struct rscompat_info *info)
Definition rscompat.c:65
UCF_LAST_USER_FLAG_3_0
#define UCF_LAST_USER_FLAG_3_0
Definition rscompat.c:50
rscompat_enablers_add_obligatory_hard_reqs
void rscompat_enablers_add_obligatory_hard_reqs(void)
Definition rscompat.c:285
effect_list_compat_cb
static bool effect_list_compat_cb(struct effect *peffect, void *data)
Definition rscompat.c:570
first_free_unit_type_user_flag
static int first_free_unit_type_user_flag(void)
Definition rscompat.c:323
effect_to_enabler
static void effect_to_enabler(action_id action, struct section_file *file, const char *sec_name, struct rscompat_info *compat, const char *type)
Definition rscompat.c:752
rscompat_action_max_range_name_S3_1
const char * rscompat_action_max_range_name_S3_1(struct rscompat_info *compat, int act_id)
Definition rscompat.c:2253
rscompat_init_info
void rscompat_init_info(struct rscompat_info *info)
Definition rscompat.c:56
slow_invasion_effects
static bool slow_invasion_effects(const char *action_rule_name)
Definition rscompat.c:1881
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_combat_bonus_name_3_1
const char * rscompat_combat_bonus_name_3_1(struct rscompat_info *compat, const char *old_type)
Definition rscompat.c:2177
enough_new_user_flags
#define enough_new_user_flags(_new_flags_, _name_, _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_)
Definition rscompat.c:43
rscompat_req_type_name_3_1
const char * rscompat_req_type_name_3_1(const char *old_type)
Definition rscompat.c:2043
effect_handle_split_universal
static bool effect_handle_split_universal(struct effect *peffect, struct universal original, struct universal separated)
Definition rscompat.c:551
rscompat.h
lookup_req_list
struct requirement_vector * lookup_req_list(struct section_file *file, struct rscompat_info *compat, const char *sec, const char *sub, const char *rfor)
Definition ruleset.c:645
RULESET_COMPAT_CAP
#define RULESET_COMPAT_CAP
Definition rscompat.h:26
autoadjust_ruleset_data
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1517
rssanity.h
ruleset.h
ruleset_error
#define ruleset_error(logger, level, format,...)
Definition ruleset.h:57
RULESET_CAPABILITIES
#define RULESET_CAPABILITIES
Definition ruleset.h:24
RSFORMAT_3_1
#define RSFORMAT_3_1
Definition ruleset.h:36
compat
static struct compatibility compat[]
Definition savecompat.c:101
ssetv_setting_get
server_setting_id ssetv_setting_get(ssetv enc)
Definition server_settings.c:129
server_setting_exists
bool server_setting_exists(server_setting_id id)
Definition server_settings.c:62
ssetv_by_rule_name
ssetv ssetv_by_rule_name(const char *name)
Definition server_settings.c:153
setting_by_name
struct setting * setting_by_name(const char *name)
Definition settings.c:3138
setting_by_number
struct setting * setting_by_number(int id)
Definition settings.c:3130
settings.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
BOOL_VAL
#define BOOL_VAL(x)
Definition shared.h:70
XOR
#define XOR(p, q)
Definition shared.h:71
action_auto_perf
Definition actions.h:568
action_auto_perf::reqs
struct requirement_vector reqs
Definition actions.h:574
action_auto_perf::alternatives
action_id alternatives[MAX_NUM_ACTIONS]
Definition actions.h:578
action_enabler
Definition actions.h:438
action_enabler::ruledit_disabled
bool ruledit_disabled
Definition actions.h:445
action_enabler::action
action_id action
Definition actions.h:439
action_enabler::actor_reqs
struct requirement_vector actor_reqs
Definition actions.h:440
action_enabler::target_reqs
struct requirement_vector target_reqs
Definition actions.h:441
action
Definition actions.h:379
action::id
action_id id
Definition actions.h:380
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:412
action::max_distance
int max_distance
Definition actions.h:395
action::quiet
bool quiet
Definition actions.h:402
action::moves_actor
enum moves_actor_kind moves_actor
Definition actions.h:432
action::is_unit
struct action::@12::@13 is_unit
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:398
action::actor
union action::@12 actor
action::target_kind
enum action_target_kind target_kind
Definition actions.h:386
action::min_distance
int min_distance
Definition actions.h:395
city
Definition city.h:309
civ_game::info
struct packet_game_info info
Definition game.h:89
clause_info
Definition diptreaty.h:53
clause_info::enabled
bool enabled
Definition diptreaty.h:55
compatibility::version
int version
Definition savecompat.c:84
effect
Definition effects.h:340
effect::value
int value
Definition effects.h:349
effect::reqs
struct requirement_vector reqs
Definition effects.h:353
effect::type
enum effect_type type
Definition effects.h:341
extra_type
Definition extras.h:85
extra_type::rmcauses
uint8_t rmcauses
Definition extras.h:92
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:150
req_vec_change::operation
enum req_vec_change_operation operation
Definition requirements.h:281
req_vec_problem
Definition requirements.h:287
req_vec_problem::num_suggested_solutions
int num_suggested_solutions
Definition requirements.h:293
req_vec_problem::description
char description[500]
Definition requirements.h:290
req_vec_problem::suggested_solutions
struct req_vec_change * suggested_solutions
Definition requirements.h:294
requirement
Definition requirements.h:80
requirement::range
enum req_range range
Definition requirements.h:82
requirement::source
struct universal source
Definition requirements.h:81
road_type
Definition road.h:75
road_type::compat
enum road_compat compat
Definition road.h:83
rscompat_info
Definition rscompat.h:29
rscompat_info::version
int version
Definition rscompat.h:32
rscompat_info::compat_mode
bool compat_mode
Definition rscompat.h:30
section_file
Definition section_file.h:36
setting
Definition settings.c:88
terrain
Definition terrain.h:176
unit_class
Definition unittype.h:136
unit_class::flags
bv_unit_class_flags flags
Definition unittype.h:144
unit_type
Definition unittype.h:481
unit_type::rscompat_cache
struct unit_type::@89 rscompat_cache
unit_type::paratroopers_mr_sub
int paratroopers_mr_sub
Definition unittype.h:572
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:161
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
terrain_flag_id_name_cb
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:805
set_user_terrain_flag_name
void set_user_terrain_flag_name(enum terrain_flag_id id, const char *name, const char *helptxt)
Definition terrain.c:776
MAX_NUM_USER_TER_FLAGS
#define MAX_NUM_USER_TER_FLAGS
Definition terrain.h:146
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
uclass_rule_name
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1693
unit_class_flag_id_name_cb
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1894
utype_number
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
unit_type_flag_id_name_cb
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1957
set_user_unit_class_flag_name
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1864
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
set_user_unit_type_flag_name
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1928
unittype.h
UCF_LAST_USER_FLAG
#define UCF_LAST_USER_FLAG
Definition unittype.h:112
HUT_FRIGHTEN
@ HUT_FRIGHTEN
Definition unittype.h:129
HUT_NOTHING
@ HUT_NOTHING
Definition unittype.h:129
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:876
MAX_NUM_USER_UNIT_FLAGS
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:316
UTYF_LAST_USER_FLAG
#define UTYF_LAST_USER_FLAG
Definition unittype.h:315
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:838
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:883
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:845
MAX_NUM_USER_UCLASS_FLAGS
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:113
edit
#define edit(pedit)
Definition widget_edit.h:34