Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/actions.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
actions.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996-2013 - Freeciv Development Team
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#include <math.h> /* ceil, floor */
19#include <stdarg.h>
20
21/* utility */
22#include "astring.h"
23
24/* common */
25#include "actions.h"
26#include "city.h"
27#include "combat.h"
28#include "fc_interface.h"
29#include "game.h"
30#include "map.h"
31#include "movement.h"
32#include "research.h"
33#include "server_settings.h"
34#include "tile.h"
35#include "unit.h"
36
37/* Custom data types for obligatory hard action requirements. */
38
39/* A contradiction to an obligatory hard requirement. */
40 struct action_enabler_contradiction {
41 /* A requirement that contradicts the obligatory hard requirement. */
42 struct requirement req;
43
44 /* Is the obligatory hard requirement in the action enabler's target
45 * requirement vector? If FALSE it is in its actor requirement vector. */
46 bool is_target;
47};
48
49/* One or more alternative obligatory hard requirement contradictions. */
50 struct ae_contra_or {
51 int alternatives;
52 /* The obligatory hard requirement is fulfilled if a contradiction exists
53 * that doesn't contradict the action enabler. */
54 struct action_enabler_contradiction *alternative;
55
56 /* How many obligatory reqs use this */
57 int users;
58};
59
60/* An obligatory hard action requirement */
61 struct obligatory_req {
62 /* The requirement is fulfilled if the action enabler doesn't contradict
63 * one of the contradictions listed here. */
64 struct ae_contra_or *contras;
65
66 /* The error message to show when the hard obligatory requirement is
67 * missing. Must be there. */
68 const char *error_msg;
69};
70
71#define SPECVEC_TAG obligatory_req
72#define SPECVEC_TYPE struct obligatory_req
73#include "specvec.h"
74#define obligatory_req_vector_iterate(obreq_vec, pobreq) \
75 TYPED_VECTOR_ITERATE(struct obligatory_req, obreq_vec, pobreq)
76#define obligatory_req_vector_iterate_end VECTOR_ITERATE_END
77
78/* Values used to interpret action probabilities.
79 *
80 * Action probabilities are sent over the network. A change in a value here
81 * will therefore change the network protocol.
82 *
83 * A change in a value here should also update the action probability
84 * format documentation in fc_types.h */
85/* The lowest possible probability value (0%) */
86#define ACTPROB_VAL_MIN 0
87/* The highest possible probability value (100%) */
88#define ACTPROB_VAL_MAX 200
89/* A probability increase of 1% corresponds to this increase. */
90#define ACTPROB_VAL_1_PCT (ACTPROB_VAL_MAX / 100)
91/* Action probability doesn't apply when min is this. */
92#define ACTPROB_VAL_NA 253
93/* Action probability unsupported when min is this. */
94#define ACTPROB_VAL_NOT_IMPL 254
95
96 static struct action *actions[MAX_NUM_ACTIONS];
97 struct action **_actions = actions;
98 struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS];
99 static bool actions_initialized = FALSE;
100
101 static struct action_enabler_list *action_enablers_by_action[MAX_NUM_ACTIONS];
102
103/* Hard requirements relates to action result. */
104 static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE];
105 static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT];
106
107 static struct astring ui_name_str = ASTRING_INIT;
108
109static struct action *
110 unit_action_new(action_id id,
111 enum action_result result,
112 bool rare_pop_up,
113 bool unitwaittime_controlled,
114 enum moves_actor_kind moves_actor,
115 const int min_distance,
116 const int max_distance,
117 bool actor_consuming_always);
118
119static enum action_sub_target_kind
120 action_sub_target_kind_default(enum action_result result);
121static enum act_tgt_compl
122 action_target_compl_calc(enum action_result result,
123 enum action_target_kind tgt_kind,
124 enum action_sub_target_kind sub_tgt_kind);
125
126static bool is_enabler_active(const struct action_enabler *enabler,
127 const struct req_context *actor,
128 const struct req_context *target);
129
130static inline bool
131 action_prob_is_signal(const struct act_prob probability);
132static inline bool
133 action_prob_not_relevant(const struct act_prob probability);
134static inline bool
135 action_prob_not_impl(const struct act_prob probability);
136
137static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
138 const struct unit *pvictim,
139 const struct tile *tgt_tile)
140 fc__attribute((nonnull(3)));
141
142/* Make sure that an action distance can target the whole map. */
143 FC_STATIC_ASSERT(MAP_DISTANCE_MAX <= ACTION_DISTANCE_LAST_NON_SIGNAL,
144 action_range_can_not_cover_the_whole_map);
145
146 static struct action_list *actlist_by_result[ACTRES_LAST];
147 static struct action_list *actlist_by_activity[ACTIVITY_LAST];
148
149/**********************************************************************/
160 static struct ae_contra_or *req_contradiction_or(int alternatives, ...)
161{
162 struct ae_contra_or *out;
163 int i;
164 va_list args;
165
166 fc_assert_ret_val(alternatives > 0, NULL);
167 out = fc_malloc(sizeof(*out));
168 out->users = 0;
169 out->alternatives = alternatives;
170 out->alternative = fc_malloc(sizeof(out->alternative[0]) * alternatives);
171
172 va_start(args, alternatives);
173 for (i = 0; i < alternatives; i++) {
174 struct requirement contradiction = va_arg(args, struct requirement);
175 bool is_target = va_arg(args, int);
176
177 out->alternative[i].req = contradiction;
178 out->alternative[i].is_target = is_target;
179 }
180 va_end(args);
181
182 return out;
183}
184
185/**********************************************************************/
189 static void ae_contra_close(struct ae_contra_or *contra)
190{
191 contra->users--;
192
193 if (contra->users < 1) {
194 /* No users left. Delete. */
195 FC_FREE(contra->alternative);
196 FC_FREE(contra);
197 }
198}
199
200/**********************************************************************/
208 static void voblig_hard_req_reg(struct ae_contra_or *contras,
209 const char *error_message,
210 va_list args)
211{
212 struct obligatory_req oreq;
213 enum action_result res;
214
215 /* A non null action message is used to indicate that an obligatory hard
216 * requirement is missing. */
217 fc_assert_ret(error_message);
218
219 /* Pack the obligatory hard requirement. */
220 oreq.contras = contras;
221 oreq.error_msg = error_message;
222
223 /* Add the obligatory hard requirement to each action result it applies
224 * to. */
225 while (ACTRES_NONE != (res = va_arg(args, enum action_result))) {
226 /* Any invalid action result should terminate the loop before this
227 * assertion. */
228 fc_assert_ret_msg(action_result_is_valid(res),
229 "Invalid action result %d", res);
230
231 /* Add to list for action result */
232 obligatory_req_vector_append(&oblig_hard_reqs_r[res], oreq);
233
234 /* Register the new user. */
235 oreq.contras->users++;
236 }
237}
238
239/**********************************************************************/
247 static void oblig_hard_req_reg(struct ae_contra_or *contras,
248 const char *error_message,
249 ...)
250{
251 va_list args;
252
253 /* Add the obligatory hard requirement to each action result it applies
254 * to. */
255 va_start(args, error_message);
256 voblig_hard_req_reg(contras, error_message, args);
257 va_end(args);
258}
259
260/**********************************************************************/
267 static void oblig_hard_req_register(struct requirement contradiction,
268 bool is_target,
269 const char *error_message,
270 ...)
271{
272 struct ae_contra_or *contra;
273 va_list args;
274
275 /* Pack the obligatory hard requirement. */
276 contra = req_contradiction_or(1, contradiction, is_target);
277
278 /* Add the obligatory hard requirement to each action result it applies
279 * to. */
280 va_start(args, error_message);
281 voblig_hard_req_reg(contra, error_message, args);
282 va_end(args);
283}
284
285/**********************************************************************/
294 static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
295 const char *error_message,
296 va_list args)
297{
298 struct obligatory_req oreq;
299 enum action_sub_result res;
300
301 /* A non null action message is used to indicate that an obligatory hard
302 * requirement is missing. */
303 fc_assert_ret(error_message);
304
305 /* Pack the obligatory hard requirement. */
306 oreq.contras = contras;
307 oreq.error_msg = error_message;
308
309 /* Add the obligatory hard requirement to each action sub result it
310 * applies to. */
311 while (ACT_SUB_RES_COUNT != (res = va_arg(args,
312 enum action_sub_result))) {
313 /* Any invalid action sub result should terminate the loop before this
314 * assertion. */
315 fc_assert_ret_msg(action_sub_result_is_valid(res),
316 "Invalid action result %d", res);
317
318 /* Add to list for action result */
319 obligatory_req_vector_append(&oblig_hard_reqs_sr[res], oreq);
320
321 /* Register the new user. */
322 oreq.contras->users++;
323 }
324}
325
326/**********************************************************************/
336 static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
337 const char *error_message,
338 ...)
339{
340 va_list args;
341
342 /* Add the obligatory hard requirement to each action result it applies
343 * to. */
344 va_start(args, error_message);
345 voblig_hard_req_reg_sub_res(contras, error_message, args);
346 va_end(args);
347}
348
349/**********************************************************************/
354 static void hard_code_oblig_hard_reqs(void)
355{
356 /* Why this is a hard requirement: There is currently no point in
357 * allowing the listed actions against domestic targets.
358 * (Possible counter argument: crazy hack involving the Lua
359 * callback action_started_callback() to use an action to do
360 * something else. */
361 /* TODO: Unhardcode as a part of false flag operation support. */
362 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
363 FALSE, FALSE, TRUE, DRO_FOREIGN),
364 FALSE,
365 N_("All action enablers for %s must require a "
366 "foreign target."),
367 ACTRES_ESTABLISH_EMBASSY,
368 ACTRES_SPY_INVESTIGATE_CITY,
369 ACTRES_SPY_STEAL_GOLD,
370 ACTRES_STEAL_MAPS,
371 ACTRES_SPY_STEAL_TECH,
372 ACTRES_SPY_TARGETED_STEAL_TECH,
373 ACTRES_SPY_INCITE_CITY,
374 ACTRES_SPY_BRIBE_UNIT,
375 ACTRES_CAPTURE_UNITS,
376 ACTRES_CONQUER_CITY,
377 ACTRES_NONE);
378 /* The same for tile targeted actions that also can be done to unclaimed
379 * tiles. */
380 oblig_hard_req_reg(req_contradiction_or(
381 2,
382 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
383 FALSE, FALSE, TRUE, DRO_FOREIGN),
384 FALSE,
385 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
386 FALSE, TRUE, TRUE,
387 CITYT_CLAIMED),
388 TRUE),
389 /* TRANS: error message for ruledit */
390 N_("All action enablers for %s must require a "
391 "non domestic target."),
392 ACTRES_PARADROP_CONQUER,
393 ACTRES_NONE);
394 /* The same for tile extras targeted actions that also can be done to
395 * unowned extras. */
396 oblig_hard_req_reg(req_contradiction_or(
397 2,
398 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
399 FALSE, FALSE, TRUE, DRO_FOREIGN),
400 FALSE,
401 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
402 FALSE, TRUE, TRUE,
403 CITYT_EXTRAS_OWNED),
404 TRUE),
405 /* TRANS: error message for ruledit */
406 N_("All action enablers for %s must require a "
407 "non domestic target."),
408 ACTRES_CONQUER_EXTRAS,
409 ACTRES_NONE);
410
411 /* Why this is a hard requirement: There is currently no point in
412 * establishing an embassy when a real embassy already exists.
413 * (Possible exception: crazy hack using the Lua callback
414 * action_started_callback() to make establish embassy do something
415 * else even if the UI still call the action Establish Embassy) */
416 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
417 FALSE, TRUE, TRUE,
418 DRO_HAS_REAL_EMBASSY),
419 FALSE,
420 N_("All action enablers for %s must require the"
421 " absence of a real embassy."),
422 ACTRES_ESTABLISH_EMBASSY,
423 ACTRES_NONE);
424
425 /* Why this is a hard requirement: There is currently no point in
426 * fortifying an already fortified unit. */
427 oblig_hard_req_register(req_from_values(VUT_ACTIVITY, REQ_RANGE_LOCAL,
428 FALSE, TRUE, TRUE,
429 ACTIVITY_FORTIFIED),
430 FALSE,
431 N_("All action enablers for %s must require that"
432 " the actor unit isn't already fortified."),
433 ACTRES_FORTIFY,
434 ACTRES_NONE);
435
436 /* Why this is a hard requirement: there is a hard requirement that
437 * the actor player is at war with the owner of any city on the
438 * target tile.
439 * The Freeciv code assumes that ACTRES_ATTACK has this. */
440 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
441 FALSE, FALSE, TRUE, DS_WAR),
442 FALSE,
443 N_("All action enablers for %s must require"
444 " that the actor is at war with the target."),
445 ACTRES_BOMBARD,
446 ACTRES_ATTACK,
447 ACTRES_NONE);
448
449 /* Why this is a hard requirement: assumed by the Freeciv code. */
450 oblig_hard_req_reg(req_contradiction_or(
451 2,
452 req_from_values(VUT_DIPLREL_TILE_O,
453 REQ_RANGE_LOCAL,
454 FALSE, FALSE, TRUE, DS_WAR),
455 TRUE,
456 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
457 FALSE, TRUE, TRUE,
458 CITYT_CENTER),
459 TRUE),
460 N_("All action enablers for %s must require"
461 " that the actor is at war with the owner of the"
462 " target tile or that the target tile doesn't have"
463 " a city."),
464 ACTRES_BOMBARD,
465 ACTRES_NONE);
466
467 /* Why this is a hard requirement: Keep the old rules. Need to work
468 * out corner cases. */
469 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
470 FALSE, TRUE, TRUE, DRO_FOREIGN),
471 FALSE,
472 N_("All action enablers for %s must require"
473 " a domestic target."),
474 ACTRES_UPGRADE_UNIT, ACTRES_NONE);
475
476 /* Why this is a hard requirement: The code expects that only domestic and
477 * allied transports can be boarded. */
478 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
479 FALSE, TRUE, TRUE, DS_ARMISTICE),
480 FALSE,
481 N_("All action enablers for %s must require"
482 " a domestic or allied target."),
483 ACTRES_TRANSPORT_EMBARK,
484 ACTRES_TRANSPORT_BOARD,
485 ACTRES_NONE);
486 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
487 FALSE, TRUE, TRUE, DS_WAR),
488 FALSE,
489 N_("All action enablers for %s must require"
490 " a domestic or allied target."),
491 ACTRES_TRANSPORT_EMBARK,
492 ACTRES_TRANSPORT_BOARD,
493 ACTRES_NONE);
494 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
495 FALSE, TRUE, TRUE, DS_CEASEFIRE),
496 FALSE,
497 N_("All action enablers for %s must require"
498 " a domestic or allied target."),
499 ACTRES_TRANSPORT_EMBARK,
500 ACTRES_TRANSPORT_BOARD,
501 ACTRES_NONE);
502 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
503 FALSE, TRUE, TRUE, DS_PEACE),
504 FALSE,
505 N_("All action enablers for %s must require"
506 " a domestic or allied target."),
507 ACTRES_TRANSPORT_EMBARK,
508 ACTRES_TRANSPORT_BOARD,
509 ACTRES_NONE);
510 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
511 FALSE, TRUE, TRUE, DS_NO_CONTACT),
512 FALSE,
513 N_("All action enablers for %s must require"
514 " a domestic or allied target."),
515 ACTRES_TRANSPORT_EMBARK,
516 ACTRES_TRANSPORT_BOARD,
517 ACTRES_NONE);
518
519 /* Why this is a hard requirement: Preserve semantics of the Settlers
520 * unit type flag. */
521 oblig_hard_req_register(req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
522 FALSE, FALSE, TRUE,
523 UTYF_SETTLERS),
524 FALSE,
525 N_("All action enablers for %s must require"
526 " that the actor has"
527 " the Settlers utype flag."),
528 ACTRES_TRANSFORM_TERRAIN,
529 ACTRES_CULTIVATE,
530 ACTRES_PLANT,
531 ACTRES_ROAD,
532 ACTRES_BASE,
533 ACTRES_MINE,
534 ACTRES_IRRIGATE,
535 ACTRES_CLEAN_POLLUTION,
536 ACTRES_CLEAN_FALLOUT,
537 ACTRES_NONE);
538
539 /* Why this is a hard requirement: Preserve semantics of the rule that a
540 * *_time of 0 disables the action. */
541 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_LOCAL,
542 FALSE, FALSE, FALSE,
543 TA_CAN_IRRIGATE),
544 TRUE,
545 N_("All action enablers for %s must require"
546 " that the target"
547 " tile's terrain's irrigation_time"
548 " is above 0. (See \"TerrainAlter\"'s"
549 " \"CanIrrigate\")"),
550 ACTRES_IRRIGATE,
551 ACTRES_NONE);
552 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_LOCAL,
553 FALSE, FALSE, FALSE,
554 TA_CAN_MINE),
555 TRUE,
556 N_("All action enablers for %s must require"
557 " that the target"
558 " tile's terrain's mining_time"
559 " is above 0. (See \"TerrainAlter\"'s"
560 " \"CanMine\")"),
561 ACTRES_MINE,
562 ACTRES_NONE);
563
564 /* Why this is a hard requirement: Preserve semantics of the NoCities
565 * terrain flag. */
566 oblig_hard_req_register(req_from_values(VUT_TERRFLAG, REQ_RANGE_LOCAL,
567 FALSE, TRUE, TRUE,
568 TER_NO_CITIES),
569 TRUE,
570 N_("All action enablers for %s must require that"
571 " the target doesn't have"
572 " the NoCities terrain flag."),
573 ACTRES_FOUND_CITY,
574 ACTRES_NONE);
575
576 /* It isn't possible to establish a trade route from a non existing
577 * city. The Freeciv code assumes this applies to Enter Marketplace
578 * too. */
579 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
580 FALSE, FALSE, TRUE,
581 USP_HAS_HOME_CITY),
582 FALSE,
583 N_("All action enablers for %s must require"
584 " that the actor has a home city."),
585 ACTRES_TRADE_ROUTE,
586 ACTRES_MARKETPLACE,
587 ACTRES_NONE);
588
589 /* Why this is a hard requirement:
590 * - preserve the semantics of the NonMil unit type flag. */
591 oblig_hard_req_reg(req_contradiction_or(
592 3,
593 req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
594 FALSE, FALSE, TRUE,
595 UTYF_CIVILIAN),
596 FALSE,
597 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
598 FALSE, TRUE, TRUE, DS_PEACE),
599 FALSE,
600 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
601 FALSE, TRUE, TRUE,
602 CITYT_CLAIMED),
603 TRUE),
604 /* TRANS: error message for ruledit */
605 N_("All action enablers for %s must require"
606 " that the actor has the NonMil utype flag"
607 " or that the target tile is unclaimed"
608 " or that the diplomatic relation to"
609 " the target tile owner isn't peace."),
610 ACTRES_PARADROP,
611 ACTRES_PARADROP_CONQUER,
612 ACTRES_NONE);
613
614 /* Why this is a hard requirement: Preserve semantics of NonMil
615 * flag. Need to replace other uses in game engine before this can
616 * be demoted to a regular unit flag. */
617 oblig_hard_req_register(req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
618 FALSE, TRUE, TRUE, UTYF_CIVILIAN),
619 FALSE,
620 N_("All action enablers for %s must require"
621 " that the actor doesn't have"
622 " the NonMil utype flag."),
623 ACTRES_ATTACK,
624 ACTRES_CONQUER_CITY,
625 ACTRES_NONE);
626 oblig_hard_req_reg(req_contradiction_or(
627 2,
628 req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
629 FALSE, TRUE, TRUE, UTYF_CIVILIAN),
630 FALSE,
631 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
632 FALSE, TRUE, TRUE,
633 CITYT_CENTER),
634 TRUE),
635 /* TRANS: error message for ruledit */
636 N_("All action enablers for %s must require"
637 " no city at the target tile or"
638 " that the actor doesn't have"
639 " the NonMil utype flag."),
640 ACTRES_PARADROP_CONQUER,
641 ACTRES_NONE);
642
643 /* Why this is a hard requirement: Preserve semantics of
644 * CanOccupyCity unit class flag. */
645 oblig_hard_req_register(req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
646 FALSE, FALSE, TRUE,
647 UCF_CAN_OCCUPY_CITY),
648 FALSE,
649 N_("All action enablers for %s must require"
650 " that the actor has"
651 " the CanOccupyCity uclass flag."),
652 ACTRES_CONQUER_CITY,
653 ACTRES_NONE);
654 oblig_hard_req_reg(req_contradiction_or(
655 2,
656 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
657 FALSE, FALSE, TRUE,
658 UCF_CAN_OCCUPY_CITY),
659 FALSE,
660 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
661 FALSE, TRUE, TRUE,
662 CITYT_CENTER),
663 TRUE),
664 /* TRANS: error message for ruledit */
665 N_("All action enablers for %s must require"
666 " no city at the target tile or"
667 " that the actor has"
668 " the CanOccupyCity uclass flag."),
669 ACTRES_PARADROP_CONQUER,
670 ACTRES_NONE);
671
672 /* Why this is a hard requirement: Consistency with ACTRES_ATTACK.
673 * Assumed by other locations in the Freeciv code. Examples:
674 * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */
675 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
676 FALSE, FALSE, TRUE, DS_WAR),
677 FALSE,
678 N_("All action enablers for %s must require"
679 " that the actor is at war with the target."),
680 ACTRES_CONQUER_CITY,
681 ACTRES_NONE);
682 oblig_hard_req_reg(req_contradiction_or(
683 2,
684 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
685 FALSE, FALSE, TRUE, DS_WAR),
686 FALSE,
687 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
688 FALSE, TRUE, TRUE,
689 CITYT_CENTER),
690 TRUE),
691 /* TRANS: error message for ruledit */
692 N_("All action enablers for %s must require"
693 " no city at the target tile or"
694 " that the actor is at war with the target."),
695 ACTRES_PARADROP_CONQUER,
696 ACTRES_NONE);
697
698 /* Why this is a hard requirement: a unit must move into a city to
699 * conquer it, move into a transport to embark, move out of a transport
700 * to disembark from it, move into an extra to conquer it and move into a
701 * hut to enter/frighten it. */
702 oblig_hard_req_register(req_from_values(VUT_MINMOVES, REQ_RANGE_LOCAL,
703 FALSE, FALSE, TRUE, 1),
704 FALSE,
705 N_("All action enablers for %s must require"
706 " that the actor has a movement point left."),
707 ACTRES_CONQUER_CITY,
708 ACTRES_TRANSPORT_DISEMBARK,
709 ACTRES_TRANSPORT_EMBARK,
710 ACTRES_CONQUER_EXTRAS,
711 ACTRES_HUT_ENTER,
712 ACTRES_HUT_FRIGHTEN,
713 ACTRES_UNIT_MOVE,
714 ACTRES_NONE);
715
716 /* Why this is a hard requirement: this eliminates the need to
717 * check if units transported by the actor unit can exist at the
718 * same tile as all the units in the occupied city.
719 *
720 * This makes an implicit rule explicit:
721 * 1. A unit must move into a city to conquer it.
722 * 2. It can't move into the city if the tile contains a non-allied
723 * unit (see unit_move_to_tile_test()).
724 * 3. A city could, at the time this rule was made explicit, only
725 * contain units allied to its owner.
726 * 3. A player could, at the time this rule was made explicit, not
727 * be allied to a player that is at war with another ally.
728 * 4. A player could, at the time this rule was made explicit, only
729 * conquer a city belonging to someone they were at war with.
730 * Conclusion: the conquered city had to be empty.
731 */
732 oblig_hard_req_register(req_from_values(VUT_MAXTILEUNITS, REQ_RANGE_LOCAL,
733 FALSE, FALSE, TRUE, 0),
734 TRUE,
735 N_("All action enablers for %s must require"
736 " that the target city is empty."),
737 ACTRES_CONQUER_CITY,
738 ACTRES_NONE);
739
740 /* Why this is a hard requirement: Assumed in the code. Corner case
741 * where diplomacy prevents a transported unit to go to the target
742 * tile. The paradrop code doesn't check if transported units can
743 * coexist with the target tile city and units. */
744 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
745 FALSE, TRUE, TRUE,
746 USP_TRANSPORTING),
747 FALSE,
748 N_("All action enablers for %s must require"
749 " that the actor isn't transporting"
750 " another unit."),
751 ACTRES_PARADROP,
752 ACTRES_PARADROP_CONQUER,
753 ACTRES_AIRLIFT,
754 ACTRES_NONE);
755
756 /* Why this is a hard requirement: sanity. */
757 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
758 FALSE, FALSE, FALSE,
759 USP_HAS_HOME_CITY),
760 FALSE,
761 N_("All action enablers for %s must require"
762 " that the actor has a home city."),
763 ACTRES_HOMELESS, ACTRES_NONE);
764
765 /* Why this is a hard requirement: Assumed in the code.
766 * See hrm Bug #772516 - https://www.hostedredmine.com/issues/772516 */
767 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
768 FALSE, TRUE, TRUE,
769 USP_TRANSPORTING),
770 TRUE,
771 N_("All action enablers for %s must require"
772 " that the target isn't transporting another"
773 " unit."),
774 ACTRES_CAPTURE_UNITS, ACTRES_NONE);
775
776 /* Why this is a hard requirement: sanity. */
777 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
778 FALSE, FALSE, TRUE,
779 USP_TRANSPORTING),
780 TRUE,
781 N_("All action enablers for %s must require"
782 " that the target is transporting a unit."),
783 ACTRES_TRANSPORT_ALIGHT, ACTRES_NONE);
784 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
785 FALSE, FALSE, TRUE,
786 USP_TRANSPORTED),
787 FALSE,
788 N_("All action enablers for %s must require"
789 " that the actor is transported."),
790 ACTRES_TRANSPORT_ALIGHT,
791 ACTRES_TRANSPORT_DISEMBARK,
792 ACTRES_NONE);
793 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
794 FALSE, FALSE, TRUE,
795 USP_LIVABLE_TILE),
796 FALSE,
797 N_("All action enablers for %s must require"
798 " that the actor is on a livable tile."),
799 ACTRES_TRANSPORT_ALIGHT, ACTRES_NONE);
800
801 /* Why this is a hard requirement: sanity. */
802 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
803 FALSE, FALSE, TRUE,
804 USP_TRANSPORTING),
805 FALSE,
806 N_("All action enablers for %s must require"
807 " that the actor is transporting a unit."),
808 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
809 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
810 FALSE, FALSE, TRUE,
811 USP_TRANSPORTED),
812 TRUE,
813 N_("All action enablers for %s must require"
814 " that the target is transported."),
815 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
816 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
817 FALSE, FALSE, TRUE,
818 USP_LIVABLE_TILE),
819 TRUE,
820 N_("All action enablers for %s must require"
821 " that the target is on a livable tile."),
822 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
823
824 /* Why this is a hard requirement: Use ACTRES_TRANSPORT_DISEMBARK to
825 * disembark. Assumed by the Freeciv code. */
826 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
827 FALSE, TRUE, TRUE,
828 USP_TRANSPORTED),
829 FALSE,
830 N_("All action enablers for %s must require"
831 " that the actor isn't transported."),
832 ACTRES_UNIT_MOVE,
833 ACTRES_NONE);
834
835 /* Why this is a hard requirement: assumed by the Freeciv code. */
836 oblig_hard_req_register(req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
837 FALSE, FALSE, TRUE,
838 CITYT_CENTER),
839 FALSE,
840 N_("All action enablers for %s must require"
841 " that the actor unit is in a city."),
842 ACTRES_AIRLIFT,
843 ACTRES_NONE);
844
845 /* Why this is a hard requirement: Give meaning to the HutFrighten unit
846 * class flag. The point of it is to keep our options open for how both
847 * entering and frightening a hut at the same tile should be handled.
848 * See hrm Feature #920427 */
849 oblig_hard_req_reg_sub_res(req_contradiction_or(
850 1,
851 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
852 FALSE, TRUE, FALSE,
853 UCF_HUT_FRIGHTEN),
854 FALSE),
855 N_("All action enablers for %s must require"
856 " that the actor unit doesn't have the"
857 " HutFrighten unit class flag."),
858 ACT_SUB_RES_HUT_ENTER,
859 ACT_SUB_RES_COUNT);
860 oblig_hard_req_reg_sub_res(req_contradiction_or(
861 1,
862 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
863 FALSE, FALSE, FALSE,
864 UCF_HUT_FRIGHTEN),
865 FALSE),
866 N_("All action enablers for %s must require"
867 " that the actor unit has the HutFrighten"
868 " unit class flag."),
869 ACT_SUB_RES_HUT_FRIGHTEN,
870 ACT_SUB_RES_COUNT);
871}
872
873/**********************************************************************/
877 static void hard_code_oblig_hard_reqs_ruleset(void)
878{
879 /* Why this is a hard requirement: the "animal can't conquer a city"
880 * rule. Assumed in unit_can_take_over(). */
881 nations_iterate(pnation) {
882 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
883 oblig_hard_req_register(req_from_values(VUT_NATION, REQ_RANGE_PLAYER,
884 FALSE, TRUE, TRUE,
885 nation_number(pnation)),
886 FALSE,
887 N_("All action enablers for %s must require"
888 " a non animal player actor."),
889 ACTRES_CONQUER_CITY,
890 ACTRES_NONE);
891 oblig_hard_req_reg(req_contradiction_or(
892 2,
893 req_from_values(VUT_NATION, REQ_RANGE_PLAYER,
894 FALSE, TRUE, TRUE,
895 nation_number(pnation)),
896 FALSE,
897 req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL,
898 FALSE, TRUE, TRUE,
899 CITYT_CENTER),
900 TRUE),
901 /* TRANS: error message for ruledit */
902 N_("All action enablers for %s must require"
903 " no city at the target tile or"
904 " a non animal player actor."),
905 ACTRES_PARADROP_CONQUER,
906 ACTRES_NONE);
907 }
908 } nations_iterate_end;
909}
910
911/**********************************************************************/
914 static void hard_code_actions(void)
915{
916 actions[ACTION_SPY_POISON] =
917 unit_action_new(ACTION_SPY_POISON, ACTRES_SPY_POISON,
918 FALSE, TRUE,
919 MAK_ESCAPE, 0, 1, TRUE);
920 actions[ACTION_SPY_POISON_ESC] =
921 unit_action_new(ACTION_SPY_POISON_ESC, ACTRES_SPY_POISON,
922 FALSE, TRUE,
923 MAK_ESCAPE, 0, 1, FALSE);
924 actions[ACTION_SPY_SABOTAGE_UNIT] =
925 unit_action_new(ACTION_SPY_SABOTAGE_UNIT, ACTRES_SPY_SABOTAGE_UNIT,
926 FALSE, TRUE,
927 MAK_ESCAPE, 0, 1, TRUE);
928 actions[ACTION_SPY_SABOTAGE_UNIT_ESC] =
929 unit_action_new(ACTION_SPY_SABOTAGE_UNIT_ESC, ACTRES_SPY_SABOTAGE_UNIT,
930 FALSE, TRUE,
931 MAK_ESCAPE, 0, 1, FALSE);
932 actions[ACTION_SPY_BRIBE_UNIT] =
933 unit_action_new(ACTION_SPY_BRIBE_UNIT, ACTRES_SPY_BRIBE_UNIT,
934 FALSE, TRUE,
935 /* Tries a forced move if the target unit is alone at
936 * its tile and not in a city. Takes all movement if
937 * the forced move fails. */
938 MAK_FORCED,
939 0, 1, FALSE);
940 actions[ACTION_SPY_SABOTAGE_CITY] =
941 unit_action_new(ACTION_SPY_SABOTAGE_CITY, ACTRES_SPY_SABOTAGE_CITY,
942 FALSE, TRUE,
943 MAK_ESCAPE, 0, 1, TRUE);
944 actions[ACTION_SPY_SABOTAGE_CITY_ESC] =
945 unit_action_new(ACTION_SPY_SABOTAGE_CITY_ESC, ACTRES_SPY_SABOTAGE_CITY,
946 FALSE, TRUE,
947 MAK_ESCAPE, 0, 1, FALSE);
948 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY] =
949 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY,
950 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
951 FALSE, TRUE,
952 MAK_ESCAPE, 0, 1, TRUE);
953 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION] =
954 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION,
955 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
956 FALSE, TRUE,
957 MAK_ESCAPE, 0, 1, TRUE);
958 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
959 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC,
960 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
961 FALSE, TRUE,
962 MAK_ESCAPE, 0, 1, FALSE);
963 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC] =
964 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC,
965 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
966 FALSE, TRUE,
967 MAK_ESCAPE, 0, 1, FALSE);
968 actions[ACTION_SPY_INCITE_CITY] =
969 unit_action_new(ACTION_SPY_INCITE_CITY, ACTRES_SPY_INCITE_CITY,
970 FALSE, TRUE,
971 MAK_ESCAPE, 0, 1, TRUE);
972 actions[ACTION_SPY_INCITE_CITY_ESC] =
973 unit_action_new(ACTION_SPY_INCITE_CITY_ESC, ACTRES_SPY_INCITE_CITY,
974 FALSE, TRUE,
975 MAK_ESCAPE, 0, 1, FALSE);
976 actions[ACTION_ESTABLISH_EMBASSY] =
977 unit_action_new(ACTION_ESTABLISH_EMBASSY,
978 ACTRES_ESTABLISH_EMBASSY,
979 FALSE, TRUE,
980 MAK_STAYS, 0, 1, FALSE);
981 actions[ACTION_ESTABLISH_EMBASSY_STAY] =
982 unit_action_new(ACTION_ESTABLISH_EMBASSY_STAY,
983 ACTRES_ESTABLISH_EMBASSY,
984 FALSE, TRUE,
985 MAK_STAYS, 0, 1, TRUE);
986 actions[ACTION_SPY_STEAL_TECH] =
987 unit_action_new(ACTION_SPY_STEAL_TECH,
988 ACTRES_SPY_STEAL_TECH,
989 FALSE, TRUE,
990 MAK_ESCAPE, 0, 1, TRUE);
991 actions[ACTION_SPY_STEAL_TECH_ESC] =
992 unit_action_new(ACTION_SPY_STEAL_TECH_ESC,
993 ACTRES_SPY_STEAL_TECH,
994 FALSE, TRUE,
995 MAK_ESCAPE, 0, 1, FALSE);
996 actions[ACTION_SPY_TARGETED_STEAL_TECH] =
997 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH,
998 ACTRES_SPY_TARGETED_STEAL_TECH,
999 FALSE, TRUE,
1000 MAK_ESCAPE, 0, 1, TRUE);
1001 actions[ACTION_SPY_TARGETED_STEAL_TECH_ESC] =
1002 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH_ESC,
1003 ACTRES_SPY_TARGETED_STEAL_TECH,
1004 FALSE, TRUE,
1005 MAK_ESCAPE, 0, 1, FALSE);
1006 actions[ACTION_SPY_INVESTIGATE_CITY] =
1007 unit_action_new(ACTION_SPY_INVESTIGATE_CITY,
1008 ACTRES_SPY_INVESTIGATE_CITY,
1009 FALSE, TRUE,
1010 MAK_STAYS, 0, 1, FALSE);
1011 actions[ACTION_INV_CITY_SPEND] =
1012 unit_action_new(ACTION_INV_CITY_SPEND,
1013 ACTRES_SPY_INVESTIGATE_CITY,
1014 FALSE, TRUE,
1015 MAK_STAYS, 0, 1, TRUE);
1016 actions[ACTION_SPY_STEAL_GOLD] =
1017 unit_action_new(ACTION_SPY_STEAL_GOLD,
1018 ACTRES_SPY_STEAL_GOLD,
1019 FALSE, TRUE,
1020 MAK_ESCAPE, 0, 1, TRUE);
1021 actions[ACTION_SPY_STEAL_GOLD_ESC] =
1022 unit_action_new(ACTION_SPY_STEAL_GOLD_ESC,
1023 ACTRES_SPY_STEAL_GOLD,
1024 FALSE, TRUE,
1025 MAK_ESCAPE, 0, 1, FALSE);
1026 actions[ACTION_SPY_SPREAD_PLAGUE] =
1027 unit_action_new(ACTION_SPY_SPREAD_PLAGUE,
1028 ACTRES_SPY_SPREAD_PLAGUE,
1029 FALSE, TRUE,
1030 MAK_ESCAPE, 0, 1, FALSE);
1031 actions[ACTION_TRADE_ROUTE] =
1032 unit_action_new(ACTION_TRADE_ROUTE, ACTRES_TRADE_ROUTE,
1033 FALSE, TRUE,
1034 MAK_STAYS, 0, 1, TRUE);
1035 actions[ACTION_MARKETPLACE] =
1036 unit_action_new(ACTION_MARKETPLACE, ACTRES_MARKETPLACE,
1037 FALSE, TRUE,
1038 MAK_STAYS, 0, 1, TRUE);
1039 actions[ACTION_HELP_WONDER] =
1040 unit_action_new(ACTION_HELP_WONDER, ACTRES_HELP_WONDER,
1041 FALSE, TRUE,
1042 MAK_STAYS, 0, 1, TRUE);
1043 actions[ACTION_CAPTURE_UNITS] =
1044 unit_action_new(ACTION_CAPTURE_UNITS, ACTRES_CAPTURE_UNITS,
1045 FALSE, TRUE, MAK_STAYS,
1046 /* A single domestic unit at the target tile will make
1047 * the action illegal. It must therefore be performed
1048 * from another tile. */
1049 1, 1,
1050 FALSE);
1051 actions[ACTION_FOUND_CITY] =
1052 unit_action_new(ACTION_FOUND_CITY, ACTRES_FOUND_CITY,
1053 TRUE, TRUE, MAK_STAYS,
1054 /* Illegal to perform to a target on another tile.
1055 * Reason: The Freeciv code assumes that the city
1056 * founding unit is located at the tile were the new
1057 * city is founded. */
1058 0, 0,
1059 TRUE);
1060 actions[ACTION_JOIN_CITY] =
1061 unit_action_new(ACTION_JOIN_CITY, ACTRES_JOIN_CITY,
1062 TRUE, TRUE,
1063 MAK_STAYS, 0, 1, TRUE);
1064 actions[ACTION_STEAL_MAPS] =
1065 unit_action_new(ACTION_STEAL_MAPS, ACTRES_STEAL_MAPS,
1066 FALSE, TRUE,
1067 MAK_ESCAPE, 0, 1, TRUE);
1068 actions[ACTION_STEAL_MAPS_ESC] =
1069 unit_action_new(ACTION_STEAL_MAPS_ESC, ACTRES_STEAL_MAPS,
1070 FALSE, TRUE,
1071 MAK_ESCAPE, 0, 1, FALSE);
1072 actions[ACTION_BOMBARD] =
1073 unit_action_new(ACTION_BOMBARD, ACTRES_BOMBARD,
1074 FALSE, TRUE, MAK_STAYS,
1075 /* A single domestic unit at the target tile will make
1076 * the action illegal. It must therefore be performed
1077 * from another tile. */
1078 1,
1079 /* Overwritten by the ruleset's bombard_max_range */
1080 1,
1081 FALSE);
1082 actions[ACTION_BOMBARD2] =
1083 unit_action_new(ACTION_BOMBARD2, ACTRES_BOMBARD,
1084 FALSE, TRUE,
1085 MAK_STAYS,
1086 /* A single domestic unit at the target tile will make
1087 * the action illegal. It must therefore be performed
1088 * from another tile. */
1089 1,
1090 /* Overwritten by the ruleset's bombard_2_max_range */
1091 1,
1092 FALSE);
1093 actions[ACTION_BOMBARD3] =
1094 unit_action_new(ACTION_BOMBARD3, ACTRES_BOMBARD,
1095 FALSE, TRUE, MAK_STAYS,
1096 /* A single domestic unit at the target tile will make
1097 * the action illegal. It must therefore be performed
1098 * from another tile. */
1099 1,
1100 /* Overwritten by the ruleset's bombard_3_max_range */
1101 1,
1102 FALSE);
1103 actions[ACTION_SPY_NUKE] =
1104 unit_action_new(ACTION_SPY_NUKE, ACTRES_SPY_NUKE,
1105 FALSE, TRUE,
1106 MAK_ESCAPE, 0, 1, TRUE);
1107 actions[ACTION_SPY_NUKE_ESC] =
1108 unit_action_new(ACTION_SPY_NUKE_ESC, ACTRES_SPY_NUKE,
1109 FALSE, TRUE,
1110 MAK_ESCAPE, 0, 1, FALSE);
1111 actions[ACTION_NUKE] =
1112 unit_action_new(ACTION_NUKE, ACTRES_NUKE,
1113 TRUE, TRUE,
1114 MAK_STAYS, 0,
1115 /* Overwritten by the ruleset's
1116 * explode_nuclear_max_range */
1117 0,
1118 TRUE);
1119 actions[ACTION_NUKE_CITY] =
1120 unit_action_new(ACTION_NUKE_CITY, ACTRES_NUKE,
1121 TRUE, TRUE,
1122 MAK_STAYS, 1, 1, TRUE);
1123 actions[ACTION_NUKE_UNITS] =
1124 unit_action_new(ACTION_NUKE_UNITS, ACTRES_NUKE_UNITS,
1125 TRUE, TRUE,
1126 MAK_STAYS, 1, 1, TRUE);
1127 actions[ACTION_DESTROY_CITY] =
1128 unit_action_new(ACTION_DESTROY_CITY, ACTRES_DESTROY_CITY,
1129 TRUE, TRUE,
1130 MAK_STAYS, 0, 1, FALSE);
1131 actions[ACTION_EXPEL_UNIT] =
1132 unit_action_new(ACTION_EXPEL_UNIT, ACTRES_EXPEL_UNIT,
1133 FALSE, TRUE,
1134 MAK_STAYS, 0, 1, FALSE);
1135 actions[ACTION_DISBAND_UNIT_RECOVER] =
1136 unit_action_new(ACTION_DISBAND_UNIT_RECOVER, ACTRES_DISBAND_UNIT_RECOVER,
1137 TRUE, TRUE, MAK_STAYS,
1138 /* Illegal to perform to a target on another tile to
1139 * keep the rules exactly as they were for now. */
1140 0, 1,
1141 TRUE);
1142 actions[ACTION_DISBAND_UNIT] =
1143 unit_action_new(ACTION_DISBAND_UNIT,
1144 /* Can't be ACTRES_NONE because
1145 * action_success_actor_consume() sets unit lost
1146 * reason based on action result. */
1147 ACTRES_DISBAND_UNIT,
1148 TRUE, TRUE,
1149 MAK_STAYS, 0, 0, TRUE);
1150 actions[ACTION_HOME_CITY] =
1151 unit_action_new(ACTION_HOME_CITY, ACTRES_HOME_CITY,
1152 TRUE, FALSE,
1153 /* Illegal to perform to a target on another tile to
1154 * keep the rules exactly as they were for now. */
1155 MAK_STAYS, 0, 0, FALSE);
1156 actions[ACTION_HOMELESS] =
1157 unit_action_new(ACTION_HOMELESS, ACTRES_HOMELESS,
1158 TRUE, FALSE,
1159 MAK_STAYS, 0, 0, FALSE);
1160 actions[ACTION_UPGRADE_UNIT] =
1161 unit_action_new(ACTION_UPGRADE_UNIT, ACTRES_UPGRADE_UNIT,
1162 TRUE, TRUE, MAK_STAYS,
1163 /* Illegal to perform to a target on another tile to
1164 * keep the rules exactly as they were for now. */
1165 0, 0,
1166 FALSE);
1167 actions[ACTION_PARADROP] =
1168 unit_action_new(ACTION_PARADROP, ACTRES_PARADROP,
1169 TRUE, TRUE,
1170 MAK_TELEPORT,
1171 1,
1172 /* Still limited by each unit type's
1173 * paratroopers_range field. */
1174 ACTION_DISTANCE_MAX,
1175 FALSE);
1176 actions[ACTION_PARADROP_CONQUER] =
1177 unit_action_new(ACTION_PARADROP_CONQUER, ACTRES_PARADROP_CONQUER,
1178 TRUE, TRUE,
1179 MAK_TELEPORT,
1180 1,
1181 /* Still limited by each unit type's
1182 * paratroopers_range field. */
1183 ACTION_DISTANCE_MAX,
1184 FALSE);
1185 actions[ACTION_PARADROP_FRIGHTEN] =
1186 unit_action_new(ACTION_PARADROP_FRIGHTEN, ACTRES_PARADROP,
1187 TRUE, TRUE,
1188 MAK_TELEPORT,
1189 1,
1190 /* Still limited by each unit type's
1191 * paratroopers_range field. */
1192 ACTION_DISTANCE_MAX,
1193 FALSE);
1194 actions[ACTION_PARADROP_FRIGHTEN_CONQUER] =
1195 unit_action_new(ACTION_PARADROP_FRIGHTEN_CONQUER,
1196 ACTRES_PARADROP_CONQUER,
1197 TRUE, TRUE,
1198 MAK_TELEPORT,
1199 1,
1200 /* Still limited by each unit type's
1201 * paratroopers_range field. */
1202 ACTION_DISTANCE_MAX,
1203 FALSE);
1204 actions[ACTION_PARADROP_ENTER] =
1205 unit_action_new(ACTION_PARADROP_ENTER, ACTRES_PARADROP,
1206 TRUE, TRUE,
1207 MAK_TELEPORT,
1208 1,
1209 /* Still limited by each unit type's
1210 * paratroopers_range field. */
1211 ACTION_DISTANCE_MAX,
1212 FALSE);
1213 actions[ACTION_PARADROP_ENTER_CONQUER] =
1214 unit_action_new(ACTION_PARADROP_ENTER_CONQUER,
1215 ACTRES_PARADROP_CONQUER,
1216 TRUE, TRUE,
1217 MAK_TELEPORT,
1218 1,
1219 /* Still limited by each unit type's
1220 * paratroopers_range field. */
1221 ACTION_DISTANCE_MAX,
1222 FALSE);
1223 actions[ACTION_AIRLIFT] =
1224 unit_action_new(ACTION_AIRLIFT, ACTRES_AIRLIFT,
1225 TRUE, TRUE,
1226 MAK_TELEPORT,
1227 1,
1228 /* Overwritten by the ruleset's airlift_max_range. */
1229 ACTION_DISTANCE_UNLIMITED,
1230 FALSE);
1231 actions[ACTION_ATTACK] =
1232 unit_action_new(ACTION_ATTACK, ACTRES_ATTACK,
1233 FALSE, TRUE,
1234 /* Tries a forced move if the target unit's tile has
1235 * no non-allied units and the occupychance dice roll
1236 * tells it to move. */
1237 MAK_FORCED,
1238 1, 1, FALSE);
1239 actions[ACTION_SUICIDE_ATTACK] =
1240 unit_action_new(ACTION_SUICIDE_ATTACK, ACTRES_ATTACK,
1241 FALSE, TRUE,
1242 MAK_FORCED, 1, 1, TRUE);
1243 actions[ACTION_STRIKE_BUILDING] =
1244 unit_action_new(ACTION_STRIKE_BUILDING, ACTRES_STRIKE_BUILDING,
1245 FALSE, FALSE,
1246 MAK_STAYS, 1, 1, FALSE);
1247 actions[ACTION_STRIKE_PRODUCTION] =
1248 unit_action_new(ACTION_STRIKE_PRODUCTION, ACTRES_STRIKE_PRODUCTION,
1249 FALSE, FALSE,
1250 MAK_STAYS, 1, 1, FALSE);
1251 actions[ACTION_CONQUER_CITY] =
1252 unit_action_new(ACTION_CONQUER_CITY, ACTRES_CONQUER_CITY,
1253 FALSE, TRUE,
1254 MAK_REGULAR, 1, 1, FALSE);
1255 actions[ACTION_CONQUER_CITY2] =
1256 unit_action_new(ACTION_CONQUER_CITY2, ACTRES_CONQUER_CITY,
1257 FALSE, TRUE,
1258 MAK_REGULAR, 1, 1, FALSE);
1259 actions[ACTION_CONQUER_CITY3] =
1260 unit_action_new(ACTION_CONQUER_CITY3, ACTRES_CONQUER_CITY,
1261 FALSE, TRUE,
1262 MAK_REGULAR, 1, 1, FALSE);
1263 actions[ACTION_CONQUER_CITY4] =
1264 unit_action_new(ACTION_CONQUER_CITY4, ACTRES_CONQUER_CITY,
1265 FALSE, TRUE,
1266 MAK_REGULAR, 1, 1, FALSE);
1267 actions[ACTION_CONQUER_EXTRAS] =
1268 unit_action_new(ACTION_CONQUER_EXTRAS, ACTRES_CONQUER_EXTRAS,
1269 FALSE, TRUE,
1270 MAK_REGULAR, 1, 1, FALSE);
1271 actions[ACTION_CONQUER_EXTRAS2] =
1272 unit_action_new(ACTION_CONQUER_EXTRAS2, ACTRES_CONQUER_EXTRAS,
1273 FALSE, TRUE,
1274 MAK_REGULAR, 1, 1, FALSE);
1275 actions[ACTION_CONQUER_EXTRAS3] =
1276 unit_action_new(ACTION_CONQUER_EXTRAS3, ACTRES_CONQUER_EXTRAS,
1277 FALSE, TRUE,
1278 MAK_REGULAR, 1, 1, FALSE);
1279 actions[ACTION_CONQUER_EXTRAS4] =
1280 unit_action_new(ACTION_CONQUER_EXTRAS4, ACTRES_CONQUER_EXTRAS,
1281 FALSE, TRUE,
1282 MAK_REGULAR, 1, 1, FALSE);
1283 actions[ACTION_HEAL_UNIT] =
1284 unit_action_new(ACTION_HEAL_UNIT, ACTRES_HEAL_UNIT,
1285 FALSE, TRUE,
1286 MAK_STAYS, 0, 1, FALSE);
1287 actions[ACTION_HEAL_UNIT2] =
1288 unit_action_new(ACTION_HEAL_UNIT2, ACTRES_HEAL_UNIT,
1289 FALSE, TRUE,
1290 MAK_STAYS, 0, 1, FALSE);
1291 actions[ACTION_TRANSFORM_TERRAIN] =
1292 unit_action_new(ACTION_TRANSFORM_TERRAIN, ACTRES_TRANSFORM_TERRAIN,
1293 TRUE, FALSE,
1294 MAK_STAYS, 0, 0, FALSE);
1295 actions[ACTION_CULTIVATE] =
1296 unit_action_new(ACTION_CULTIVATE, ACTRES_CULTIVATE,
1297 TRUE, FALSE,
1298 MAK_STAYS, 0, 0, FALSE);
1299 actions[ACTION_PLANT] =
1300 unit_action_new(ACTION_PLANT, ACTRES_PLANT,
1301 TRUE, FALSE,
1302 MAK_STAYS, 0, 0, FALSE);
1303 actions[ACTION_PILLAGE] =
1304 unit_action_new(ACTION_PILLAGE, ACTRES_PILLAGE,
1305 TRUE, FALSE,
1306 MAK_STAYS, 0, 0, FALSE);
1307 actions[ACTION_CLEAN_POLLUTION] =
1308 unit_action_new(ACTION_CLEAN_POLLUTION, ACTRES_CLEAN_POLLUTION,
1309 TRUE, FALSE,
1310 MAK_STAYS, 0, 0, FALSE);
1311 actions[ACTION_CLEAN_FALLOUT] =
1312 unit_action_new(ACTION_CLEAN_FALLOUT, ACTRES_CLEAN_FALLOUT,
1313 TRUE, FALSE,
1314 MAK_STAYS, 0, 0, FALSE);
1315 actions[ACTION_FORTIFY] =
1316 unit_action_new(ACTION_FORTIFY, ACTRES_FORTIFY,
1317 TRUE, FALSE,
1318 MAK_STAYS, 0, 0, FALSE);
1319 actions[ACTION_ROAD] =
1320 unit_action_new(ACTION_ROAD, ACTRES_ROAD,
1321 TRUE, FALSE,
1322 MAK_STAYS, 0, 0, FALSE);
1323 actions[ACTION_CONVERT] =
1324 unit_action_new(ACTION_CONVERT, ACTRES_CONVERT,
1325 TRUE, FALSE,
1326 MAK_STAYS, 0, 0, FALSE);
1327 actions[ACTION_BASE] =
1328 unit_action_new(ACTION_BASE, ACTRES_BASE,
1329 TRUE, FALSE,
1330 MAK_STAYS, 0, 0, FALSE);
1331 actions[ACTION_MINE] =
1332 unit_action_new(ACTION_MINE, ACTRES_MINE,
1333 TRUE, FALSE,
1334 MAK_STAYS, 0, 0, FALSE);
1335 actions[ACTION_IRRIGATE] =
1336 unit_action_new(ACTION_IRRIGATE, ACTRES_IRRIGATE,
1337 TRUE, FALSE,
1338 MAK_STAYS, 0, 0, FALSE);
1339 actions[ACTION_TRANSPORT_ALIGHT] =
1340 unit_action_new(ACTION_TRANSPORT_ALIGHT, ACTRES_TRANSPORT_ALIGHT,
1341 TRUE, FALSE,
1342 MAK_STAYS, 0, 0, FALSE);
1343 actions[ACTION_TRANSPORT_BOARD] =
1344 unit_action_new(ACTION_TRANSPORT_BOARD, ACTRES_TRANSPORT_BOARD,
1345 TRUE, FALSE,
1346 MAK_STAYS, 0, 0, FALSE);
1347 actions[ACTION_TRANSPORT_UNLOAD] =
1348 unit_action_new(ACTION_TRANSPORT_UNLOAD, ACTRES_TRANSPORT_UNLOAD,
1349 TRUE, FALSE,
1350 MAK_STAYS, 0, 0, FALSE);
1351 actions[ACTION_TRANSPORT_DISEMBARK1] =
1352 unit_action_new(ACTION_TRANSPORT_DISEMBARK1,
1353 ACTRES_TRANSPORT_DISEMBARK,
1354 FALSE, TRUE,
1355 MAK_REGULAR, 1, 1, FALSE);
1356 actions[ACTION_TRANSPORT_DISEMBARK2] =
1357 unit_action_new(ACTION_TRANSPORT_DISEMBARK2,
1358 ACTRES_TRANSPORT_DISEMBARK,
1359 FALSE, TRUE,
1360 MAK_REGULAR, 1, 1, FALSE);
1361 actions[ACTION_TRANSPORT_DISEMBARK3] =
1362 unit_action_new(ACTION_TRANSPORT_DISEMBARK3,
1363 ACTRES_TRANSPORT_DISEMBARK,
1364 FALSE, TRUE,
1365 MAK_REGULAR, 1, 1, FALSE);
1366 actions[ACTION_TRANSPORT_DISEMBARK4] =
1367 unit_action_new(ACTION_TRANSPORT_DISEMBARK4,
1368 ACTRES_TRANSPORT_DISEMBARK,
1369 FALSE, TRUE,
1370 MAK_REGULAR, 1, 1, FALSE);
1371 actions[ACTION_TRANSPORT_EMBARK] =
1372 unit_action_new(ACTION_TRANSPORT_EMBARK, ACTRES_TRANSPORT_EMBARK,
1373 TRUE, TRUE,
1374 MAK_REGULAR, 1, 1, FALSE);
1375 actions[ACTION_TRANSPORT_EMBARK2] =
1376 unit_action_new(ACTION_TRANSPORT_EMBARK2, ACTRES_TRANSPORT_EMBARK,
1377 TRUE, TRUE,
1378 MAK_REGULAR, 1, 1, FALSE);
1379 actions[ACTION_TRANSPORT_EMBARK3] =
1380 unit_action_new(ACTION_TRANSPORT_EMBARK3, ACTRES_TRANSPORT_EMBARK,
1381 TRUE, TRUE,
1382 MAK_REGULAR, 1, 1, FALSE);
1383 actions[ACTION_SPY_ATTACK] =
1384 unit_action_new(ACTION_SPY_ATTACK, ACTRES_SPY_ATTACK,
1385 FALSE, TRUE,
1386 MAK_STAYS, 1, 1, FALSE);
1387 actions[ACTION_HUT_ENTER] =
1388 unit_action_new(ACTION_HUT_ENTER, ACTRES_HUT_ENTER,
1389 FALSE, TRUE,
1390 MAK_REGULAR, 1, 1, FALSE);
1391 actions[ACTION_HUT_ENTER2] =
1392 unit_action_new(ACTION_HUT_ENTER2, ACTRES_HUT_ENTER,
1393 FALSE, TRUE,
1394 MAK_REGULAR, 1, 1, FALSE);
1395 actions[ACTION_HUT_ENTER3] =
1396 unit_action_new(ACTION_HUT_ENTER3, ACTRES_HUT_ENTER,
1397 FALSE, TRUE,
1398 MAK_REGULAR, 1, 1, FALSE);
1399 actions[ACTION_HUT_ENTER4] =
1400 unit_action_new(ACTION_HUT_ENTER4, ACTRES_HUT_ENTER,
1401 FALSE, TRUE,
1402 MAK_REGULAR, 1, 1, FALSE);
1403 actions[ACTION_HUT_FRIGHTEN] =
1404 unit_action_new(ACTION_HUT_FRIGHTEN, ACTRES_HUT_FRIGHTEN,
1405 FALSE, TRUE,
1406 MAK_REGULAR, 1, 1, FALSE);
1407 actions[ACTION_HUT_FRIGHTEN2] =
1408 unit_action_new(ACTION_HUT_FRIGHTEN2, ACTRES_HUT_FRIGHTEN,
1409 FALSE, TRUE,
1410 MAK_REGULAR, 1, 1, FALSE);
1411 actions[ACTION_HUT_FRIGHTEN3] =
1412 unit_action_new(ACTION_HUT_FRIGHTEN3, ACTRES_HUT_FRIGHTEN,
1413 FALSE, TRUE,
1414 MAK_REGULAR, 1, 1, FALSE);
1415 actions[ACTION_HUT_FRIGHTEN4] =
1416 unit_action_new(ACTION_HUT_FRIGHTEN4, ACTRES_HUT_FRIGHTEN,
1417 FALSE, TRUE,
1418 MAK_REGULAR, 1, 1, FALSE);
1419 actions[ACTION_UNIT_MOVE] =
1420 unit_action_new(ACTION_UNIT_MOVE, ACTRES_UNIT_MOVE,
1421 TRUE, TRUE,
1422 MAK_REGULAR, 1, 1, FALSE);
1423 actions[ACTION_UNIT_MOVE2] =
1424 unit_action_new(ACTION_UNIT_MOVE2, ACTRES_UNIT_MOVE,
1425 TRUE, TRUE,
1426 MAK_REGULAR, 1, 1, FALSE);
1427 actions[ACTION_UNIT_MOVE3] =
1428 unit_action_new(ACTION_UNIT_MOVE3, ACTRES_UNIT_MOVE,
1429 TRUE, TRUE,
1430 MAK_REGULAR, 1, 1, FALSE);
1431 actions[ACTION_USER_ACTION1] =
1432 unit_action_new(ACTION_USER_ACTION1, ACTRES_NONE,
1433 FALSE, TRUE,
1434 MAK_UNREPRESENTABLE,
1435 /* Overwritten by the ruleset */
1436 0, 1, FALSE);
1437 actions[ACTION_USER_ACTION2] =
1438 unit_action_new(ACTION_USER_ACTION2, ACTRES_NONE,
1439 FALSE, TRUE,
1440 MAK_UNREPRESENTABLE,
1441 /* Overwritten by the ruleset */
1442 0, 1, FALSE);
1443 actions[ACTION_USER_ACTION3] =
1444 unit_action_new(ACTION_USER_ACTION3, ACTRES_NONE,
1445 FALSE, TRUE,
1446 MAK_UNREPRESENTABLE,
1447 /* Overwritten by the ruleset */
1448 0, 1, FALSE);
1449 actions[ACTION_USER_ACTION4] =
1450 unit_action_new(ACTION_USER_ACTION4, ACTRES_NONE,
1451 FALSE, TRUE,
1452 MAK_UNREPRESENTABLE,
1453 /* Overwritten by the ruleset */
1454 0, 1, FALSE);
1455}
1456
1457/**********************************************************************/
1460 void actions_init(void)
1461{
1462 int i, j;
1463
1464 for (i = 0; i < ACTRES_LAST; i++) {
1465 actlist_by_result[i] = action_list_new();
1466 }
1467 for (i = 0; i < ACTIVITY_LAST; i++) {
1468 actlist_by_activity[i] = action_list_new();
1469 }
1470
1471 /* Hard code the actions */
1472 hard_code_actions();
1473
1474 /* Initialize the action enabler list */
1475 action_iterate(act) {
1476 action_enablers_by_action[act] = action_enabler_list_new();
1477 } action_iterate_end;
1478
1479 /* Initialize action obligatory hard requirements. */
1480
1481 /* Obligatory hard requirements sorted by action result in memory. */
1482 for (i = 0; i < ACTRES_NONE; i++) {
1483 /* Prepare each action result's storage area. */
1484 obligatory_req_vector_init(&oblig_hard_reqs_r[i]);
1485 }
1486
1487 /* Obligatory hard requirements sorted by action sub result in memory. */
1488 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
1489 /* Prepare each action sub result's storage area. */
1490 obligatory_req_vector_init(&oblig_hard_reqs_sr[i]);
1491 }
1492
1493 /* Obligatory hard requirements are sorted by requirement in the source
1494 * code. This makes it easy to read, modify and explain it. */
1495 hard_code_oblig_hard_reqs();
1496
1497 /* Initialize the action auto performers. */
1498 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
1499 /* Nothing here. Nothing after this point. */
1500 auto_perfs[i].cause = AAPC_COUNT;
1501
1502 /* The criteria to pick *this* auto performer for its cause. */
1503 requirement_vector_init(&auto_perfs[i].reqs);
1504
1505 for (j = 0; j < MAX_NUM_ACTIONS; j++) {
1506 /* Nothing here. Nothing after this point. */
1507 auto_perfs[i].alternatives[j] = ACTION_NONE;
1508 }
1509 }
1510
1511 /* The actions them self are now initialized. */
1512 actions_initialized = TRUE;
1513}
1514
1515/**********************************************************************/
1520 void actions_rs_pre_san_gen(void)
1521{
1522 /* Some obligatory hard requirements needs access to the rest of the
1523 * ruleset. */
1524 hard_code_oblig_hard_reqs_ruleset();
1525}
1526
1527/**********************************************************************/
1530 void actions_free(void)
1531{
1532 int i;
1533
1534 /* Don't consider the actions to be initialized any longer. */
1535 actions_initialized = FALSE;
1536
1537 action_iterate(act) {
1538 action_enabler_list_iterate(action_enablers_by_action[act], enabler) {
1539 action_enabler_free(enabler);
1540 } action_enabler_list_iterate_end;
1541
1542 action_enabler_list_destroy(action_enablers_by_action[act]);
1543
1544 FC_FREE(actions[act]);
1545 } action_iterate_end;
1546
1547 /* Free the obligatory hard action requirements. */
1548 for (i = 0; i < ACTRES_NONE; i++) {
1549 obligatory_req_vector_iterate(&oblig_hard_reqs_r[i], oreq) {
1550 ae_contra_close(oreq->contras);
1551 } obligatory_req_vector_iterate_end;
1552 obligatory_req_vector_free(&oblig_hard_reqs_r[i]);
1553 }
1554 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
1555 obligatory_req_vector_iterate(&oblig_hard_reqs_sr[i], oreq) {
1556 ae_contra_close(oreq->contras);
1557 } obligatory_req_vector_iterate_end;
1558 obligatory_req_vector_free(&oblig_hard_reqs_sr[i]);
1559 }
1560
1561 /* Free the action auto performers. */
1562 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
1563 requirement_vector_free(&auto_perfs[i].reqs);
1564 }
1565
1566 astr_free(&ui_name_str);
1567
1568 for (i = 0; i < ACTRES_LAST; i++) {
1569 action_list_destroy(actlist_by_result[i]);
1570 actlist_by_result[i] = NULL;
1571 }
1572 for (i = 0; i < ACTIVITY_LAST; i++) {
1573 action_list_destroy(actlist_by_activity[i]);
1574 actlist_by_activity[i] = NULL;
1575 }
1576}
1577
1578/**********************************************************************/
1583 bool actions_are_ready(void)
1584{
1585 if (!actions_initialized) {
1586 /* The actions them self aren't initialized yet. */
1587 return FALSE;
1588 }
1589
1590 action_iterate(act) {
1591 if (actions[act]->ui_name[0] == '\0') {
1592 /* An action without a UI name exists means that the ruleset haven't
1593 * loaded yet. The ruleset loading will assign a default name to
1594 * any actions not named by the ruleset. The client will get this
1595 * name from the server. */
1596 return FALSE;
1597 }
1598 } action_iterate_end;
1599
1600 /* The actions should be ready for use. */
1601 return TRUE;
1602}
1603
1604/**********************************************************************/
1607 static struct action *action_new(action_id id,
1608 enum action_result result,
1609 const int min_distance,
1610 const int max_distance,
1611 bool actor_consuming_always)
1612{
1613 struct action *action;
1614
1615 action = fc_malloc(sizeof(*action));
1616
1617 action->id = id;
1618
1619 action->result = result;
1620
1621 if (result != ACTRES_LAST) {
1622 enum unit_activity act = actres_get_activity(result);
1623
1624 action_list_append(actlist_by_result[result], action);
1625
1626 if (act != ACTIVITY_LAST) {
1627 action_list_append(actlist_by_activity[act], action);
1628 }
1629 }
1630
1631 /* Not set here */
1632 BV_CLR_ALL(action->sub_results);
1633
1634 action->actor_kind = AAK_UNIT;
1635 action->target_kind = action_target_kind_default(result);
1636 action->sub_target_kind = action_sub_target_kind_default(result);
1637 action->target_complexity
1638 = action_target_compl_calc(result, action->target_kind,
1639 action->sub_target_kind);
1640
1641 /* ASTK_NONE implies ACT_TGT_COMPL_SIMPLE and
1642 * !ASTK_NONE implies !ACT_TGT_COMPL_SIMPLE */
1643 fc_assert_msg(((action->sub_target_kind == ASTK_NONE
1644 && action->target_complexity == ACT_TGT_COMPL_SIMPLE)
1645 || (action->sub_target_kind != ASTK_NONE
1646 && action->target_complexity != ACT_TGT_COMPL_SIMPLE)),
1647 "%s contradicts itself regarding sub targets.",
1648 action_rule_name(action));
1649
1650 /* The distance between the actor and itself is always 0. */
1651 fc_assert(action->target_kind != ATK_SELF
1652 || (min_distance == 0 && max_distance == 0));
1653
1654 action->min_distance = min_distance;
1655 action->max_distance = max_distance;
1656
1657 action->actor_consuming_always = actor_consuming_always;
1658
1659 /* Loaded from the ruleset. Until generalized actions are ready it has to
1660 * be defined separately from other action data. */
1661 action->ui_name[0] = '\0';
1662 action->quiet = FALSE;
1663 BV_CLR_ALL(action->blocked_by);
1664
1665 return action;
1666}
1667
1668/**********************************************************************/
1671static struct action *
1672unit_action_new(action_id id,
1673 enum action_result result,
1674 bool rare_pop_up,
1675 bool unitwaittime_controlled,
1676 enum moves_actor_kind moves_actor,
1677 const int min_distance,
1678 const int max_distance,
1679 bool actor_consuming_always)
1680{
1681 struct action *act = action_new(id, result,
1682 min_distance, max_distance,
1683 actor_consuming_always);
1684
1685 act->actor.is_unit.rare_pop_up = rare_pop_up;
1686
1687 act->actor.is_unit.unitwaittime_controlled = unitwaittime_controlled;
1688
1689 act->actor.is_unit.moves_actor = moves_actor;
1690
1691 return act;
1692}
1693
1694/**********************************************************************/
1697 bool action_id_exists(const action_id act_id)
1698{
1699 /* Actions are still hard coded. */
1700 return gen_action_is_valid(act_id) && actions[act_id];
1701}
1702
1703/**********************************************************************/
1708 struct action *action_by_rule_name(const char *name)
1709{
1710 /* Actions are still hard coded in the gen_action enum. */
1711 action_id act_id;
1712 const char *current_name = gen_action_name_update_cb(name);
1713
1714 act_id = gen_action_by_name(current_name, fc_strcasecmp);
1715
1716 if (!action_id_exists(act_id)) {
1717 /* Nothing to return. */
1718
1719 log_verbose("Asked for non existing action named %s", name);
1720
1721 return NULL;
1722 }
1723
1724 return action_by_number(act_id);
1725}
1726
1727/**********************************************************************/
1730 enum action_actor_kind action_get_actor_kind(const struct action *paction)
1731{
1732 fc_assert_ret_val_msg(paction, AAK_COUNT, "Action doesn't exist.");
1733
1734 return paction->actor_kind;
1735}
1736
1737/**********************************************************************/
1740 enum action_target_kind action_get_target_kind(
1741 const struct action *paction)
1742{
1743 fc_assert_ret_val_msg(paction, ATK_COUNT, "Action doesn't exist.");
1744
1745 return paction->target_kind;
1746}
1747
1748/**********************************************************************/
1751 enum action_sub_target_kind action_get_sub_target_kind(
1752 const struct action *paction)
1753{
1754 fc_assert_ret_val_msg(paction, ASTK_COUNT, "Action doesn't exist.");
1755
1756 return paction->sub_target_kind;
1757}
1758
1759/**********************************************************************/
1762 enum action_battle_kind action_get_battle_kind(const struct action *pact)
1763{
1764 switch (pact->result) {
1765 case ACTRES_ATTACK:
1766 return ABK_STANDARD;
1767 case ACTRES_SPY_ATTACK:
1768 case ACTRES_SPY_POISON:
1769 case ACTRES_SPY_STEAL_GOLD:
1770 case ACTRES_SPY_SABOTAGE_CITY:
1771 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
1772 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
1773 case ACTRES_SPY_STEAL_TECH:
1774 case ACTRES_SPY_TARGETED_STEAL_TECH:
1775 case ACTRES_SPY_INCITE_CITY:
1776 case ACTRES_SPY_BRIBE_UNIT:
1777 case ACTRES_SPY_SABOTAGE_UNIT:
1778 case ACTRES_STEAL_MAPS:
1779 case ACTRES_SPY_NUKE:
1780 case ACTRES_SPY_SPREAD_PLAGUE:
1781 return ABK_DIPLOMATIC;
1782 default:
1783 return ABK_NONE;
1784 }
1785}
1786
1787/**********************************************************************/
1792 bool action_has_complex_target(const struct action *paction)
1793{
1794 fc_assert_ret_val(paction != NULL, FALSE);
1795
1796 return paction->target_complexity >= ACT_TGT_COMPL_FLEXIBLE;
1797}
1798
1799/**********************************************************************/
1805 bool action_requires_details(const struct action *paction)
1806{
1807 fc_assert_ret_val(paction != NULL, FALSE);
1808
1809 return paction->target_complexity >= ACT_TGT_COMPL_MANDATORY;
1810}
1811
1812/**********************************************************************/
1820 bool action_id_is_rare_pop_up(action_id act_id)
1821{
1822 fc_assert_ret_val_msg((action_id_exists(act_id)),
1823 FALSE, "Action %d don't exist.", act_id);
1824 fc_assert_ret_val(action_id_get_actor_kind(act_id) == AAK_UNIT, FALSE);
1825
1826 return actions[act_id]->actor.is_unit.rare_pop_up;
1827}
1828
1829/**********************************************************************/
1833 bool action_distance_inside_max(const struct action *action,
1834 const int distance)
1835{
1836 return (distance <= action->max_distance
1837 || action->max_distance == ACTION_DISTANCE_UNLIMITED);
1838}
1839
1840/**********************************************************************/
1844 bool action_distance_accepted(const struct action *action,
1845 const int distance)
1846{
1847 fc_assert_ret_val(action, FALSE);
1848
1849 return (distance >= action->min_distance
1850 && action_distance_inside_max(action, distance));
1851}
1852
1853/**********************************************************************/
1856 bool action_would_be_blocked_by(const struct action *blocked,
1857 const struct action *blocker)
1858{
1859 fc_assert_ret_val(blocked, FALSE);
1860 fc_assert_ret_val(blocker, FALSE);
1861
1862 return BV_ISSET(blocked->blocked_by, action_number(blocker));
1863}
1864
1865/**********************************************************************/
1868 int action_number(const struct action *action)
1869{
1870 return action->id;
1871}
1872
1873/**********************************************************************/
1876 const char *action_rule_name(const struct action *action)
1877{
1878 /* Rule name is still hard coded. */
1879 return action_id_rule_name(action->id);
1880}
1881
1882/**********************************************************************/
1890 const char *action_name_translation(const struct action *action)
1891{
1892 /* Use action_id_name_translation() to format the UI name. */
1893 return action_id_name_translation(action->id);
1894}
1895
1896/**********************************************************************/
1899 const char *action_id_rule_name(action_id act_id)
1900{
1901 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
1902
1903 return gen_action_name(act_id);
1904}
1905
1906/**********************************************************************/
1910 const char *action_id_name_translation(action_id act_id)
1911{
1912 return action_prepare_ui_name(act_id, "", ACTPROB_NA, NULL);
1913}
1914
1915/**********************************************************************/
1918 const char *action_get_ui_name_mnemonic(action_id act_id,
1919 const char *mnemonic)
1920{
1921 return action_prepare_ui_name(act_id, mnemonic, ACTPROB_NA, NULL);
1922}
1923
1924/**********************************************************************/
1931 static const char *action_prob_to_text(const struct act_prob prob)
1932{
1933 static struct astring chance = ASTRING_INIT;
1934
1935 /* How to interpret action probabilities like prob is documented in
1936 * fc_types.h */
1937 if (action_prob_is_signal(prob)) {
1938 fc_assert(action_prob_not_impl(prob)
1939 || action_prob_not_relevant(prob));
1940
1941 /* Unknown because of missing server support or should not exits. */
1942 return NULL;
1943 }
1944
1945 if (prob.min == prob.max) {
1946 /* Only one probability in range. */
1947
1948 /* TRANS: the probability that an action will succeed. Given in
1949 * percentage. Resolution is 0.5%. */
1950 astr_set(&chance, _("%.1f%%"), (double)prob.max / ACTPROB_VAL_1_PCT);
1951 } else {
1952 /* TRANS: the interval (end points included) where the probability of
1953 * the action's success is. Given in percentage. Resolution is 0.5%. */
1954 astr_set(&chance, _("[%.1f%%, %.1f%%]"),
1955 (double)prob.min / ACTPROB_VAL_1_PCT,
1956 (double)prob.max / ACTPROB_VAL_1_PCT);
1957 }
1958
1959 return astr_str(&chance);
1960}
1961
1962/**********************************************************************/
1972 const char *action_prepare_ui_name(action_id act_id, const char *mnemonic,
1973 const struct act_prob prob,
1974 const char *custom)
1975{
1976 struct astring chance = ASTRING_INIT;
1977
1978 /* Text representation of the probability. */
1979 const char *probtxt;
1980
1981 if (!actions_are_ready()) {
1982 /* Could be a client who haven't gotten the ruleset yet */
1983
1984 /* so there shouldn't be any action probability to show */
1985 fc_assert(action_prob_not_relevant(prob));
1986
1987 /* but the action should be valid */
1988 fc_assert_ret_val_msg(action_id_exists(act_id),
1989 "Invalid action",
1990 "Invalid action %d", act_id);
1991
1992 /* and no custom text will be inserted */
1993 fc_assert(custom == NULL || custom[0] == '\0');
1994
1995 /* Make the best of what is known */
1996 astr_set(&ui_name_str, _("%s%s (name may be wrong)"),
1997 mnemonic, action_id_rule_name(act_id));
1998
1999 /* Return the guess. */
2000 return astr_str(&ui_name_str);
2001 }
2002
2003 probtxt = action_prob_to_text(prob);
2004
2005 /* Format the info part of the action's UI name. */
2006 if (probtxt != NULL && custom != NULL) {
2007 /* TRANS: action UI name's info part with custom info and probability.
2008 * Hint: you can move the paren handling from this sting to the action
2009 * names if you need to add extra information (like a mnemonic letter
2010 * that doesn't appear in the action UI name) to it. In that case you
2011 * must do so for all strings with this comment and for every action
2012 * name. To avoid a `()` when no UI name info part is added you have
2013 * to add the extra information to every action name or remove the
2014 * surrounding parens. */
2015 astr_set(&chance, _(" (%s; %s)"), custom, probtxt);
2016 } else if (probtxt != NULL) {
2017 /* TRANS: action UI name's info part with probability.
2018 * Hint: you can move the paren handling from this sting to the action
2019 * names if you need to add extra information (like a mnemonic letter
2020 * that doesn't appear in the action UI name) to it. In that case you
2021 * must do so for all strings with this comment and for every action
2022 * name. To avoid a `()` when no UI name info part is added you have
2023 * to add the extra information to every action name or remove the
2024 * surrounding parens. */
2025 astr_set(&chance, _(" (%s)"), probtxt);
2026 } else if (custom != NULL) {
2027 /* TRANS: action UI name's info part with custom info.
2028 * Hint: you can move the paren handling from this sting to the action
2029 * names if you need to add extra information (like a mnemonic letter
2030 * that doesn't appear in the action UI name) to it. In that case you
2031 * must do so for all strings with this comment and for every action
2032 * name. To avoid a `()` when no UI name info part is added you have
2033 * to add the extra information to every action name or remove the
2034 * surrounding parens. */
2035 astr_set(&chance, _(" (%s)"), custom);
2036 } else {
2037 /* No info part to display. */
2038 astr_clear(&chance);
2039 }
2040
2041 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
2042
2043 /* Escape any instances of the mnemonic in the action's UI format string.
2044 * (Assumes any mnemonic can be escaped by doubling, and that they are
2045 * unlikely to appear in a format specifier. True for clients seen so
2046 * far: Gtk's _ and Qt's &) */
2047 {
2048 struct astring fmtstr = ASTRING_INIT;
2049 const char *ui_name = _(actions[act_id]->ui_name);
2050
2051 if (mnemonic[0] != '\0') {
2052 const char *hit;
2053
2054 fc_assert(!strchr(mnemonic, '%'));
2055 while ((hit = strstr(ui_name, mnemonic))) {
2056 astr_add(&fmtstr, "%.*s%s%s", (int)(hit - ui_name), ui_name,
2057 mnemonic, mnemonic);
2058 ui_name = hit + strlen(mnemonic);
2059 }
2060 }
2061 astr_add(&fmtstr, "%s", ui_name);
2062
2063 /* Use the modified format string */
2064 astr_set(&ui_name_str, astr_str(&fmtstr), mnemonic,
2065 astr_str(&chance));
2066
2067 astr_free(&fmtstr);
2068 }
2069
2070 astr_free(&chance);
2071
2072 return astr_str(&ui_name_str);
2073}
2074
2075/**********************************************************************/
2083 const char *action_prob_explain(const struct act_prob prob)
2084{
2085 static struct astring tool_tip = ASTRING_INIT;
2086
2087 if (action_prob_is_signal(prob)) {
2088 fc_assert(action_prob_not_impl(prob));
2089
2090 /* Missing server support. No in game action will change this. */
2091 astr_clear(&tool_tip);
2092 } else if (prob.min == prob.max) {
2093 /* TRANS: action probability of success. Given in percentage.
2094 * Resolution is 0.5%. */
2095 astr_set(&tool_tip, _("The probability of success is %.1f%%."),
2096 (double)prob.max / ACTPROB_VAL_1_PCT);
2097 } else {
2098 astr_set(&tool_tip,
2099 /* TRANS: action probability interval (min to max). Given in
2100 * percentage. Resolution is 0.5%. The string at the end is
2101 * shown when the interval is wide enough to not be caused by
2102 * rounding. It explains that the interval is imprecise because
2103 * the player doesn't have enough information. */
2104 _("The probability of success is %.1f%%, %.1f%% or somewhere"
2105 " in between.%s"),
2106 (double)prob.min / ACTPROB_VAL_1_PCT,
2107 (double)prob.max / ACTPROB_VAL_1_PCT,
2108 prob.max - prob.min > 1 ?
2109 /* TRANS: explanation used in the action probability tooltip
2110 * above. Preserve leading space. */
2111 _(" (This is the most precise interval I can calculate "
2112 "given the information our nation has access to.)") :
2113 "");
2114 }
2115
2116 return astr_str(&tool_tip);
2117}
2118
2119/**********************************************************************/
2123 int action_get_role(const struct action *paction)
2124{
2125 fc_assert_msg(AAK_UNIT == action_get_actor_kind(paction),
2126 "Action %s isn't performed by a unit",
2127 action_rule_name(paction));
2128
2129 return paction->id + L_LAST;
2130}
2131
2132/**********************************************************************/
2136 enum unit_activity actres_get_activity(enum action_result result)
2137{
2138 if (result == ACTRES_FORTIFY) {
2139 return ACTIVITY_FORTIFYING;
2140 } else if (result == ACTRES_BASE) {
2141 return ACTIVITY_BASE;
2142 } else if (result == ACTRES_ROAD) {
2143 return ACTIVITY_GEN_ROAD;
2144 } else if (result == ACTRES_PILLAGE) {
2145 return ACTIVITY_PILLAGE;
2146 } else if (result == ACTRES_CLEAN_POLLUTION) {
2147 return ACTIVITY_POLLUTION;
2148 } else if (result == ACTRES_CLEAN_FALLOUT) {
2149 return ACTIVITY_FALLOUT;
2150 } else if (result == ACTRES_TRANSFORM_TERRAIN) {
2151 return ACTIVITY_TRANSFORM;
2152 } else if (result == ACTRES_CONVERT) {
2153 return ACTIVITY_CONVERT;
2154 } else if (result == ACTRES_PLANT) {
2155 return ACTIVITY_PLANT;
2156 } else if (result == ACTRES_MINE) {
2157 return ACTIVITY_MINE;
2158 } else if (result == ACTRES_CULTIVATE) {
2159 return ACTIVITY_CULTIVATE;
2160 } else if (result == ACTRES_IRRIGATE) {
2161 return ACTIVITY_IRRIGATE;
2162 } else {
2163 return ACTIVITY_LAST;
2164 }
2165}
2166
2167/**********************************************************************/
2173 int action_get_act_time(const struct action *paction,
2174 const struct unit *actor_unit,
2175 const struct tile *tgt_tile,
2176 const struct extra_type *tgt_extra)
2177{
2178 enum unit_activity pactivity = actres_get_activity(paction->result);
2179
2180 if (pactivity == ACTIVITY_LAST) {
2181 /* Happens instantaneously, not at turn change. */
2182 return ACT_TIME_INSTANTANEOUS;
2183 }
2184
2185 switch (pactivity) {
2186 case ACTIVITY_PILLAGE:
2187 case ACTIVITY_POLLUTION:
2188 case ACTIVITY_FALLOUT:
2189 case ACTIVITY_BASE:
2190 case ACTIVITY_GEN_ROAD:
2191 case ACTIVITY_IRRIGATE:
2192 case ACTIVITY_MINE:
2193 case ACTIVITY_CULTIVATE:
2194 case ACTIVITY_PLANT:
2195 case ACTIVITY_TRANSFORM:
2196 return tile_activity_time(pactivity, tgt_tile, tgt_extra);
2197 case ACTIVITY_FORTIFYING:
2198 return 1;
2199 case ACTIVITY_CONVERT:
2200 return unit_type_get(actor_unit)->convert_time * ACTIVITY_FACTOR;
2201 case ACTIVITY_EXPLORE:
2202 case ACTIVITY_IDLE:
2203 case ACTIVITY_FORTIFIED:
2204 case ACTIVITY_SENTRY:
2205 case ACTIVITY_GOTO:
2206 case ACTIVITY_UNKNOWN:
2207 case ACTIVITY_PATROL_UNUSED:
2208 case ACTIVITY_LAST:
2209 case ACTIVITY_OLD_ROAD:
2210 case ACTIVITY_OLD_RAILROAD:
2211 case ACTIVITY_FORTRESS:
2212 case ACTIVITY_AIRBASE:
2213 /* Should not happen. Caught by the assertion below. */
2214 break;
2215 }
2216
2217 fc_assert(FALSE);
2218 return ACT_TIME_INSTANTANEOUS;
2219}
2220
2221/**********************************************************************/
2224 bool action_creates_extra(const struct action *paction,
2225 const struct extra_type *pextra)
2226{
2227 fc_assert(paction != NULL);
2228 if (pextra == NULL) {
2229 return FALSE;
2230 }
2231
2232 if (!pextra->buildable) {
2233 return FALSE;
2234 }
2235
2236 switch (paction->result) {
2237 case ACTRES_ROAD:
2238 return is_extra_caused_by(pextra, EC_ROAD);
2239 case ACTRES_BASE:
2240 return is_extra_caused_by(pextra, EC_BASE);
2241 case ACTRES_MINE:
2242 return is_extra_caused_by(pextra, EC_MINE);
2243 case ACTRES_IRRIGATE:
2244 return is_extra_caused_by(pextra, EC_IRRIGATION);
2245 case ACTRES_ESTABLISH_EMBASSY:
2246 case ACTRES_SPY_INVESTIGATE_CITY:
2247 case ACTRES_SPY_POISON:
2248 case ACTRES_SPY_STEAL_GOLD:
2249 case ACTRES_SPY_SABOTAGE_CITY:
2250 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2251 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2252 case ACTRES_SPY_STEAL_TECH:
2253 case ACTRES_SPY_TARGETED_STEAL_TECH:
2254 case ACTRES_SPY_INCITE_CITY:
2255 case ACTRES_TRADE_ROUTE:
2256 case ACTRES_MARKETPLACE:
2257 case ACTRES_HELP_WONDER:
2258 case ACTRES_SPY_BRIBE_UNIT:
2259 case ACTRES_SPY_SABOTAGE_UNIT:
2260 case ACTRES_CAPTURE_UNITS:
2261 case ACTRES_FOUND_CITY:
2262 case ACTRES_JOIN_CITY:
2263 case ACTRES_STEAL_MAPS:
2264 case ACTRES_BOMBARD:
2265 case ACTRES_SPY_NUKE:
2266 case ACTRES_NUKE:
2267 case ACTRES_NUKE_UNITS:
2268 case ACTRES_DESTROY_CITY:
2269 case ACTRES_EXPEL_UNIT:
2270 case ACTRES_DISBAND_UNIT_RECOVER:
2271 case ACTRES_DISBAND_UNIT:
2272 case ACTRES_HOME_CITY:
2273 case ACTRES_HOMELESS:
2274 case ACTRES_UPGRADE_UNIT:
2275 case ACTRES_PARADROP:
2276 case ACTRES_PARADROP_CONQUER:
2277 case ACTRES_AIRLIFT:
2278 case ACTRES_STRIKE_BUILDING:
2279 case ACTRES_STRIKE_PRODUCTION:
2280 case ACTRES_ATTACK:
2281 case ACTRES_CONQUER_CITY:
2282 case ACTRES_CONQUER_EXTRAS:
2283 case ACTRES_HEAL_UNIT:
2284 case ACTRES_TRANSFORM_TERRAIN:
2285 case ACTRES_CULTIVATE:
2286 case ACTRES_PLANT:
2287 case ACTRES_PILLAGE:
2288 case ACTRES_CLEAN_POLLUTION:
2289 case ACTRES_CLEAN_FALLOUT:
2290 case ACTRES_FORTIFY:
2291 case ACTRES_CONVERT:
2292 case ACTRES_TRANSPORT_ALIGHT:
2293 case ACTRES_TRANSPORT_UNLOAD:
2294 case ACTRES_TRANSPORT_DISEMBARK:
2295 case ACTRES_TRANSPORT_BOARD:
2296 case ACTRES_TRANSPORT_EMBARK:
2297 case ACTRES_SPY_ATTACK:
2298 case ACTRES_SPY_SPREAD_PLAGUE:
2299 case ACTRES_HUT_ENTER:
2300 case ACTRES_HUT_FRIGHTEN:
2301 case ACTRES_UNIT_MOVE:
2302 case ACTRES_NONE:
2303 break;
2304 }
2305
2306 return FALSE;
2307}
2308
2309/**********************************************************************/
2312 bool action_removes_extra(const struct action *paction,
2313 const struct extra_type *pextra)
2314{
2315 fc_assert(paction != NULL);
2316 if (pextra == NULL) {
2317 return FALSE;
2318 }
2319
2320 switch (paction->result) {
2321 case ACTRES_PILLAGE:
2322 return is_extra_removed_by(pextra, ERM_PILLAGE);
2323 case ACTRES_CLEAN_POLLUTION:
2324 return is_extra_removed_by(pextra, ERM_CLEANPOLLUTION);
2325 case ACTRES_CLEAN_FALLOUT:
2326 return is_extra_removed_by(pextra, ERM_CLEANFALLOUT);
2327 case ACTRES_HUT_ENTER:
2328 case ACTRES_HUT_FRIGHTEN:
2329 return is_extra_removed_by(pextra, ERM_ENTER);
2330 case ACTRES_ESTABLISH_EMBASSY:
2331 case ACTRES_SPY_INVESTIGATE_CITY:
2332 case ACTRES_SPY_POISON:
2333 case ACTRES_SPY_STEAL_GOLD:
2334 case ACTRES_SPY_SABOTAGE_CITY:
2335 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2336 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2337 case ACTRES_SPY_STEAL_TECH:
2338 case ACTRES_SPY_TARGETED_STEAL_TECH:
2339 case ACTRES_SPY_INCITE_CITY:
2340 case ACTRES_TRADE_ROUTE:
2341 case ACTRES_MARKETPLACE:
2342 case ACTRES_HELP_WONDER:
2343 case ACTRES_SPY_BRIBE_UNIT:
2344 case ACTRES_SPY_SABOTAGE_UNIT:
2345 case ACTRES_CAPTURE_UNITS:
2346 case ACTRES_FOUND_CITY:
2347 case ACTRES_JOIN_CITY:
2348 case ACTRES_STEAL_MAPS:
2349 case ACTRES_BOMBARD:
2350 case ACTRES_SPY_NUKE:
2351 case ACTRES_NUKE:
2352 case ACTRES_NUKE_UNITS:
2353 case ACTRES_DESTROY_CITY:
2354 case ACTRES_EXPEL_UNIT:
2355 case ACTRES_DISBAND_UNIT_RECOVER:
2356 case ACTRES_DISBAND_UNIT:
2357 case ACTRES_HOME_CITY:
2358 case ACTRES_HOMELESS:
2359 case ACTRES_UPGRADE_UNIT:
2360 case ACTRES_PARADROP:
2361 case ACTRES_PARADROP_CONQUER:
2362 case ACTRES_AIRLIFT:
2363 case ACTRES_STRIKE_BUILDING:
2364 case ACTRES_STRIKE_PRODUCTION:
2365 case ACTRES_ATTACK:
2366 case ACTRES_CONQUER_CITY:
2367 case ACTRES_CONQUER_EXTRAS:
2368 case ACTRES_HEAL_UNIT:
2369 case ACTRES_TRANSFORM_TERRAIN:
2370 case ACTRES_CULTIVATE:
2371 case ACTRES_PLANT:
2372 case ACTRES_FORTIFY:
2373 case ACTRES_ROAD:
2374 case ACTRES_CONVERT:
2375 case ACTRES_BASE:
2376 case ACTRES_MINE:
2377 case ACTRES_IRRIGATE:
2378 case ACTRES_TRANSPORT_ALIGHT:
2379 case ACTRES_TRANSPORT_UNLOAD:
2380 case ACTRES_TRANSPORT_DISEMBARK:
2381 case ACTRES_TRANSPORT_BOARD:
2382 case ACTRES_TRANSPORT_EMBARK:
2383 case ACTRES_SPY_ATTACK:
2384 case ACTRES_SPY_SPREAD_PLAGUE:
2385 case ACTRES_UNIT_MOVE:
2386 case ACTRES_NONE:
2387 break;
2388 }
2389
2390 return FALSE;
2391}
2392
2393/**********************************************************************/
2396 struct action_enabler *action_enabler_new(void)
2397{
2398 struct action_enabler *enabler;
2399
2400 enabler = fc_malloc(sizeof(*enabler));
2401 enabler->ruledit_disabled = FALSE;
2402 requirement_vector_init(&enabler->actor_reqs);
2403 requirement_vector_init(&enabler->target_reqs);
2404
2405 /* Make sure that action doesn't end up as a random value that happens to
2406 * be a valid action id. */
2407 enabler->action = ACTION_NONE;
2408
2409 return enabler;
2410}
2411
2412/**********************************************************************/
2415 void action_enabler_free(struct action_enabler *enabler)
2416{
2417 requirement_vector_free(&enabler->actor_reqs);
2418 requirement_vector_free(&enabler->target_reqs);
2419
2420 free(enabler);
2421}
2422
2423/**********************************************************************/
2426struct action_enabler *
2427action_enabler_copy(const struct action_enabler *original)
2428{
2429 struct action_enabler *enabler = action_enabler_new();
2430
2431 enabler->action = original->action;
2432
2433 requirement_vector_copy(&enabler->actor_reqs, &original->actor_reqs);
2434 requirement_vector_copy(&enabler->target_reqs, &original->target_reqs);
2435
2436 return enabler;
2437}
2438
2439/**********************************************************************/
2442 void action_enabler_add(struct action_enabler *enabler)
2443{
2444 /* Sanity check: a non existing action enabler can't be added. */
2445 fc_assert_ret(enabler);
2446 /* Sanity check: a non existing action doesn't have enablers. */
2447 fc_assert_ret(action_id_exists(enabler->action));
2448
2449 action_enabler_list_append(
2450 action_enablers_for_action(enabler->action),
2451 enabler);
2452}
2453
2454/**********************************************************************/
2459 bool action_enabler_remove(struct action_enabler *enabler)
2460{
2461 /* Sanity check: a non existing action enabler can't be removed. */
2462 fc_assert_ret_val(enabler, FALSE);
2463 /* Sanity check: a non existing action doesn't have enablers. */
2464 fc_assert_ret_val(action_id_exists(enabler->action), FALSE);
2465
2466 return action_enabler_list_remove(
2467 action_enablers_for_action(enabler->action),
2468 enabler);
2469}
2470
2471/**********************************************************************/
2474struct action_enabler_list *
2475action_enablers_for_action(action_id action)
2476{
2477 /* Sanity check: a non existing action doesn't have enablers. */
2478 fc_assert_ret_val(action_id_exists(action), NULL);
2479
2480 return action_enablers_by_action[action];
2481}
2482
2483/**********************************************************************/
2493static struct req_vec_problem *
2494ae_suggest_repair_if_no_oblig(const struct action_enabler *enabler,
2495 const struct obligatory_req_vector *oblig)
2496{
2497 struct action *paction;
2498
2499 /* Sanity check: a non existing action enabler is missing but it doesn't
2500 * miss any obligatory hard requirements. */
2501 fc_assert_ret_val(enabler, NULL);
2502
2503 /* Sanity check: a non existing action doesn't have any obligatory hard
2504 * requirements. */
2505 fc_assert_ret_val(action_id_exists(enabler->action), NULL);
2506 paction = action_by_number(enabler->action);
2507
2508 /* No obligatory hard requirements. */
2509 fc_assert_ret_val(oblig, NULL);
2510
2511 obligatory_req_vector_iterate(oblig, obreq) {
2512 struct req_vec_problem *out;
2513 int i;
2514 bool fulfilled = FALSE;
2515
2516 /* Check each alternative. */
2517 for (i = 0; i < obreq->contras->alternatives; i++) {
2518 const struct requirement_vector *ae_vec;
2519
2520 /* Select action enabler requirement vector. */
2521 ae_vec = (obreq->contras->alternative[i].is_target
2522 ? &enabler->target_reqs
2523 : &enabler->actor_reqs);
2524
2525 if (does_req_contradicts_reqs(&obreq->contras->alternative[i].req,
2526 ae_vec)
2527 /* Consider the hard requirement fulfilled since a universal that
2528 * never is there always will be absent in this ruleset. */
2529 || (obreq->contras->alternative[i].req.present
2530 && universal_never_there(
2531 &obreq->contras->alternative[i].req.source))) {
2532 /* It is enough that one alternative accepts the enabler. */
2533 fulfilled = TRUE;
2534 break;
2535 }
2536
2537 /* Fall back to the next alternative */
2538 }
2539
2540 if (fulfilled) {
2541 /* This obligatory hard requirement isn't a problem. */
2542 continue;
2543 }
2544
2545 /* Missing hard obligatory requirement detected */
2546
2547 out = req_vec_problem_new(obreq->contras->alternatives,
2548 obreq->error_msg,
2549 action_rule_name(paction));
2550
2551 for (i = 0; i < obreq->contras->alternatives; i++) {
2552 const struct requirement_vector *ae_vec;
2553
2554 /* Select action enabler requirement vector. */
2555 ae_vec = (obreq->contras->alternative[i].is_target
2556 ? &enabler->target_reqs
2557 : &enabler->actor_reqs);
2558
2559 /* The suggested fix is to append a requirement that makes the enabler
2560 * contradict the missing hard obligatory requirement detector. */
2561 out->suggested_solutions[i].operation = RVCO_APPEND;
2562 out->suggested_solutions[i].vector_number
2563 = action_enabler_vector_number(enabler, ae_vec);
2564
2565 /* Change the requirement from what should conflict to what is
2566 * wanted. */
2567 out->suggested_solutions[i].req.present
2568 = !obreq->contras->alternative[i].req.present;
2569 out->suggested_solutions[i].req.source
2570 = obreq->contras->alternative[i].req.source;
2571 out->suggested_solutions[i].req.range
2572 = obreq->contras->alternative[i].req.range;
2573 out->suggested_solutions[i].req.survives
2574 = obreq->contras->alternative[i].req.survives;
2575 out->suggested_solutions[i].req.quiet
2576 = obreq->contras->alternative[i].req.quiet;
2577 }
2578
2579 /* Return the first problem found. The next problem will be detected
2580 * during the next call. */
2581 return out;
2582 } obligatory_req_vector_iterate_end;
2583
2584 /* No obligatory req problems found. */
2585 return NULL;
2586}
2587
2588/**********************************************************************/
2597struct req_vec_problem *
2598action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
2599{
2600 struct action *paction;
2601 enum action_sub_result sub_res;
2602 struct req_vec_problem *out;
2603
2604 /* Sanity check: a non existing action enabler is missing but it doesn't
2605 * miss any obligatory hard requirements. */
2606 fc_assert_ret_val(enabler, NULL);
2607
2608 /* Sanity check: a non existing action doesn't have any obligatory hard
2609 * requirements. */
2610 fc_assert_ret_val(action_id_exists(enabler->action), NULL);
2611 paction = action_by_number(enabler->action);
2612
2613 if (paction->result != ACTRES_NONE) {
2614 /* A hard coded action result may mean obligatory requirements. */
2615 out = ae_suggest_repair_if_no_oblig(enabler,
2616 &oblig_hard_reqs_r[paction->result]);
2617 if (out != NULL) {
2618 return out;
2619 }
2620 }
2621
2622 for (sub_res = action_sub_result_begin();
2623 sub_res != action_sub_result_end();
2624 sub_res = action_sub_result_next(sub_res)) {
2625 if (!BV_ISSET(paction->sub_results, sub_res)) {
2626 /* Not relevant */
2627 continue;
2628 }
2629
2630 /* The action has this sub result. Check its hard requirements. */
2631 out = ae_suggest_repair_if_no_oblig(enabler,
2632 &oblig_hard_reqs_sr[sub_res]);
2633 if (out != NULL) {
2634 return out;
2635 }
2636 }
2637
2638 /* No obligatory req problems found. */
2639 return NULL;
2640}
2641
2642/**********************************************************************/
2648static struct requirement *
2649req_vec_first_local_diplrel(const struct requirement_vector *vec)
2650{
2651 requirement_vector_iterate(vec, preq) {
2652 if (preq->source.kind == VUT_DIPLREL
2653 && preq->range == REQ_RANGE_LOCAL) {
2654 return preq;
2655 }
2656 } requirement_vector_iterate_end;
2657
2658 return NULL;
2659}
2660
2661/**********************************************************************/
2669static struct requirement *
2670req_vec_first_contradiction_in_vec(const struct requirement *req,
2671 const struct requirement_vector *vec)
2672{
2673 /* If the requirement is contradicted by any requirement in the vector it
2674 * contradicts the entire requirement vector. */
2675 requirement_vector_iterate(vec, preq) {
2676 if (are_requirements_contradictions(req, preq)) {
2677 return preq;
2678 }
2679 } requirement_vector_iterate_end;
2680
2681 /* Not a singe requirement in the requirement vector is contradicted be
2682 * the specified requirement. */
2683 return NULL;
2684}
2685
2686/**********************************************************************/
2692static struct req_vec_problem *
2693enabler_tile_tgt_local_diplrel_implies_claimed(
2694 const struct action_enabler *enabler)
2695{
2696 struct req_vec_problem *out;
2697 struct requirement *local_diplrel;
2698 struct requirement *claimed_req;
2699 struct requirement tile_is_claimed;
2700 struct requirement tile_is_unclaimed;
2701 struct action *paction = action_by_number(enabler->action);
2702 struct astring astr;
2703
2704 if (action_get_target_kind(paction) != ATK_TILE) {
2705 /* Not tile targeted */
2706 return NULL;
2707 }
2708
2709 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
2710 if (local_diplrel == NULL) {
2711 /* No local diplrel */
2712 return NULL;
2713 }
2714
2715 /* Tile is unclaimed as a requirement. */
2716 tile_is_unclaimed.range = REQ_RANGE_LOCAL;
2717 tile_is_unclaimed.survives = FALSE;
2718 tile_is_unclaimed.source.kind = VUT_CITYTILE;
2719 tile_is_unclaimed.present = FALSE;
2720 tile_is_unclaimed.source.value.citytile = CITYT_CLAIMED;
2721
2722 claimed_req = req_vec_first_contradiction_in_vec(&tile_is_unclaimed,
2723 &enabler->target_reqs);
2724
2725 if (claimed_req) {
2726 /* Already clear */
2727 return NULL;
2728 }
2729
2730 /* Tile is claimed as a requirement. */
2731 tile_is_claimed.range = REQ_RANGE_LOCAL;
2732 tile_is_claimed.survives = FALSE;
2733 tile_is_claimed.source.kind = VUT_CITYTILE;
2734 tile_is_claimed.present = TRUE;
2735 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
2736
2737 out = req_vec_problem_new(
2738 1,
2739 /* TRANS: ruledit shows this when an enabler for a tile targeted
2740 * action requires that the actor has a diplomatic relationship to
2741 * the target but doesn't require that the target tile is claimed.
2742 * (DiplRel requirements to an unclaimed tile are never fulfilled
2743 * so this is implicit.) */
2744 N_("Requirement {%s} of action \"%s\" implies a claimed "
2745 "tile. No diplomatic relation to Nature."),
2746 req_to_fstring(local_diplrel, &astr), action_rule_name(paction));
2747
2748 astr_free(&astr);
2749
2750 /* The solution is to add the requirement that the tile is claimed */
2751 out->suggested_solutions[0].req = tile_is_claimed;
2752 out->suggested_solutions[0].vector_number
2753 = action_enabler_vector_number(enabler, &enabler->target_reqs);
2754 out->suggested_solutions[0].operation = RVCO_APPEND;
2755
2756 return out;
2757}
2758
2759/**********************************************************************/
2765static struct req_vec_problem *
2766enabler_first_self_contradiction(const struct action_enabler *enabler)
2767{
2768 struct req_vec_problem *out;
2769 struct requirement *local_diplrel;
2770 struct requirement *unclaimed_req;
2771 struct requirement tile_is_claimed;
2772 struct action *paction = action_by_number(enabler->action);
2773 struct astring astr1;
2774 struct astring astr2;
2775
2776 if (action_get_target_kind(paction) != ATK_TILE) {
2777 /* Not tile targeted */
2778 return NULL;
2779 }
2780
2781 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
2782 if (local_diplrel == NULL) {
2783 /* No local diplrel */
2784 return NULL;
2785 }
2786
2787 /* Tile is claimed as a requirement. */
2788 tile_is_claimed.range = REQ_RANGE_LOCAL;
2789 tile_is_claimed.survives = FALSE;
2790 tile_is_claimed.source.kind = VUT_CITYTILE;
2791 tile_is_claimed.present = TRUE;
2792 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
2793
2794 unclaimed_req = req_vec_first_contradiction_in_vec(&tile_is_claimed,
2795 &enabler->target_reqs);
2796
2797 if (unclaimed_req == NULL) {
2798 /* No unclaimed req */
2799 return NULL;
2800 }
2801
2802 out = req_vec_problem_new(
2803 2,
2804 /* TRANS: ruledit shows this when an enabler for a tile targeted
2805 * action requires that the target tile is unclaimed and that the
2806 * actor has a diplomatic relationship to the target. (DiplRel
2807 * requirements to an unclaimed tile are never fulfilled.) */
2808 N_("In enabler for \"%s\": No diplomatic relation to Nature."
2809 " Requirements {%s} and {%s} contradict each other."),
2810 action_rule_name(paction),
2811 req_to_fstring(local_diplrel, &astr1),
2812 req_to_fstring(unclaimed_req, &astr2));
2813
2814 astr_free(&astr1);
2815 astr_free(&astr2);
2816
2817 /* The first suggestion is to remove the diplrel */
2818 out->suggested_solutions[0].req = *local_diplrel;
2819 out->suggested_solutions[0].vector_number
2820 = action_enabler_vector_number(enabler, &enabler->actor_reqs);
2821 out->suggested_solutions[0].operation = RVCO_REMOVE;
2822
2823 /* The 2nd is to remove the requirement that the tile is unclaimed */
2824 out->suggested_solutions[1].req = *unclaimed_req;
2825 out->suggested_solutions[1].vector_number
2826 = action_enabler_vector_number(enabler, &enabler->target_reqs);
2827 out->suggested_solutions[1].operation = RVCO_REMOVE;
2828
2829 return out;
2830}
2831
2832/**********************************************************************/
2837struct req_vec_problem *
2838action_enabler_suggest_repair(const struct action_enabler *enabler)
2839{
2840 struct req_vec_problem *out;
2841
2842 out = action_enabler_suggest_repair_oblig(enabler);
2843 if (out != NULL) {
2844 return out;
2845 }
2846
2847 /* Look for errors in the requirement vectors. */
2848 out = req_vec_suggest_repair(&enabler->actor_reqs,
2849 action_enabler_vector_number,
2850 enabler);
2851 if (out != NULL) {
2852 return out;
2853 }
2854
2855 out = req_vec_suggest_repair(&enabler->target_reqs,
2856 action_enabler_vector_number,
2857 enabler);
2858 if (out != NULL) {
2859 return out;
2860 }
2861
2862 /* Enabler specific contradictions. */
2863 out = enabler_first_self_contradiction(enabler);
2864 if (out != NULL) {
2865 return out;
2866 }
2867
2868 /* Needed in action not enabled explanation finding. */
2869 out = enabler_tile_tgt_local_diplrel_implies_claimed(enabler);
2870 if (out != NULL) {
2871 return out;
2872 }
2873
2874 /* No problems found. */
2875 return NULL;
2876}
2877
2878/**********************************************************************/
2885static struct req_vec_problem *
2886enabler_first_clarification(const struct action_enabler *enabler)
2887{
2888 struct req_vec_problem *out;
2889
2890 out = NULL;
2891
2892 return out;
2893}
2894
2895/**********************************************************************/
2903struct req_vec_problem *
2904action_enabler_suggest_improvement(const struct action_enabler *enabler)
2905{
2906 struct action *paction;
2907 struct req_vec_problem *out;
2908
2909 out = action_enabler_suggest_repair(enabler);
2910 if (out) {
2911 /* A bug, not just a potential improvement */
2912 return out;
2913 }
2914
2915 paction = action_by_number(enabler->action);
2916
2917 /* Look for improvement suggestions to the requirement vectors. */
2918 out = req_vec_suggest_improvement(&enabler->actor_reqs,
2919 action_enabler_vector_number,
2920 enabler);
2921 if (out) {
2922 return out;
2923 }
2924 out = req_vec_suggest_improvement(&enabler->target_reqs,
2925 action_enabler_vector_number,
2926 enabler);
2927 if (out) {
2928 return out;
2929 }
2930
2931 /* Detect unused action enablers. */
2932 if (action_get_actor_kind(paction) == AAK_UNIT) {
2933 bool has_user = FALSE;
2934
2935 unit_type_iterate(pactor) {
2936 if (action_actor_utype_hard_reqs_ok(paction, pactor)
2937 && requirement_fulfilled_by_unit_type(pactor,
2938 &(enabler->actor_reqs))) {
2939 has_user = TRUE;
2940 break;
2941 }
2942 } unit_type_iterate_end;
2943
2944 if (!has_user) {
2945 /* TRANS: ruledit warns a user about an unused action enabler */
2946 out = req_vec_problem_new(0, N_("Action enabler for \"%s\" is never"
2947 " used by any unit."),
2948 action_rule_name(paction));
2949 }
2950 }
2951 if (out != NULL) {
2952 return out;
2953 }
2954
2955 out = enabler_first_clarification(enabler);
2956
2957 return out;
2958}
2959
2960/**********************************************************************/
2967 req_vec_num_in_item
2968action_enabler_vector_number(const void *enabler,
2969 const struct requirement_vector *vec)
2970{
2971 struct action_enabler *ae = (struct action_enabler *)enabler;
2972
2973 if (vec == &ae->actor_reqs) {
2974 return 0;
2975 } else if (vec == &ae->target_reqs) {
2976 return 1;
2977 } else {
2978 return -1;
2979 }
2980}
2981
2982/********************************************************************/
2990struct requirement_vector *
2991action_enabler_vector_by_number(const void *enabler,
2992 req_vec_num_in_item number)
2993{
2994 struct action_enabler *ae = (struct action_enabler *)enabler;
2995
2996 fc_assert_ret_val(number >= 0, NULL);
2997
2998 switch (number) {
2999 case 0:
3000 return &ae->actor_reqs;
3001 case 1:
3002 return &ae->target_reqs;
3003 default:
3004 return NULL;
3005 }
3006}
3007
3008/*********************************************************************/
3015 const char *action_enabler_vector_by_number_name(req_vec_num_in_item vec)
3016{
3017 switch (vec) {
3018 case 0:
3019 /* TRANS: requirement vector in an action enabler (ruledit) */
3020 return _("actor_reqs");
3021 case 1:
3022 /* TRANS: requirement vector in an action enabler (ruledit) */
3023 return _("target_reqs");
3024 default:
3025 return NULL;
3026 }
3027}
3028
3029/**********************************************************************/
3033 static bool plr_knows_tile(const struct player *plr,
3034 const struct tile *ttile)
3035{
3036 return plr && ttile && (tile_get_known(ttile, plr) != TILE_UNKNOWN);
3037}
3038
3039/**********************************************************************/
3042 static bool plr_sees_tile(const struct player *plr,
3043 const struct tile *ttile)
3044{
3045 return plr && ttile && (tile_get_known(ttile, plr) == TILE_KNOWN_SEEN);
3046}
3047
3048/**********************************************************************/
3053static const struct impr_type *
3054tgt_city_local_building(const struct city *target_city)
3055{
3056 /* Only used with city targets */
3057 fc_assert_ret_val(target_city, NULL);
3058
3059 if (target_city->production.kind == VUT_IMPROVEMENT) {
3060 /* The local building is what the target city currently is building. */
3061 return target_city->production.value.building;
3062 } else {
3063 /* In the current semantic the local building is always the building
3064 * being built. */
3065 /* TODO: Consider making the local building the target building for
3066 * actions that allows specifying a building target. */
3067 return NULL;
3068 }
3069}
3070
3071/**********************************************************************/
3076static const struct unit_type *
3077tgt_city_local_utype(const struct city *target_city)
3078{
3079 /* Only used with city targets */
3080 fc_assert_ret_val(target_city, NULL);
3081
3082 if (target_city->production.kind == VUT_UTYPE) {
3083 /* The local unit type is what the target city currently is
3084 * building. */
3085 return target_city->production.value.utype;
3086 } else {
3087 /* In the current semantic the local utype is always the type of the
3088 * unit being built. */
3089 return NULL;
3090 }
3091}
3092
3093/**********************************************************************/
3101static const struct tile *
3102blocked_find_target_tile(const struct action *act,
3103 const struct unit *actor_unit,
3104 const struct tile *target_tile_arg,
3105 const struct city *target_city,
3106 const struct unit *target_unit)
3107{
3108 if (target_tile_arg != NULL) {
3109 /* Trust the caller. */
3110 return target_tile_arg;
3111 }
3112
3113 /* Action should always be set */
3114 fc_assert_ret_val(act, NULL);
3115
3116 switch (action_get_target_kind(act)) {
3117 case ATK_CITY:
3118 fc_assert_ret_val(target_city, NULL);
3119 return city_tile(target_city);
3120 case ATK_UNIT:
3121 if (target_unit == NULL) {
3122 fc_assert(target_unit != NULL);
3123 return NULL;
3124 }
3125 return unit_tile(target_unit);
3126 case ATK_UNITS:
3127 fc_assert_ret_val(target_unit || target_tile_arg, NULL);
3128 if (target_unit) {
3129 return unit_tile(target_unit);
3130 }
3131
3132 fc__fallthrough;
3133 case ATK_TILE:
3134 case ATK_EXTRAS:
3135 fc_assert_ret_val(target_tile_arg, NULL);
3136 return target_tile_arg;
3137 case ATK_SELF:
3138 fc_assert_ret_val(actor_unit, NULL);
3139 return unit_tile(actor_unit);
3140 case ATK_COUNT:
3141 /* Handled below. */
3142 break;
3143 }
3144
3145 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
3146 action_get_target_kind(act), action_rule_name(act));
3147 return NULL;
3148}
3149
3150/**********************************************************************/
3159static const struct city *
3160blocked_find_target_city(const struct action *act,
3161 const struct unit *actor_unit,
3162 const struct tile *target_tile,
3163 const struct city *target_city_arg,
3164 const struct unit *target_unit)
3165{
3166 if (target_city_arg != NULL) {
3167 /* Trust the caller. */
3168 return target_city_arg;
3169 }
3170
3171 /* action should always be set */
3172 fc_assert_ret_val(act, NULL);
3173
3174 switch (action_get_target_kind(act)) {
3175 case ATK_CITY:
3176 fc_assert_ret_val(target_city_arg, NULL);
3177 return target_city_arg;
3178 case ATK_UNIT:
3179 fc_assert_ret_val(target_unit, NULL);
3180 fc_assert_ret_val(unit_tile(target_unit), NULL);
3181 return tile_city(unit_tile(target_unit));
3182 case ATK_UNITS:
3183 fc_assert_ret_val(target_unit || target_tile, NULL);
3184 if (target_unit) {
3185 fc_assert_ret_val(unit_tile(target_unit), NULL);
3186 return tile_city(unit_tile(target_unit));
3187 }
3188
3189 fc__fallthrough;
3190 case ATK_TILE:
3191 case ATK_EXTRAS:
3192 fc_assert_ret_val(target_tile, NULL);
3193 return tile_city(target_tile);
3194 case ATK_SELF:
3195 fc_assert_ret_val(actor_unit, NULL);
3196 fc_assert_ret_val(unit_tile(actor_unit), NULL);
3197 return tile_city(unit_tile(actor_unit));
3198 case ATK_COUNT:
3199 /* Handled below. */
3200 break;
3201 }
3202
3203 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
3204 action_get_target_kind(act), action_rule_name(act));
3205 return NULL;
3206}
3207
3208/**********************************************************************/
3214 struct action *action_is_blocked_by(const struct action *act,
3215 const struct unit *actor_unit,
3216 const struct tile *target_tile_arg,
3217 const struct city *target_city_arg,
3218 const struct unit *target_unit)
3219{
3220 const struct tile *target_tile
3221 = blocked_find_target_tile(act, actor_unit, target_tile_arg,
3222 target_city_arg, target_unit);
3223 const struct city *target_city
3224 = blocked_find_target_city(act, actor_unit, target_tile,
3225 target_city_arg, target_unit);
3226 const struct civ_map *nmap = &(wld.map);
3227
3228 action_iterate(blocker_id) {
3229 struct action *blocker = action_by_number(blocker_id);
3230
3231 fc_assert_action(action_get_actor_kind(blocker) == AAK_UNIT,
3232 continue);
3233
3234 if (!action_would_be_blocked_by(act, blocker)) {
3235 /* It doesn't matter if it is legal. It won't block the action. */
3236 continue;
3237 }
3238
3239 switch (action_get_target_kind(blocker)) {
3240 case ATK_CITY:
3241 if (!target_city) {
3242 /* Can't be enabled. No target. */
3243 continue;
3244 }
3245 if (is_action_enabled_unit_on_city(nmap, blocker->id,
3246 actor_unit, target_city)) {
3247 return blocker;
3248 }
3249 break;
3250 case ATK_UNIT:
3251 if (!target_unit) {
3252 /* Can't be enabled. No target. */
3253 continue;
3254 }
3255 if (is_action_enabled_unit_on_unit(nmap, blocker->id,
3256 actor_unit, target_unit)) {
3257 return blocker;
3258 }
3259 break;
3260 case ATK_UNITS:
3261 if (!target_tile) {
3262 /* Can't be enabled. No target. */
3263 continue;
3264 }
3265 if (is_action_enabled_unit_on_units(nmap, blocker->id,
3266 actor_unit, target_tile)) {
3267 return blocker;
3268 }
3269 break;
3270 case ATK_TILE:
3271 if (!target_tile) {
3272 /* Can't be enabled. No target. */
3273 continue;
3274 }
3275 if (is_action_enabled_unit_on_tile(nmap, blocker->id,
3276 actor_unit, target_tile, NULL)) {
3277 return blocker;
3278 }
3279 break;
3280 case ATK_EXTRAS:
3281 if (!target_tile) {
3282 /* Can't be enabled. No target. */
3283 continue;
3284 }
3285 if (is_action_enabled_unit_on_extras(nmap, blocker->id,
3286 actor_unit, target_tile, NULL)) {
3287 return blocker;
3288 }
3289 break;
3290 case ATK_SELF:
3291 if (is_action_enabled_unit_on_self(nmap, blocker->id, actor_unit)) {
3292 return blocker;
3293 }
3294 break;
3295 case ATK_COUNT:
3296 fc_assert_action(action_id_get_target_kind(blocker->id) != ATK_COUNT,
3297 continue);
3298 break;
3299 }
3300 } action_iterate_end;
3301
3302 /* Not blocked. */
3303 return NULL;
3304}
3305
3306/**********************************************************************/
3326static bool
3327action_actor_utype_hard_reqs_ok_full(const struct action *paction,
3328 const struct unit_type *actor_unittype,
3329 bool ignore_third_party)
3330{
3331 switch (paction->result) {
3332 case ACTRES_JOIN_CITY:
3333 if (actor_unittype->pop_cost <= 0) {
3334 /* Reason: Must have population to add. */
3335 return FALSE;
3336 }
3337 break;
3338
3339 case ACTRES_BOMBARD:
3340 if (actor_unittype->bombard_rate <= 0) {
3341 /* Reason: Can't bombard if it never fires. */
3342 return FALSE;
3343 }
3344
3345 if (actor_unittype->attack_strength <= 0) {
3346 /* Reason: Can't bombard without attack strength. */
3347 return FALSE;
3348 }
3349
3350 break;
3351
3352 case ACTRES_UPGRADE_UNIT:
3353 if (actor_unittype->obsoleted_by == U_NOT_OBSOLETED) {
3354 /* Reason: Nothing to upgrade to. */
3355 return FALSE;
3356 }
3357 break;
3358
3359 case ACTRES_ATTACK:
3360 if (actor_unittype->attack_strength <= 0) {
3361 /* Reason: Can't attack without strength. */
3362 return FALSE;
3363 }
3364 break;
3365
3366 case ACTRES_CONVERT:
3367 if (!actor_unittype->converted_to) {
3368 /* Reason: must be able to convert to something. */
3369 return FALSE;
3370 }
3371 break;
3372
3373 case ACTRES_TRANSPORT_UNLOAD:
3374 if (actor_unittype->transport_capacity < 1) {
3375 /* Reason: can't transport anything to unload. */
3376 return FALSE;
3377 }
3378 break;
3379
3380 case ACTRES_TRANSPORT_BOARD:
3381 case ACTRES_TRANSPORT_EMBARK:
3382 case ACTRES_TRANSPORT_ALIGHT:
3383 case ACTRES_TRANSPORT_DISEMBARK:
3384 if (!ignore_third_party) {
3385 bool has_transporter = FALSE;
3386
3387 unit_type_iterate(utrans) {
3388 if (can_unit_type_transport(utrans, utype_class(actor_unittype))) {
3389 has_transporter = TRUE;
3390 break;
3391 }
3392 } unit_type_iterate_end;
3393
3394 if (!has_transporter) {
3395 /* Reason: no other unit can transport this unit. */
3396 return FALSE;
3397 }
3398 }
3399 break;
3400
3401 case ACTRES_CONQUER_EXTRAS:
3402 if (!ignore_third_party) {
3403 bool has_target = FALSE;
3404 struct unit_class *pclass = utype_class(actor_unittype);
3405
3406 /* Use cache when it has been initialized */
3407 if (pclass->cache.native_bases != NULL) {
3408 /* Extra being native one is a hard requirement */
3409 extra_type_list_iterate(pclass->cache.native_bases, pextra) {
3410 if (!territory_claiming_base(pextra->data.base)) {
3411 /* Hard requirement */
3412 continue;
3413 }
3414
3415 has_target = TRUE;
3416 break;
3417 } extra_type_list_iterate_end;
3418 } else {
3419 struct extra_type_list *terr_claimers = extra_type_list_of_terr_claimers();
3420
3421 extra_type_list_iterate(terr_claimers, pextra) {
3422 if (!is_native_extra_to_uclass(pextra, pclass)) {
3423 /* Hard requirement */
3424 continue;
3425 }
3426
3427 has_target = TRUE;
3428 break;
3429 } extra_type_list_iterate_end;
3430 }
3431
3432 if (!has_target) {
3433 /* Reason: no extras can be conquered by this unit. */
3434 return FALSE;
3435 }
3436 }
3437 break;
3438
3439 case ACTRES_PARADROP:
3440 case ACTRES_PARADROP_CONQUER:
3441 if (actor_unittype->paratroopers_range <= 0) {
3442 /* Reason: Can't paradrop 0 tiles. */
3443 return FALSE;
3444 }
3445 break;
3446
3447 case ACTRES_HUT_ENTER:
3448 case ACTRES_HUT_FRIGHTEN:
3449 case ACTRES_ESTABLISH_EMBASSY:
3450 case ACTRES_SPY_INVESTIGATE_CITY:
3451 case ACTRES_SPY_POISON:
3452 case ACTRES_SPY_STEAL_GOLD:
3453 case ACTRES_SPY_SPREAD_PLAGUE:
3454 case ACTRES_SPY_SABOTAGE_CITY:
3455 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
3456 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
3457 case ACTRES_SPY_STEAL_TECH:
3458 case ACTRES_SPY_TARGETED_STEAL_TECH:
3459 case ACTRES_SPY_INCITE_CITY:
3460 case ACTRES_TRADE_ROUTE:
3461 case ACTRES_MARKETPLACE:
3462 case ACTRES_HELP_WONDER:
3463 case ACTRES_SPY_BRIBE_UNIT:
3464 case ACTRES_SPY_SABOTAGE_UNIT:
3465 case ACTRES_CAPTURE_UNITS:
3466 case ACTRES_FOUND_CITY:
3467 case ACTRES_STEAL_MAPS:
3468 case ACTRES_SPY_NUKE:
3469 case ACTRES_NUKE:
3470 case ACTRES_NUKE_UNITS:
3471 case ACTRES_DESTROY_CITY:
3472 case ACTRES_EXPEL_UNIT:
3473 case ACTRES_DISBAND_UNIT_RECOVER:
3474 case ACTRES_DISBAND_UNIT:
3475 case ACTRES_HOME_CITY:
3476 case ACTRES_HOMELESS:
3477 case ACTRES_AIRLIFT:
3478 case ACTRES_STRIKE_BUILDING:
3479 case ACTRES_STRIKE_PRODUCTION:
3480 case ACTRES_CONQUER_CITY:
3481 case ACTRES_HEAL_UNIT:
3482 case ACTRES_PILLAGE:
3483 case ACTRES_CLEAN_POLLUTION:
3484 case ACTRES_CLEAN_FALLOUT:
3485 case ACTRES_FORTIFY:
3486 case ACTRES_TRANSFORM_TERRAIN:
3487 case ACTRES_CULTIVATE:
3488 case ACTRES_PLANT:
3489 case ACTRES_ROAD:
3490 case ACTRES_BASE:
3491 case ACTRES_MINE:
3492 case ACTRES_IRRIGATE:
3493 case ACTRES_SPY_ATTACK:
3494 case ACTRES_UNIT_MOVE:
3495 case ACTRES_NONE:
3496 /* No hard unit type requirements. */
3497 break;
3498 }
3499
3500 return TRUE;
3501}
3502
3503/**********************************************************************/
3519bool
3520action_actor_utype_hard_reqs_ok(const struct action *paction,
3521 const struct unit_type *actor_unittype)
3522{
3523 return action_actor_utype_hard_reqs_ok_full(paction,
3524 actor_unittype, FALSE);
3525}
3526
3527/**********************************************************************/
3539static enum fc_tristate
3540action_hard_reqs_actor(const struct civ_map *nmap,
3541 const struct action *paction,
3542 const struct req_context *actor,
3543 const bool omniscient,
3544 const struct city *homecity)
3545{
3546 enum action_result result = paction->result;
3547
3548 if (actor == NULL) {
3549 actor = req_context_empty();
3550 }
3551
3552 if (!action_actor_utype_hard_reqs_ok_full(paction, actor->unittype,
3553 TRUE)) {
3554 /* Info leak: The actor player knows the type of their unit. */
3555 /* The actor unit type can't perform the action because of hard
3556 * unit type requirements. */
3557 return TRI_NO;
3558 }
3559
3560 switch (result) {
3561 case ACTRES_PARADROP:
3562 case ACTRES_PARADROP_CONQUER:
3563 /* Reason: Keep the old rules. */
3564 /* Info leak: The player knows if their unit already has paradropped this
3565 * turn. */
3566 if (actor->unit->paradropped) {
3567 return TRI_NO;
3568 }
3569
3570 break;
3571
3572 case ACTRES_AIRLIFT:
3573 {
3574 /* Obligatory hard requirement. Checked here too since
3575 * action_hard_reqs_actor() may be called before any
3576 * action enablers are checked. */
3577 if (actor->city == NULL) {
3578 /* No city to airlift from. */
3579 return TRI_NO;
3580 }
3581
3582 if (actor->player != city_owner(actor->city)
3583 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_SRC
3584 && pplayers_allied(actor->player,
3585 city_owner(actor->city)))) {
3586 /* Not allowed to airlift from this source. */
3587 return TRI_NO;
3588 }
3589
3590 if (!(omniscient || city_owner(actor->city) == actor->player)) {
3591 /* Can't check for airlifting capacity. */
3592 return TRI_MAYBE;
3593 }
3594
3595 if (0 >= actor->city->airlift
3596 && (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)
3597 || !game.info.airlift_from_always_enabled)) {
3598 /* The source cannot airlift for this turn (maybe already airlifted
3599 * or no airport).
3600 *
3601 * See also do_airline() in server/unittools.h. */
3602 return TRI_NO;
3603 }
3604 }
3605 break;
3606
3607 case ACTRES_CONVERT:
3608 /* Reason: Keep the old rules. */
3609 /* Info leak: The player knows their unit's cargo and location. */
3610 if (!unit_can_convert(nmap, actor->unit)) {
3611 return TRI_NO;
3612 }
3613 break;
3614
3615 case ACTRES_TRANSPORT_BOARD:
3616 case ACTRES_TRANSPORT_EMBARK:
3617 if (unit_transported(actor->unit)) {
3618 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
3619 /* Can't leave current transport. */
3620 return TRI_NO;
3621 }
3622 }
3623 break;
3624
3625 case ACTRES_TRANSPORT_DISEMBARK:
3626 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
3627 /* Keep the old rules about Unreachable and disembarks. */
3628 return TRI_NO;
3629 }
3630 break;
3631
3632 case ACTRES_HOMELESS:
3633 case ACTRES_UNIT_MOVE:
3634 case ACTRES_ESTABLISH_EMBASSY:
3635 case ACTRES_SPY_INVESTIGATE_CITY:
3636 case ACTRES_SPY_POISON:
3637 case ACTRES_SPY_STEAL_GOLD:
3638 case ACTRES_SPY_SPREAD_PLAGUE:
3639 case ACTRES_SPY_SABOTAGE_CITY:
3640 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
3641 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
3642 case ACTRES_SPY_STEAL_TECH:
3643 case ACTRES_SPY_TARGETED_STEAL_TECH:
3644 case ACTRES_SPY_INCITE_CITY:
3645 case ACTRES_TRADE_ROUTE:
3646 case ACTRES_MARKETPLACE:
3647 case ACTRES_HELP_WONDER:
3648 case ACTRES_SPY_BRIBE_UNIT:
3649 case ACTRES_SPY_SABOTAGE_UNIT:
3650 case ACTRES_CAPTURE_UNITS:
3651 case ACTRES_FOUND_CITY:
3652 case ACTRES_JOIN_CITY:
3653 case ACTRES_STEAL_MAPS:
3654 case ACTRES_BOMBARD:
3655 case ACTRES_SPY_NUKE:
3656 case ACTRES_NUKE:
3657 case ACTRES_NUKE_UNITS:
3658 case ACTRES_DESTROY_CITY:
3659 case ACTRES_EXPEL_UNIT:
3660 case ACTRES_DISBAND_UNIT_RECOVER:
3661 case ACTRES_DISBAND_UNIT:
3662 case ACTRES_HOME_CITY:
3663 case ACTRES_UPGRADE_UNIT:
3664 case ACTRES_ATTACK:
3665 case ACTRES_STRIKE_BUILDING:
3666 case ACTRES_STRIKE_PRODUCTION:
3667 case ACTRES_CONQUER_CITY:
3668 case ACTRES_CONQUER_EXTRAS:
3669 case ACTRES_HEAL_UNIT:
3670 case ACTRES_TRANSFORM_TERRAIN:
3671 case ACTRES_CULTIVATE:
3672 case ACTRES_PLANT:
3673 case ACTRES_PILLAGE:
3674 case ACTRES_CLEAN_POLLUTION:
3675 case ACTRES_CLEAN_FALLOUT:
3676 case ACTRES_FORTIFY:
3677 case ACTRES_ROAD:
3678 case ACTRES_BASE:
3679 case ACTRES_MINE:
3680 case ACTRES_IRRIGATE:
3681 case ACTRES_TRANSPORT_ALIGHT:
3682 case ACTRES_TRANSPORT_UNLOAD:
3683 case ACTRES_SPY_ATTACK:
3684 case ACTRES_HUT_ENTER:
3685 case ACTRES_HUT_FRIGHTEN:
3686 case ACTRES_NONE:
3687 /* No hard unit requirements. */
3688 break;
3689 }
3690
3691 return TRI_YES;
3692}
3693
3694/**********************************************************************/
3717static enum fc_tristate
3718is_action_possible(const struct civ_map *nmap,
3719 const action_id wanted_action,
3720 const struct req_context *actor,
3721 const struct req_context *target,
3722 const struct extra_type *target_extra,
3723 const bool omniscient,
3724 const struct city *homecity)
3725{
3726 bool can_see_tgt_unit;
3727 bool can_see_tgt_tile;
3728 enum fc_tristate out;
3729 struct terrain *pterrain;
3730 struct action *paction = action_by_number(wanted_action);
3731 enum action_target_kind tkind = action_get_target_kind(paction);
3732
3733 if (actor == NULL) {
3734 actor = req_context_empty();
3735 }
3736 if (target == NULL) {
3737 target = req_context_empty();
3738 }
3739
3740 fc_assert_msg((tkind == ATK_CITY && target->city != NULL)
3741 || (tkind == ATK_TILE && target->tile != NULL)
3742 || (tkind == ATK_EXTRAS && target->tile != NULL)
3743 || (tkind == ATK_UNIT && target->unit != NULL)
3744 /* At this level each individual unit is tested. */
3745 || (tkind == ATK_UNITS && target->unit != NULL)
3746 || (tkind == ATK_SELF),
3747 "Missing target!");
3748
3749 /* Only check requirement against the target unit if the actor can see it
3750 * or if the evaluator is omniscient. The game checking the rules is
3751 * omniscient. The player asking about their odds isn't. */
3752 can_see_tgt_unit = (omniscient || (target->unit
3753 && can_player_see_unit(actor->player,
3754 target->unit)));
3755
3756 /* Only check requirement against the target tile if the actor can see it
3757 * or if the evaluator is omniscient. The game checking the rules is
3758 * omniscient. The player asking about their odds isn't. */
3759 can_see_tgt_tile = (omniscient
3760 || plr_sees_tile(actor->player, target->tile));
3761
3762 /* Info leak: The player knows where their unit is. */
3763 if (tkind != ATK_SELF
3764 && !action_distance_accepted(paction,
3765 real_map_distance(actor->tile,
3766 target->tile))) {
3767 /* The distance between the actor and the target isn't inside the
3768 * action's accepted range. */
3769 return TRI_NO;
3770 }
3771
3772 switch (tkind) {
3773 case ATK_UNIT:
3774 /* The Freeciv code for all actions that is controlled by action
3775 * enablers and targets a unit assumes that the acting
3776 * player can see the target unit.
3777 * Examples:
3778 * - action_prob_vs_unit()'s quick check that the distance between actor
3779 * and target is acceptable would leak distance to target unit if the
3780 * target unit can't be seen.
3781 */
3782 if (!can_player_see_unit(actor->player, target->unit)) {
3783 return TRI_NO;
3784 }
3785 break;
3786 case ATK_CITY:
3787 /* The Freeciv code assumes that the player is aware of the target
3788 * city's existence. (How can you order an airlift to a city when you
3789 * don't know its city ID?) */
3790 if (fc_funcs->player_tile_city_id_get(city_tile(target->city),
3791 actor->player)
3792 != target->city->id) {
3793 return TRI_NO;
3794 }
3795 break;
3796 case ATK_UNITS:
3797 case ATK_TILE:
3798 case ATK_EXTRAS:
3799 case ATK_SELF:
3800 /* No special player knowledge checks. */
3801 break;
3802 case ATK_COUNT:
3803 fc_assert(tkind != ATK_COUNT);
3804 break;
3805 }
3806
3807 if (action_is_blocked_by(paction, actor->unit,
3808 target->tile, target->city, target->unit)) {
3809 /* Allows an action to block an other action. If a blocking action is
3810 * legal the actions it blocks becomes illegal. */
3811 return TRI_NO;
3812 }
3813
3814 /* Actor specific hard requirements. */
3815 out = action_hard_reqs_actor(nmap, paction, actor, omniscient, homecity);
3816
3817 if (out == TRI_NO) {
3818 /* Illegal because of a hard actor requirement. */
3819 return TRI_NO;
3820 }
3821
3822 /* Hard requirements for individual actions. */
3823 switch (paction->result) {
3824 case ACTRES_CAPTURE_UNITS:
3825 case ACTRES_SPY_BRIBE_UNIT:
3826 /* Why this is a hard requirement: Can't transfer a unique unit if the
3827 * actor player already has one. */
3828 /* Info leak: This is only checked for when the actor player can see
3829 * the target unit. Since the target unit is seen its type is known.
3830 * The fact that a city hiding the unseen unit is occupied is known. */
3831
3832 if (!can_see_tgt_unit) {
3833 /* An omniscient player can see the target unit. */
3834 fc_assert(!omniscient);
3835
3836 return TRI_MAYBE;
3837 }
3838
3839 if (utype_player_already_has_this_unique(actor->player,
3840 target->unittype)) {
3841 return TRI_NO;
3842 }
3843
3844 /* FIXME: Capture Unit may want to look for more than one unique unit
3845 * of the same kind at the target tile. Currently caught by sanity
3846 * check in do_capture_units(). */
3847
3848 break;
3849
3850 case ACTRES_SPY_TARGETED_STEAL_TECH:
3851 /* Reason: The Freeciv code don't support selecting a target tech
3852 * unless it is known that the victim player has it. */
3853 /* Info leak: The actor player knowns whose techs they can see. */
3854 if (!can_see_techs_of_target(actor->player, target->player)) {
3855 return TRI_NO;
3856 }
3857
3858 break;
3859
3860 case ACTRES_SPY_STEAL_GOLD:
3861 /* If actor->unit can do the action the actor->player can see how much
3862 * gold target->player have. Not requiring it is therefore pointless.
3863 */
3864 if (target->player->economic.gold <= 0) {
3865 return TRI_NO;
3866 }
3867
3868 break;
3869
3870 case ACTRES_TRADE_ROUTE:
3871 case ACTRES_MARKETPLACE:
3872 {
3873 /* Checked in action_hard_reqs_actor() */
3874 fc_assert_ret_val(homecity != NULL, TRI_NO);
3875
3876 /* Can't establish a trade route or enter the market place if the
3877 * cities can't trade at all. */
3878 /* TODO: Should this restriction (and the above restriction that the
3879 * actor unit must have a home city) be kept for Enter Marketplace? */
3880 if (!can_cities_trade(homecity, target->city)) {
3881 return TRI_NO;
3882 }
3883
3884 /* There are more restrictions on establishing a trade route than on
3885 * entering the market place. */
3886 if (action_has_result(paction, ACTRES_TRADE_ROUTE)
3887 && !can_establish_trade_route(homecity, target->city)) {
3888 return TRI_NO;
3889 }
3890 }
3891
3892 break;
3893
3894 case ACTRES_HELP_WONDER:
3895 case ACTRES_DISBAND_UNIT_RECOVER:
3896 /* It is only possible to help the production if the production needs
3897 * the help. (If not it would be possible to add shields for something
3898 * that can't legally receive help if it is build later) */
3899 /* Info leak: The player knows that the production in their own city has
3900 * been hurried (bought or helped). The information isn't revealed when
3901 * asking for action probabilities since omniscient is FALSE. */
3902 if (!omniscient
3903 && !can_player_see_city_internals(actor->player, target->city)) {
3904 return TRI_MAYBE;
3905 }
3906
3907 if (!(target->city->shield_stock
3908 < city_production_build_shield_cost(target->city))) {
3909 return TRI_NO;
3910 }
3911
3912 break;
3913
3914 case ACTRES_FOUND_CITY:
3915 if (game.scenario.prevent_new_cities) {
3916 /* Reason: allow scenarios to disable city founding. */
3917 /* Info leak: the setting is public knowledge. */
3918 return TRI_NO;
3919 }
3920
3921 if (can_see_tgt_tile && tile_city(target->tile)) {
3922 /* Reason: a tile can have 0 or 1 cities. */
3923 return TRI_NO;
3924 }
3925
3926 if (citymindist_prevents_city_on_tile(nmap, target->tile)) {
3927 if (omniscient) {
3928 /* No need to check again. */
3929 return TRI_NO;
3930 } else {
3931 square_iterate(nmap, target->tile,
3932 game.info.citymindist - 1, otile) {
3933 if (tile_city(otile) != NULL
3934 && plr_sees_tile(actor->player, otile)) {
3935 /* Known to be blocked by citymindist */
3936 return TRI_NO;
3937 }
3938 } square_iterate_end;
3939 }
3940 }
3941
3942 /* The player may not have enough information to be certain. */
3943
3944 if (!can_see_tgt_tile) {
3945 /* Need to know if target tile already has a city, has TER_NO_CITIES
3946 * terrain, is non native to the actor or is owned by a foreigner. */
3947 return TRI_MAYBE;
3948 }
3949
3950 if (!omniscient) {
3951 /* The player may not have enough information to find out if
3952 * citymindist blocks or not. This doesn't depend on if it blocks. */
3953 square_iterate(nmap, target->tile,
3954 game.info.citymindist - 1, otile) {
3955 if (!plr_sees_tile(actor->player, otile)) {
3956 /* Could have a city that blocks via citymindist. Even if this
3957 * tile has TER_NO_CITIES terrain the player don't know that it
3958 * didn't change and had a city built on it. */
3959 return TRI_MAYBE;
3960 }
3961 } square_iterate_end;
3962 }
3963
3964 break;
3965
3966 case ACTRES_JOIN_CITY:
3967 {
3968 int new_pop;
3969
3970 if (!omniscient
3971 && !player_can_see_city_externals(actor->player, target->city)) {
3972 return TRI_MAYBE;
3973 }
3974
3975 new_pop = city_size_get(target->city) + unit_pop_value(actor->unit);
3976
3977 if (new_pop > game.info.add_to_size_limit) {
3978 /* Reason: Make the add_to_size_limit setting work. */
3979 return TRI_NO;
3980 }
3981
3982 if (!city_can_grow_to(target->city, new_pop)) {
3983 /* Reason: respect city size limits. */
3984 /* Info leak: when it is legal to join a foreign city is legal and
3985 * the EFT_SIZE_UNLIMIT effect or the EFT_SIZE_ADJ effect depends on
3986 * something the actor player don't have access to.
3987 * Example: depends on a building (like Aqueduct) that isn't
3988 * VisibleByOthers. */
3989 return TRI_NO;
3990 }
3991 }
3992
3993 break;
3994
3995 case ACTRES_NUKE_UNITS:
3996 if (unit_attack_units_at_tile_result(actor->unit, paction,
3997 target->tile)
3998 != ATT_OK) {
3999 /* Unreachable. */
4000 return TRI_NO;
4001 }
4002
4003 break;
4004
4005 case ACTRES_HOME_CITY:
4006 /* Reason: can't change to what is. */
4007 /* Info leak: The player knows their unit's current home city. */
4008 if (homecity != NULL && homecity->id == target->city->id) {
4009 /* This is already the unit's home city. */
4010 return TRI_NO;
4011 }
4012
4013 {
4014 int slots = unit_type_get(actor->unit)->city_slots;
4015
4016 if (slots > 0 && city_unit_slots_available(target->city) < slots) {
4017 return TRI_NO;
4018 }
4019 }
4020
4021 break;
4022
4023 case ACTRES_UPGRADE_UNIT:
4024 /* Reason: Keep the old rules. */
4025 /* Info leak: The player knows their unit's type. They know if they can
4026 * build the unit type upgraded to. If the upgrade happens in a foreign
4027 * city that fact may leak. This can be seen as a price for changing
4028 * the rules to allow upgrading in a foreign city.
4029 * The player knows how much gold they have. If the Upgrade_Price_Pct
4030 * effect depends on information they don't have that information may
4031 * leak. The player knows the location of their unit. They know if the
4032 * tile has a city and if the unit can exist there outside a transport.
4033 * The player knows their unit's cargo. By knowing the number and type
4034 * of cargo, they can predict if there will be enough room in the unit
4035 * upgraded to, as long as they know what unit type their unit will end
4036 * up as. */
4037 if (unit_upgrade_test(nmap, actor->unit, FALSE) != UU_OK) {
4038 return TRI_NO;
4039 }
4040
4041 break;
4042
4043 case ACTRES_PARADROP:
4044 case ACTRES_PARADROP_CONQUER:
4045 /* Reason: Keep the old rules. */
4046 /* Info leak: The player knows if they know the target tile. */
4047 if (!plr_knows_tile(actor->player, target->tile)) {
4048 return TRI_NO;
4049 }
4050
4051 if (plr_sees_tile(actor->player, target->tile)) {
4052 /* Check for seen stuff that may kill the actor unit. */
4053
4054 /* Reason: Keep the old rules. Be merciful. */
4055 /* Info leak: The player sees the target tile. */
4056 if (!can_unit_exist_at_tile(nmap, actor->unit, target->tile)
4057 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
4058 || !unit_could_load_at(actor->unit, target->tile))) {
4059 return TRI_NO;
4060 }
4061
4062 /* Reason: Keep the old rules. Be merciful. */
4063 /* Info leak: The player sees the target tile. */
4064 if (is_non_attack_city_tile(target->tile, actor->player)) {
4065 return TRI_NO;
4066 }
4067
4068 /* Reason: Be merciful. */
4069 /* Info leak: The player sees all units checked. Invisible units are
4070 * ignored. */
4071 unit_list_iterate(target->tile->units, pother) {
4072 if (can_player_see_unit(actor->player, pother)
4073 && !pplayers_allied(actor->player, unit_owner(pother))) {
4074 return TRI_NO;
4075 }
4076 } unit_list_iterate_end;
4077 }
4078
4079 /* Reason: Keep paratroopers_range working. */
4080 /* Info leak: The player knows the location of the actor and of the
4081 * target tile. */
4082 if (unit_type_get(actor->unit)->paratroopers_range
4083 < real_map_distance(actor->tile, target->tile)) {
4084 return TRI_NO;
4085 }
4086
4087 break;
4088
4089 case ACTRES_AIRLIFT:
4090 /* Reason: Keep the old rules. */
4091 /* Info leak: same as test_unit_can_airlift_to() */
4092 switch (test_unit_can_airlift_to(nmap, omniscient ? NULL : actor->player,
4093 actor->unit, target->city)) {
4094 case AR_OK:
4095 return TRI_YES;
4096 case AR_OK_SRC_UNKNOWN:
4097 case AR_OK_DST_UNKNOWN:
4098 return TRI_MAYBE;
4099 case AR_NO_MOVES:
4100 case AR_WRONG_UNITTYPE:
4101 case AR_OCCUPIED:
4102 case AR_NOT_IN_CITY:
4103 case AR_BAD_SRC_CITY:
4104 case AR_BAD_DST_CITY:
4105 case AR_SRC_NO_FLIGHTS:
4106 case AR_DST_NO_FLIGHTS:
4107 return TRI_NO;
4108 }
4109
4110 break;
4111
4112 case ACTRES_ATTACK:
4113 /* Reason: Keep the old rules. */
4114 if (!can_unit_attack_tile(actor->unit, paction, target->tile)) {
4115 return TRI_NO;
4116 }
4117 break;
4118
4119 case ACTRES_CONQUER_CITY:
4120 /* Reason: "Conquer City" involves moving into the city. */
4121 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4122 FALSE, FALSE, TRUE)) {
4123 return TRI_NO;
4124 }
4125
4126 break;
4127
4128 case ACTRES_CONQUER_EXTRAS:
4129 /* Reason: "Conquer Extras" involves moving to the tile. */
4130 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4131 FALSE, FALSE, FALSE)) {
4132 return TRI_NO;
4133 }
4134 /* Reason: Must have something to claim. The more specific restriction
4135 * that the base must be native to the actor unit is hard coded in
4136 * unit_move(), in action_actor_utype_hard_reqs_ok_full(), in
4137 * helptext_extra(), in helptext_unit(), in do_attack() and in
4138 * diplomat_bribe(). */
4139 if (!tile_has_claimable_base(target->tile, actor->unittype)) {
4140 return TRI_NO;
4141 }
4142 break;
4143
4144 case ACTRES_HEAL_UNIT:
4145 /* Reason: It is not the healthy who need a doctor, but the sick. */
4146 /* Info leak: the actor can see the target's HP. */
4147 if (!can_see_tgt_unit) {
4148 return TRI_MAYBE;
4149 }
4150 if (!(target->unit->hp < target->unittype->hp)) {
4151 return TRI_NO;
4152 }
4153 break;
4154
4155 case ACTRES_TRANSFORM_TERRAIN:
4156 pterrain = tile_terrain(target->tile);
4157 if (pterrain->transform_result == T_NONE
4158 || pterrain == pterrain->transform_result
4159 || !terrain_surroundings_allow_change(nmap, target->tile,
4160 pterrain->transform_result)
4161 || (terrain_has_flag(pterrain->transform_result, TER_NO_CITIES)
4162 && (tile_city(target->tile)))) {
4163 return TRI_NO;
4164 }
4165 break;
4166
4167 case ACTRES_CULTIVATE:
4168 pterrain = tile_terrain(target->tile);
4169 if (pterrain->cultivate_result == NULL) {
4170 return TRI_NO;
4171 }
4172 if (!terrain_surroundings_allow_change(nmap, target->tile,
4173 pterrain->cultivate_result)
4174 || (terrain_has_flag(pterrain->cultivate_result, TER_NO_CITIES)
4175 && tile_city(target->tile))) {
4176 return TRI_NO;
4177 }
4178 break;
4179
4180 case ACTRES_PLANT:
4181 pterrain = tile_terrain(target->tile);
4182 if (pterrain->plant_result == NULL) {
4183 return TRI_NO;
4184 }
4185 if (!terrain_surroundings_allow_change(nmap, target->tile,
4186 pterrain->plant_result)
4187 || (terrain_has_flag(pterrain->plant_result, TER_NO_CITIES)
4188 && tile_city(target->tile))) {
4189 return TRI_NO;
4190 }
4191 break;
4192
4193 case ACTRES_ROAD:
4194 if (target_extra == NULL) {
4195 return TRI_NO;
4196 }
4197 if (!is_extra_caused_by(target_extra, EC_ROAD)) {
4198 /* Reason: This is not a road. */
4199 return TRI_NO;
4200 }
4201 if (!can_build_road(nmap, extra_road_get(target_extra), actor->unit,
4202 target->tile)) {
4203 return TRI_NO;
4204 }
4205 break;
4206
4207 case ACTRES_BASE:
4208 if (target_extra == NULL) {
4209 return TRI_NO;
4210 }
4211 if (!is_extra_caused_by(target_extra, EC_BASE)) {
4212 /* Reason: This is not a base. */
4213 return TRI_NO;
4214 }
4215 if (!can_build_base(actor->unit,
4216 extra_base_get(target_extra), target->tile)) {
4217 return TRI_NO;
4218 }
4219 break;
4220
4221 case ACTRES_MINE:
4222 if (target_extra == NULL) {
4223 return TRI_NO;
4224 }
4225 if (!is_extra_caused_by(target_extra, EC_MINE)) {
4226 /* Reason: This is not a mine. */
4227 return TRI_NO;
4228 }
4229
4230 if (!can_build_extra(target_extra, actor->unit, target->tile)) {
4231 return TRI_NO;
4232 }
4233 break;
4234
4235 case ACTRES_IRRIGATE:
4236 if (target_extra == NULL) {
4237 return TRI_NO;
4238 }
4239 if (!is_extra_caused_by(target_extra, EC_IRRIGATION)) {
4240 /* Reason: This is not an irrigation. */
4241 return TRI_NO;
4242 }
4243
4244 if (!can_build_extra(target_extra, actor->unit, target->tile)) {
4245 return TRI_NO;
4246 }
4247 break;
4248
4249 case ACTRES_PILLAGE:
4250 pterrain = tile_terrain(target->tile);
4251 if (pterrain->pillage_time == 0) {
4252 return TRI_NO;
4253 }
4254
4255 {
4256 bv_extras pspresent = get_tile_infrastructure_set(target->tile, NULL);
4257 bv_extras psworking = get_unit_tile_pillage_set(target->tile);
4258 bv_extras pspossible;
4259
4260 BV_CLR_ALL(pspossible);
4261 extra_type_iterate(pextra) {
4262 int idx = extra_index(pextra);
4263
4264 /* Only one unit can pillage a given improvement at a time */
4265 if (BV_ISSET(pspresent, idx)
4266 && (!BV_ISSET(psworking, idx)
4267 || actor->unit->activity_target == pextra)
4268 && can_remove_extra(pextra, actor->unit, target->tile)) {
4269 bool required = FALSE;
4270
4271 extra_type_iterate(pdepending) {
4272 if (BV_ISSET(pspresent, extra_index(pdepending))) {
4273 extra_deps_iterate(&(pdepending->reqs), pdep) {
4274 if (pdep == pextra) {
4275 required = TRUE;
4276 break;
4277 }
4278 } extra_deps_iterate_end;
4279 }
4280 if (required) {
4281 break;
4282 }
4283 } extra_type_iterate_end;
4284
4285 if (!required) {
4286 BV_SET(pspossible, idx);
4287 }
4288 }
4289 } extra_type_iterate_end;
4290
4291 if (!BV_ISSET_ANY(pspossible)) {
4292 /* Nothing available to pillage */
4293 return TRI_NO;
4294 }
4295
4296 if (target_extra != NULL) {
4297 if (!game.info.pillage_select) {
4298 /* Hobson's choice (this case mostly exists for old clients) */
4299 /* Needs to match what unit_activity_assign_target chooses */
4300 struct extra_type *tgt;
4301
4302 tgt = get_preferred_pillage(pspossible);
4303
4304 if (tgt != target_extra) {
4305 /* Only one target allowed, which wasn't the requested one */
4306 return TRI_NO;
4307 }
4308 }
4309
4310 if (!BV_ISSET(pspossible, extra_index(target_extra))) {
4311 return TRI_NO;
4312 }
4313 }
4314 }
4315 break;
4316
4317 case ACTRES_CLEAN_POLLUTION:
4318 {
4319 const struct extra_type *pextra;
4320
4321 pterrain = tile_terrain(target->tile);
4322 if (pterrain->clean_pollution_time == 0) {
4323 return TRI_NO;
4324 }
4325
4326 if (target_extra != NULL) {
4327 pextra = target_extra;
4328
4329 if (!is_extra_removed_by(pextra, ERM_CLEANPOLLUTION)) {
4330 return TRI_NO;
4331 }
4332
4333 if (!tile_has_extra(target->tile, pextra)) {
4334 return TRI_NO;
4335 }
4336 } else {
4337 /* TODO: Make sure that all callers set target so that
4338 * we don't need this fallback. */
4339 pextra = prev_extra_in_tile(target->tile,
4340 ERM_CLEANPOLLUTION,
4341 actor->player,
4342 actor->unit);
4343 if (pextra == NULL) {
4344 /* No available pollution extras */
4345 return TRI_NO;
4346 }
4347 }
4348
4349 if (can_remove_extra(pextra, actor->unit, target->tile)) {
4350 return TRI_YES;
4351 }
4352
4353 return TRI_NO;
4354 }
4355 break;
4356
4357 case ACTRES_CLEAN_FALLOUT:
4358 {
4359 const struct extra_type *pextra;
4360
4361 pterrain = tile_terrain(target->tile);
4362 if (pterrain->clean_fallout_time == 0) {
4363 return TRI_NO;
4364 }
4365
4366 if (target_extra != NULL) {
4367 pextra = target_extra;
4368
4369 if (!is_extra_removed_by(pextra, ERM_CLEANFALLOUT)) {
4370 return TRI_NO;
4371 }
4372
4373 if (!tile_has_extra(target->tile, pextra)) {
4374 return TRI_NO;
4375 }
4376 } else {
4377 /* TODO: Make sure that all callers set target so that
4378 * we don't need this fallback. */
4379 pextra = prev_extra_in_tile(target->tile,
4380 ERM_CLEANFALLOUT,
4381 actor->player,
4382 actor->unit);
4383 if (pextra == NULL) {
4384 /* No available fallout extras */
4385 return TRI_NO;
4386 }
4387 }
4388
4389 if (can_remove_extra(pextra, actor->unit, target->tile)) {
4390 return TRI_YES;
4391 }
4392
4393 return TRI_NO;
4394 }
4395 break;
4396
4397 case ACTRES_TRANSPORT_ALIGHT:
4398 if (!can_unit_unload(actor->unit, target->unit)) {
4399 /* Keep the old rules about Unreachable and disembarks. */
4400 return TRI_NO;
4401 }
4402 break;
4403
4404 case ACTRES_TRANSPORT_BOARD:
4405 if (unit_transported(actor->unit)) {
4406 if (target->unit == unit_transport_get(actor->unit)) {
4407 /* Already inside this transport. */
4408 return TRI_NO;
4409 }
4410 }
4411 if (!could_unit_load(actor->unit, target->unit)) {
4412 /* Keep the old rules. */
4413 return TRI_NO;
4414 }
4415 break;
4416
4417 case ACTRES_TRANSPORT_UNLOAD:
4418 if (!can_unit_unload(target->unit, actor->unit)) {
4419 /* Keep the old rules about Unreachable and disembarks. */
4420 return TRI_NO;
4421 }
4422 break;
4423
4424 case ACTRES_TRANSPORT_DISEMBARK:
4425 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4426 FALSE, FALSE, FALSE)) {
4427 /* Reason: involves moving to the tile. */
4428 return TRI_NO;
4429 }
4430
4431 /* We cannot move a transport into a tile that holds
4432 * units or cities not allied with all of our cargo. */
4433 if (get_transporter_capacity(actor->unit) > 0) {
4434 unit_list_iterate(unit_tile(actor->unit)->units, pcargo) {
4435 if (unit_contained_in(pcargo, actor->unit)
4436 && (is_non_allied_unit_tile(target->tile, unit_owner(pcargo))
4437 || is_non_allied_city_tile(target->tile,
4438 unit_owner(pcargo)))) {
4439 return TRI_NO;
4440 }
4441 } unit_list_iterate_end;
4442 }
4443 break;
4444
4445 case ACTRES_TRANSPORT_EMBARK:
4446 if (unit_transported(actor->unit)) {
4447 if (target->unit == unit_transport_get(actor->unit)) {
4448 /* Already inside this transport. */
4449 return TRI_NO;
4450 }
4451 }
4452 if (!could_unit_load(actor->unit, target->unit)) {
4453 /* Keep the old rules. */
4454 return TRI_NO;
4455 }
4456 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4457 FALSE, TRUE, FALSE)) {
4458 /* Reason: involves moving to the tile. */
4459 return TRI_NO;
4460 }
4461 /* We cannot move a transport into a tile that holds
4462 * units or cities not allied with all of our cargo. */
4463 if (get_transporter_capacity(actor->unit) > 0) {
4464 unit_list_iterate(unit_tile(actor->unit)->units, pcargo) {
4465 if (unit_contained_in(pcargo, actor->unit)
4466 && (is_non_allied_unit_tile(target->tile, unit_owner(pcargo))
4467 || is_non_allied_city_tile(target->tile,
4468 unit_owner(pcargo)))) {
4469 return TRI_NO;
4470 }
4471 } unit_list_iterate_end;
4472 }
4473 break;
4474
4475 case ACTRES_SPY_ATTACK:
4476 {
4477 bool found;
4478
4479 if (!omniscient
4480 && !can_player_see_hypotetic_units_at(actor->player,
4481 target->tile)) {
4482 /* May have a hidden diplomatic defender. */
4483 return TRI_MAYBE;
4484 }
4485
4486 found = FALSE;
4487 unit_list_iterate(target->tile->units, punit) {
4488 struct player *uplayer = unit_owner(punit);
4489
4490 if (uplayer == actor->player) {
4491 /* Won't defend against its owner. */
4492 continue;
4493 }
4494
4495 if (unit_has_type_flag(punit, UTYF_SUPERSPY)) {
4496 /* This unbeatable diplomatic defender will defend before any
4497 * that can be beaten. */
4498 found = FALSE;
4499 break;
4500 }
4501
4502 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
4503 /* Found a beatable diplomatic defender. */
4504 found = TRUE;
4505 break;
4506 }
4507 } unit_list_iterate_end;
4508
4509 if (!found) {
4510 return TRI_NO;
4511 }
4512 }
4513 break;
4514
4515 case ACTRES_HUT_ENTER:
4516 case ACTRES_HUT_FRIGHTEN:
4517 /* Reason: involves moving to the tile. */
4518 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4519 FALSE, FALSE, FALSE)) {
4520 return TRI_NO;
4521 }
4522 if (!unit_can_displace_hut(actor->unit, target->tile)) {
4523 /* Reason: keep extra rmreqs working. */
4524 return TRI_NO;
4525 }
4526 break;
4527
4528 case ACTRES_UNIT_MOVE:
4529 /* Reason: is moving to the tile. */
4530 if (!unit_can_move_to_tile(nmap, actor->unit, target->tile,
4531 FALSE, FALSE, FALSE)) {
4532 return TRI_NO;
4533 }
4534
4535 /* Reason: Don't override "Transport Embark" */
4536 if (!can_unit_exist_at_tile(nmap, actor->unit, target->tile)) {
4537 return TRI_NO;
4538 }
4539
4540 /* We cannot move a transport into a tile that holds
4541 * units or cities not allied with all of our cargo. */
4542 if (get_transporter_capacity(actor->unit) > 0) {
4543 unit_list_iterate(unit_tile(actor->unit)->units, pcargo) {
4544 if (unit_contained_in(pcargo, actor->unit)
4545 && (is_non_allied_unit_tile(target->tile, unit_owner(pcargo))
4546 || is_non_allied_city_tile(target->tile,
4547 unit_owner(pcargo)))) {
4548 return TRI_NO;
4549 }
4550 } unit_list_iterate_end;
4551 }
4552 break;
4553
4554 case ACTRES_SPY_SPREAD_PLAGUE:
4555 /* Enabling this action with illness_on = FALSE prevents spread. */
4556 break;
4557 case ACTRES_BOMBARD:
4558 {
4559 /* Allow bombing only if there's reachable units in the target
4560 * tile. Bombing without anybody taking damage is certainly not
4561 * what user really wants.
4562 * Allow bombing when player does not know if there's units in
4563 * target tile. */
4564 if (tile_city(target->tile) == NULL
4565 && fc_funcs->player_tile_vision_get(target->tile, actor->player,
4566 V_MAIN)
4567 && fc_funcs->player_tile_vision_get(target->tile, actor->player,
4568 V_INVIS)
4569 && fc_funcs->player_tile_vision_get(target->tile, actor->player,
4570 V_SUBSURFACE)) {
4571 bool hiding_extra = FALSE;
4572
4573 extra_type_iterate(pextra) {
4574 if (pextra->eus == EUS_HIDDEN
4575 && tile_has_extra(target->tile, pextra)) {
4576 hiding_extra = TRUE;
4577 break;
4578 }
4579 } extra_type_iterate_end;
4580
4581 if (!hiding_extra) {
4582 bool has_target = FALSE;
4583
4584 unit_list_iterate(target->tile->units, punit) {
4585 if (is_unit_reachable_at(punit, actor->unit, target->tile)) {
4586 has_target = TRUE;
4587 break;
4588 }
4589 } unit_list_iterate_end;
4590
4591 if (!has_target) {
4592 return TRI_NO;
4593 }
4594 }
4595 }
4596 }
4597 break;
4598 case ACTRES_ESTABLISH_EMBASSY:
4599 case ACTRES_SPY_INVESTIGATE_CITY:
4600 case ACTRES_SPY_POISON:
4601 case ACTRES_SPY_SABOTAGE_CITY:
4602 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
4603 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
4604 case ACTRES_SPY_STEAL_TECH:
4605 case ACTRES_SPY_INCITE_CITY:
4606 case ACTRES_SPY_SABOTAGE_UNIT:
4607 case ACTRES_STEAL_MAPS:
4608 case ACTRES_SPY_NUKE:
4609 case ACTRES_NUKE:
4610 case ACTRES_DESTROY_CITY:
4611 case ACTRES_EXPEL_UNIT:
4612 case ACTRES_DISBAND_UNIT:
4613 case ACTRES_CONVERT:
4614 case ACTRES_STRIKE_BUILDING:
4615 case ACTRES_STRIKE_PRODUCTION:
4616 case ACTRES_FORTIFY:
4617 case ACTRES_HOMELESS:
4618 case ACTRES_NONE:
4619 /* No known hard coded requirements. */
4620 break;
4621 }
4622
4623 return out;
4624}
4625
4626/**********************************************************************/
4632 static bool is_enabler_active(const struct action_enabler *enabler,
4633 const struct req_context *actor,
4634 const struct req_context *target)
4635{
4636 return are_reqs_active(actor, target != NULL ? target->player : NULL,
4637 &enabler->actor_reqs, RPT_CERTAIN)
4638 && are_reqs_active(target, actor != NULL ? actor->player : NULL,
4639 &enabler->target_reqs, RPT_CERTAIN);
4640}
4641
4642/**********************************************************************/
4651 static bool is_action_enabled(const struct civ_map *nmap,
4652 const action_id wanted_action,
4653 const struct req_context *actor,
4654 const struct req_context *target,
4655 const struct extra_type *target_extra,
4656 const struct city *actor_home)
4657{
4658 enum fc_tristate possible;
4659
4660 possible = is_action_possible(nmap, wanted_action, actor, target, target_extra,
4661 TRUE, actor_home);
4662
4663 if (possible != TRI_YES) {
4664 /* This context is omniscient. Should be yes or no. */
4665 fc_assert_msg(possible != TRI_MAYBE,
4666 "Is omniscient, should get yes or no.");
4667
4668 /* The action enablers are irrelevant since the action it self is
4669 * impossible. */
4670 return FALSE;
4671 }
4672
4673 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
4674 enabler) {
4675 if (is_enabler_active(enabler, actor, target)) {
4676 return TRUE;
4677 }
4678 } action_enabler_list_iterate_end;
4679
4680 return FALSE;
4681}
4682
4683/**********************************************************************/
4689static bool
4690is_action_enabled_unit_on_city_full(const struct civ_map *nmap,
4691 const action_id wanted_action,
4692 const struct unit *actor_unit,
4693 const struct city *actor_home,
4694 const struct tile *actor_tile,
4695 const struct city *target_city)
4696{
4697 const struct impr_type *target_building;
4698 const struct unit_type *target_utype;
4699
4700 if (actor_unit == NULL || target_city == NULL) {
4701 /* Can't do an action when actor or target are missing. */
4702 return FALSE;
4703 }
4704
4705 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4706 FALSE, "Action %s is performed by %s not %s",
4707 action_id_rule_name(wanted_action),
4708 action_actor_kind_name(
4709 action_id_get_actor_kind(wanted_action)),
4710 action_actor_kind_name(AAK_UNIT));
4711
4712 fc_assert_ret_val_msg(ATK_CITY
4713 == action_id_get_target_kind(wanted_action),
4714 FALSE, "Action %s is against %s not %s",
4715 action_id_rule_name(wanted_action),
4716 action_target_kind_name(
4717 action_id_get_target_kind(wanted_action)),
4718 action_target_kind_name(ATK_CITY));
4719
4720 fc_assert_ret_val(actor_tile, FALSE);
4721
4722 if (!unit_can_do_action(actor_unit, wanted_action)) {
4723 /* No point in continuing. */
4724 return FALSE;
4725 }
4726
4727 target_building = tgt_city_local_building(target_city);
4728 target_utype = tgt_city_local_utype(target_city);
4729
4730 return is_action_enabled(nmap, wanted_action,
4731 &(const struct req_context) {
4732 .player = unit_owner(actor_unit),
4733 .city = tile_city(actor_tile),
4734 .tile = actor_tile,
4735 .unit = actor_unit,
4736 .unittype = unit_type_get(actor_unit),
4737 },
4738 &(const struct req_context) {
4739 .player = city_owner(target_city),
4740 .city = target_city,
4741 .building = target_building,
4742 .tile = city_tile(target_city),
4743 .unittype = target_utype,
4744 },
4745 NULL,
4746 actor_home);
4747}
4748
4749/**********************************************************************/
4755 bool is_action_enabled_unit_on_city(const struct civ_map *nmap,
4756 const action_id wanted_action,
4757 const struct unit *actor_unit,
4758 const struct city *target_city)
4759{
4760 return is_action_enabled_unit_on_city_full(nmap, wanted_action, actor_unit,
4761 unit_home(actor_unit),
4762 unit_tile(actor_unit),
4763 target_city);
4764}
4765
4766/**********************************************************************/
4772static bool
4773is_action_enabled_unit_on_unit_full(const struct civ_map *nmap,
4774 const action_id wanted_action,
4775 const struct unit *actor_unit,
4776 const struct city *actor_home,
4777 const struct tile *actor_tile,
4778 const struct unit *target_unit)
4779{
4780 if (actor_unit == NULL || target_unit == NULL) {
4781 /* Can't do an action when actor or target are missing. */
4782 return FALSE;
4783 }
4784
4785 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4786 FALSE, "Action %s is performed by %s not %s",
4787 action_id_rule_name(wanted_action),
4788 action_actor_kind_name(
4789 action_id_get_actor_kind(wanted_action)),
4790 action_actor_kind_name(AAK_UNIT));
4791
4792 fc_assert_ret_val_msg(ATK_UNIT
4793 == action_id_get_target_kind(wanted_action),
4794 FALSE, "Action %s is against %s not %s",
4795 action_id_rule_name(wanted_action),
4796 action_target_kind_name(
4797 action_id_get_target_kind(wanted_action)),
4798 action_target_kind_name(ATK_UNIT));
4799
4800 fc_assert_ret_val(actor_tile, FALSE);
4801
4802 if (!unit_can_do_action(actor_unit, wanted_action)) {
4803 /* No point in continuing. */
4804 return FALSE;
4805 }
4806
4807 return is_action_enabled(nmap, wanted_action,
4808 &(const struct req_context) {
4809 .player = unit_owner(actor_unit),
4810 .city = tile_city(actor_tile),
4811 .tile = actor_tile,
4812 .unit = actor_unit,
4813 .unittype = unit_type_get(actor_unit),
4814 },
4815 &(const struct req_context) {
4816 .player = unit_owner(target_unit),
4817 .city = tile_city(unit_tile(target_unit)),
4818 .tile = unit_tile(target_unit),
4819 .unit = target_unit,
4820 .unittype = unit_type_get(target_unit),
4821 },
4822 NULL,
4823 actor_home);
4824}
4825
4826/**********************************************************************/
4832 bool is_action_enabled_unit_on_unit(const struct civ_map *nmap,
4833 const action_id wanted_action,
4834 const struct unit *actor_unit,
4835 const struct unit *target_unit)
4836{
4837 return is_action_enabled_unit_on_unit_full(nmap, wanted_action, actor_unit,
4838 unit_home(actor_unit),
4839 unit_tile(actor_unit),
4840 target_unit);
4841}
4842
4843/**********************************************************************/
4849static bool
4850is_action_enabled_unit_on_units_full(const struct civ_map *nmap,
4851 const action_id wanted_action,
4852 const struct unit *actor_unit,
4853 const struct city *actor_home,
4854 const struct tile *actor_tile,
4855 const struct tile *target_tile)
4856{
4857 const struct req_context *actor_ctxt;
4858
4859 if (actor_unit == NULL || target_tile == NULL
4860 || unit_list_size(target_tile->units) == 0) {
4861 /* Can't do an action when actor or target are missing. */
4862 return FALSE;
4863 }
4864
4865 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4866 FALSE, "Action %s is performed by %s not %s",
4867 action_id_rule_name(wanted_action),
4868 action_actor_kind_name(
4869 action_id_get_actor_kind(wanted_action)),
4870 action_actor_kind_name(AAK_UNIT));
4871
4872 fc_assert_ret_val_msg(ATK_UNITS
4873 == action_id_get_target_kind(wanted_action),
4874 FALSE, "Action %s is against %s not %s",
4875 action_id_rule_name(wanted_action),
4876 action_target_kind_name(
4877 action_id_get_target_kind(wanted_action)),
4878 action_target_kind_name(ATK_UNITS));
4879
4880 fc_assert_ret_val(actor_tile, FALSE);
4881
4882 if (!unit_can_do_action(actor_unit, wanted_action)) {
4883 /* No point in continuing. */
4884 return FALSE;
4885 }
4886
4887 actor_ctxt = &(const struct req_context) {
4888 .player = unit_owner(actor_unit),
4889 .city = tile_city(actor_tile),
4890 .tile = actor_tile,
4891 .unit = actor_unit,
4892 .unittype = unit_type_get(actor_unit),
4893 };
4894
4895 unit_list_iterate(target_tile->units, target_unit) {
4896 if (!is_action_enabled(nmap, wanted_action, actor_ctxt,
4897 &(const struct req_context) {
4898 .player = unit_owner(target_unit),
4899 .city = tile_city(unit_tile(target_unit)),
4900 .tile = unit_tile(target_unit),
4901 .unit = target_unit,
4902 .unittype = unit_type_get(target_unit),
4903 },
4904 NULL, actor_home)) {
4905 /* One unit makes it impossible for all units. */
4906 return FALSE;
4907 }
4908 } unit_list_iterate_end;
4909
4910 /* Not impossible for any of the units at the tile. */
4911 return TRUE;
4912}
4913
4914/**********************************************************************/
4920 bool is_action_enabled_unit_on_units(const struct civ_map *nmap,
4921 const action_id wanted_action,
4922 const struct unit *actor_unit,
4923 const struct tile *target_tile)
4924{
4925 return is_action_enabled_unit_on_units_full(nmap, wanted_action, actor_unit,
4926 unit_home(actor_unit),
4927 unit_tile(actor_unit),
4928 target_tile);
4929}
4930
4931/**********************************************************************/
4937static bool
4938is_action_enabled_unit_on_tile_full(const struct civ_map *nmap,
4939 const action_id wanted_action,
4940 const struct unit *actor_unit,
4941 const struct city *actor_home,
4942 const struct tile *actor_tile,
4943 const struct tile *target_tile,
4944 const struct extra_type *target_extra)
4945{
4946 if (actor_unit == NULL || target_tile == NULL) {
4947 /* Can't do an action when actor or target are missing. */
4948 return FALSE;
4949 }
4950
4951 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4952 FALSE, "Action %s is performed by %s not %s",
4953 action_id_rule_name(wanted_action),
4954 action_actor_kind_name(
4955 action_id_get_actor_kind(wanted_action)),
4956 action_actor_kind_name(AAK_UNIT));
4957
4958 fc_assert_ret_val_msg(ATK_TILE
4959 == action_id_get_target_kind(wanted_action),
4960 FALSE, "Action %s is against %s not %s",
4961 action_id_rule_name(wanted_action),
4962 action_target_kind_name(
4963 action_id_get_target_kind(wanted_action)),
4964 action_target_kind_name(ATK_TILE));
4965
4966 fc_assert_ret_val(actor_tile, FALSE);
4967
4968 if (!unit_can_do_action(actor_unit, wanted_action)) {
4969 /* No point in continuing. */
4970 return FALSE;
4971 }
4972
4973 return is_action_enabled(nmap, wanted_action,
4974 &(const struct req_context) {
4975 .player = unit_owner(actor_unit),
4976 .city = tile_city(actor_tile),
4977 .tile = actor_tile,
4978 .unit = actor_unit,
4979 .unittype = unit_type_get(actor_unit),
4980 },
4981 &(const struct req_context) {
4982 .player = tile_owner(target_tile),
4983 .city = tile_city(target_tile),
4984 .tile = target_tile,
4985 },
4986 target_extra,
4987 actor_home);
4988}
4989
4990/**********************************************************************/
4996 bool is_action_enabled_unit_on_tile(const struct civ_map *nmap,
4997 const action_id wanted_action,
4998 const struct unit *actor_unit,
4999 const struct tile *target_tile,
5000 const struct extra_type *target_extra)
5001{
5002 return is_action_enabled_unit_on_tile_full(nmap, wanted_action, actor_unit,
5003 unit_home(actor_unit),
5004 unit_tile(actor_unit),
5005 target_tile, target_extra);
5006}
5007
5008/**********************************************************************/
5014static bool
5015is_action_enabled_unit_on_extras_full(const struct civ_map *nmap,
5016 const action_id wanted_action,
5017 const struct unit *actor_unit,
5018 const struct city *actor_home,
5019 const struct tile *actor_tile,
5020 const struct tile *target_tile,
5021 const struct extra_type *target_extra)
5022{
5023 if (actor_unit == NULL || target_tile == NULL) {
5024 /* Can't do an action when actor or target are missing. */
5025 return FALSE;
5026 }
5027
5028 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
5029 FALSE, "Action %s is performed by %s not %s",
5030 action_id_rule_name(wanted_action),
5031 action_actor_kind_name(
5032 action_id_get_actor_kind(wanted_action)),
5033 action_actor_kind_name(AAK_UNIT));
5034
5035 fc_assert_ret_val_msg(ATK_EXTRAS
5036 == action_id_get_target_kind(wanted_action),
5037 FALSE, "Action %s is against %s not %s",
5038 action_id_rule_name(wanted_action),
5039 action_target_kind_name(
5040 action_id_get_target_kind(wanted_action)),
5041 action_target_kind_name(ATK_EXTRAS));
5042
5043 fc_assert_ret_val(actor_tile, FALSE);
5044
5045 if (!unit_can_do_action(actor_unit, wanted_action)) {
5046 /* No point in continuing. */
5047 return FALSE;
5048 }
5049
5050 return is_action_enabled(nmap, wanted_action,
5051 &(const struct req_context) {
5052 .player = unit_owner(actor_unit),
5053 .city = tile_city(actor_tile),
5054 .tile = actor_tile,
5055 .unit = actor_unit,
5056 .unittype = unit_type_get(actor_unit),
5057 },
5058 &(const struct req_context) {
5059 .player = target_tile->extras_owner,
5060 .city = tile_city(target_tile),
5061 .tile = target_tile,
5062 },
5063 target_extra,
5064 actor_home);
5065}
5066
5067/**********************************************************************/
5073 bool is_action_enabled_unit_on_extras(const struct civ_map *nmap,
5074 const action_id wanted_action,
5075 const struct unit *actor_unit,
5076 const struct tile *target_tile,
5077 const struct extra_type *target_extra)
5078{
5079 return is_action_enabled_unit_on_extras_full(nmap, wanted_action, actor_unit,
5080 unit_home(actor_unit),
5081 unit_tile(actor_unit),
5082 target_tile, target_extra);
5083}
5084
5085/**********************************************************************/
5092static bool
5093is_action_enabled_unit_on_self_full(const struct civ_map *nmap,
5094 const action_id wanted_action,
5095 const struct unit *actor_unit,
5096 const struct city *actor_home,
5097 const struct tile *actor_tile)
5098{
5099 if (actor_unit == NULL) {
5100 /* Can't do an action when the actor is missing. */
5101 return FALSE;
5102 }
5103
5104 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
5105 FALSE, "Action %s is performed by %s not %s",
5106 action_id_rule_name(wanted_action),
5107 action_actor_kind_name(
5108 action_id_get_actor_kind(wanted_action)),
5109 action_actor_kind_name(AAK_UNIT));
5110
5111 fc_assert_ret_val_msg(ATK_SELF
5112 == action_id_get_target_kind(wanted_action),
5113 FALSE, "Action %s is against %s not %s",
5114 action_id_rule_name(wanted_action),
5115 action_target_kind_name(
5116 action_id_get_target_kind(wanted_action)),
5117 action_target_kind_name(ATK_SELF));
5118
5119 fc_assert_ret_val(actor_tile, FALSE);
5120
5121 if (!unit_can_do_action(actor_unit, wanted_action)) {
5122 /* No point in continuing. */
5123 return FALSE;
5124 }
5125
5126 return is_action_enabled(nmap, wanted_action,
5127 &(const struct req_context) {
5128 .player = unit_owner(actor_unit),
5129 .city = tile_city(actor_tile),
5130 .tile = actor_tile,
5131 .unit = actor_unit,
5132 .unittype = unit_type_get(actor_unit),
5133 },
5134 NULL, NULL,
5135 actor_home);
5136}
5137
5138/**********************************************************************/
5145 bool is_action_enabled_unit_on_self(const struct civ_map *nmap,
5146 const action_id wanted_action,
5147 const struct unit *actor_unit)
5148{
5149 return is_action_enabled_unit_on_self_full(nmap, wanted_action, actor_unit,
5150 unit_home(actor_unit),
5151 unit_tile(actor_unit));
5152}
5153
5154/**********************************************************************/
5172static enum fc_tristate
5173action_enabled_local(const action_id wanted_action,
5174 const struct req_context *actor,
5175 const struct req_context *target)
5176{
5177 enum fc_tristate current;
5178 enum fc_tristate result;
5179
5180 if (actor == NULL || actor->player == NULL) {
5181 /* Need actor->player for point of view */
5182 return TRI_MAYBE;
5183 }
5184
5185 if (target == NULL) {
5186 target = req_context_empty();
5187 }
5188
5189 result = TRI_NO;
5190 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
5191 enabler) {
5192 current = fc_tristate_and(mke_eval_reqs(actor->player, actor,
5193 target->player,
5194 &enabler->actor_reqs,
5195 RPT_CERTAIN),
5196 mke_eval_reqs(actor->player, target,
5197 actor->player,
5198 &enabler->target_reqs,
5199 RPT_CERTAIN));
5200 if (current == TRI_YES) {
5201 return TRI_YES;
5202 } else if (current == TRI_MAYBE) {
5203 result = TRI_MAYBE;
5204 }
5205 } action_enabler_list_iterate_end;
5206
5207 return result;
5208}
5209
5210/**********************************************************************/
5219 static bool is_effect_val_known(enum effect_type effect_type,
5220 const struct player *pov_player,
5221 const struct req_context *context,
5222 const struct player *other_player)
5223{
5224 effect_list_iterate(get_effects(effect_type), peffect) {
5225 if (TRI_MAYBE == mke_eval_reqs(pov_player, context,
5226 other_player,
5227 &(peffect->reqs), RPT_CERTAIN)) {
5228 return FALSE;
5229 }
5230 } effect_list_iterate_end;
5231
5232 return TRUE;
5233}
5234
5235/**********************************************************************/
5238static enum fc_tristate
5239tech_can_be_stolen(const struct player *actor_player,
5240 const struct player *target_player)
5241{
5242 const struct research *actor_research = research_get(actor_player);
5243 const struct research *target_research = research_get(target_player);
5244
5245 if (actor_research != target_research) {
5246 if (can_see_techs_of_target(actor_player, target_player)) {
5247 advance_iterate(A_FIRST, padvance) {
5248 Tech_type_id i = advance_number(padvance);
5249
5250 if (research_invention_state(target_research, i) == TECH_KNOWN
5251 && research_invention_gettable(actor_research, i,
5252 game.info.tech_steal_allow_holes)
5253 && (research_invention_state(actor_research, i) == TECH_UNKNOWN
5254 || (research_invention_state(actor_research, i)
5255 == TECH_PREREQS_KNOWN))) {
5256 return TRI_YES;
5257 }
5258 } advance_iterate_end;
5259 } else {
5260 return TRI_MAYBE;
5261 }
5262 }
5263
5264 return TRI_NO;
5265}
5266
5267/**********************************************************************/
5275 static struct act_prob ap_dipl_battle_win(const struct unit *pattacker,
5276 const struct unit *pdefender)
5277{
5278 /* Keep unconverted until the end to avoid scaling each step */
5279 int chance;
5280 struct act_prob out;
5281
5282 /* Superspy always win */
5283 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
5284 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
5285 return ACTPROB_IMPOSSIBLE;
5286 }
5287 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
5288 /* An attacking UTYF_SUPERSPY will defeat every possible defender
5289 * except another UTYF_SUPERSPY. */
5290 return ACTPROB_CERTAIN;
5291 }
5292
5293 /* Base chance is 50% */
5294 chance = 50;
5295
5296 /* Spy attack bonus */
5297 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
5298 chance += 25;
5299 }
5300
5301 /* Spy defense bonus */
5302 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
5303 chance -= 25;
5304 }
5305
5306 /* Veteran attack and defense bonus */
5307 {
5308 const struct veteran_level *vatt =
5309 utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
5310 const struct veteran_level *vdef =
5311 utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
5312
5313 chance += vatt->power_fact - vdef->power_fact;
5314 }
5315
5316 /* Defense bonus. */
5317 {
5318 const struct req_context defender_ctxt = {
5319 .player = tile_owner(pdefender->tile),
5320 .city = tile_city(pdefender->tile),
5321 .tile = pdefender->tile,
5322 };
5323 if (!is_effect_val_known(EFT_SPY_RESISTANT, unit_owner(pattacker),
5324 &defender_ctxt,
5325 NULL)) {
5326 return ACTPROB_NOT_KNOWN;
5327 }
5328
5329 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
5330 chance -= chance * get_target_bonus_effects(
5331 NULL,
5332 &defender_ctxt,
5333 NULL,
5334 EFT_SPY_RESISTANT
5335 ) / 100;
5336 }
5337
5338 chance = CLIP(0, chance, 100);
5339
5340 /* Convert to action probability */
5341 out.min = chance * ACTPROB_VAL_1_PCT;
5342 out.max = chance * ACTPROB_VAL_1_PCT;
5343
5344 return out;
5345}
5346
5347/**********************************************************************/
5352 static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
5353 const struct unit *pvictim,
5354 const struct tile *tgt_tile)
5355{
5356 struct unit *pdefender;
5357
5358 if (!can_player_see_hypotetic_units_at(unit_owner(pattacker),
5359 tgt_tile)) {
5360 /* Don't leak information about unseen defenders. */
5361 return ACTPROB_NOT_KNOWN;
5362 }
5363
5364 pdefender = get_diplomatic_defender(pattacker, pvictim, tgt_tile);
5365
5366 if (pdefender) {
5367 /* There will be a diplomatic battle instead of an action. */
5368 return ap_dipl_battle_win(pattacker, pdefender);
5369 };
5370
5371 /* No diplomatic battle will occur. */
5372 return ACTPROB_CERTAIN;
5373}
5374
5375/**********************************************************************/
5378 static struct act_prob act_prob_unseen_target(const struct civ_map *nmap,
5379 action_id act_id,
5380 const struct unit *actor_unit)
5381{
5382 if (action_maybe_possible_actor_unit(nmap, act_id, actor_unit)) {
5383 /* Unknown because the target is unseen. */
5384 return ACTPROB_NOT_KNOWN;
5385 } else {
5386 /* The actor it self can't do this. */
5387 return ACTPROB_IMPOSSIBLE;
5388 }
5389}
5390
5391/**********************************************************************/
5395static struct act_prob
5396action_prob_pre_action_dice_roll(const struct player *act_player,
5397 const struct unit *act_unit,
5398 const struct city *tgt_city,
5399 const struct player *tgt_player,
5400 const struct action *paction)
5401{
5402 if (is_effect_val_known(EFT_ACTION_ODDS_PCT, act_player,
5403 &(const struct req_context) {
5404 .player = act_player,
5405 .city = tgt_city,
5406 .unit = act_unit,
5407 .unittype = unit_type_get(act_unit),
5408 },
5409 tgt_player)) {
5410 int unconverted = action_dice_roll_odds(act_player, act_unit, tgt_city,
5411 tgt_player, paction);
5412 struct act_prob result = { .min = unconverted * ACTPROB_VAL_1_PCT,
5413 .max = unconverted * ACTPROB_VAL_1_PCT };
5414
5415 return result;
5416 } else {
5417 /* Could be improved to return a more exact probability in some cases.
5418 * Example: The player has enough information to know that the
5419 * probability always will be above 25% and always under 75% because
5420 * the only effect with unknown requirements that may apply adds (or
5421 * subtracts) 50% while all the requirements of the other effects that
5422 * may apply are known. */
5423 return ACTPROB_NOT_KNOWN;
5424 }
5425}
5426
5427/**********************************************************************/
5432static struct act_prob
5433action_prob_battle_then_dice_roll(const struct player *act_player,
5434 const struct unit *act_unit,
5435 const struct city *tgt_city,
5436 const struct unit *tgt_unit,
5437 const struct tile *tgt_tile,
5438 const struct player *tgt_player,
5439 const struct action *paction)
5440{
5441 struct act_prob battle;
5442 struct act_prob dice_roll;
5443
5444 battle = ACTPROB_CERTAIN;
5445 switch (action_get_battle_kind(paction)) {
5446 case ABK_NONE:
5447 /* No pre action battle. */
5448 break;
5449 case ABK_DIPLOMATIC:
5450 battle = ap_diplomat_battle(act_unit, tgt_unit, tgt_tile);
5451 break;
5452 case ABK_STANDARD:
5453 /* Not supported here yet. Implement when users appear. */
5454 fc_assert(action_get_battle_kind(paction) != ABK_STANDARD);
5455 break;
5456 case ABK_COUNT:
5457 fc_assert(action_get_battle_kind(paction) != ABK_COUNT);
5458 break;
5459 }
5460
5461 dice_roll = action_prob_pre_action_dice_roll(act_player, act_unit,
5462 tgt_city, tgt_player,
5463 paction);
5464
5465 return action_prob_and(&battle, &dice_roll);
5466}
5467
5468/**********************************************************************/
5479static struct act_prob
5480action_prob(const struct civ_map *nmap,
5481 const action_id wanted_action,
5482 const struct req_context *actor,
5483 const struct city *actor_home,
5484 const struct req_context *target,
5485 const struct extra_type *target_extra)
5486{
5487 int known;
5488 struct act_prob chance;
5489 const struct action *paction = action_by_number(wanted_action);
5490
5491 if (actor == NULL) {
5492 actor = req_context_empty();
5493 }
5494 if (target == NULL) {
5495 target = req_context_empty();
5496 }
5497
5498 known = is_action_possible(nmap, wanted_action, actor, target,
5499 target_extra,
5500 FALSE, actor_home);
5501
5502 if (known == TRI_NO) {
5503 /* The action enablers are irrelevant since the action it self is
5504 * impossible. */
5505 return ACTPROB_IMPOSSIBLE;
5506 }
5507
5508 chance = ACTPROB_NOT_IMPLEMENTED;
5509
5510 known = fc_tristate_and(known,
5511 action_enabled_local(wanted_action,
5512 actor, target));
5513
5514 switch (paction->result) {
5515 case ACTRES_SPY_POISON:
5516 /* All uncertainty comes from potential diplomatic battles and the
5517 * (diplchance server setting and the) Action_Odds_Pct effect controlled
5518 * dice roll before the action. */
5519 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
5520 target->city, target->unit,
5521 target->tile, target->player,
5522 paction);
5523 break;
5524 case ACTRES_SPY_STEAL_GOLD:
5525 /* TODO */
5526 break;
5527 case ACTRES_SPY_SPREAD_PLAGUE:
5528 /* TODO */
5529 break;
5530 case ACTRES_STEAL_MAPS:
5531 /* TODO */
5532 break;
5533 case ACTRES_SPY_SABOTAGE_UNIT:
5534 /* All uncertainty comes from potential diplomatic battles. */
5535 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile);
5536 break;
5537 case ACTRES_SPY_BRIBE_UNIT:
5538 /* All uncertainty comes from potential diplomatic battles. */
5539 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile);
5540 break;
5541 case ACTRES_SPY_ATTACK:
5542 /* All uncertainty comes from potential diplomatic battles. */
5543 chance = ap_diplomat_battle(actor->unit, NULL, target->tile);
5544 break;
5545 case ACTRES_SPY_SABOTAGE_CITY:
5546 /* TODO */
5547 break;
5548 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
5549 /* TODO */
5550 break;
5551 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
5552 /* TODO */
5553 break;
5554 case ACTRES_SPY_INCITE_CITY:
5555 /* TODO */
5556 break;
5557 case ACTRES_ESTABLISH_EMBASSY:
5558 chance = ACTPROB_CERTAIN;
5559 break;
5560 case ACTRES_SPY_STEAL_TECH:
5561 /* Do the victim have anything worth taking? */
5562 known = fc_tristate_and(known,
5563 tech_can_be_stolen(actor->player,
5564 target->player));
5565
5566 /* TODO: Calculate actual chance */
5567
5568 break;
5569 case ACTRES_SPY_TARGETED_STEAL_TECH:
5570 /* Do the victim have anything worth taking? */
5571 known = fc_tristate_and(known,
5572 tech_can_be_stolen(actor->player,
5573 target->player));
5574
5575 /* TODO: Calculate actual chance */
5576
5577 break;
5578 case ACTRES_SPY_INVESTIGATE_CITY:
5579 /* There is no risk that the city won't get investigated. */
5580 chance = ACTPROB_CERTAIN;
5581 break;
5582 case ACTRES_TRADE_ROUTE:
5583 /* TODO */
5584 break;
5585 case ACTRES_MARKETPLACE:
5586 /* Possible when not blocked by is_action_possible() */
5587 chance = ACTPROB_CERTAIN;
5588 break;
5589 case ACTRES_HELP_WONDER:
5590 /* Possible when not blocked by is_action_possible() */
5591 chance = ACTPROB_CERTAIN;
5592 break;
5593 case ACTRES_CAPTURE_UNITS:
5594 /* No battle is fought first. */
5595 chance = ACTPROB_CERTAIN;
5596 break;
5597 case ACTRES_EXPEL_UNIT:
5598 /* No battle is fought first. */
5599 chance = ACTPROB_CERTAIN;
5600 break;
5601 case ACTRES_BOMBARD:
5602 /* No battle is fought first. */
5603 chance = ACTPROB_CERTAIN;
5604 break;
5605 case ACTRES_FOUND_CITY:
5606 /* Possible when not blocked by is_action_possible() */
5607 chance = ACTPROB_CERTAIN;
5608 break;
5609 case ACTRES_JOIN_CITY:
5610 /* Possible when not blocked by is_action_possible() */
5611 chance = ACTPROB_CERTAIN;
5612 break;
5613 case ACTRES_SPY_NUKE:
5614 /* All uncertainty comes from potential diplomatic battles and the
5615 * (diplchance server setting and the) Action_Odds_Pct effect controlled
5616 * dice roll before the action. */
5617 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
5618 target->city, target->unit,
5619 target->tile,
5620 target->player,
5621 paction);
5622 break;
5623 case ACTRES_NUKE:
5624 /* TODO */
5625 break;
5626 case ACTRES_NUKE_UNITS:
5627 /* TODO */
5628 break;
5629 case ACTRES_DESTROY_CITY:
5630 /* No battle is fought first. */
5631 chance = ACTPROB_CERTAIN;
5632 break;
5633 case ACTRES_DISBAND_UNIT_RECOVER:
5634 /* No battle is fought first. */
5635 chance = ACTPROB_CERTAIN;
5636 break;
5637 case ACTRES_DISBAND_UNIT:
5638 /* No battle is fought first. */
5639 chance = ACTPROB_CERTAIN;
5640 break;
5641 case ACTRES_HOME_CITY:
5642 /* No battle is fought first. */
5643 chance = ACTPROB_CERTAIN;
5644 break;
5645 case ACTRES_HOMELESS:
5646 /* No battle is fought first. */
5647 chance = ACTPROB_CERTAIN;
5648 break;
5649 case ACTRES_UPGRADE_UNIT:
5650 /* No battle is fought first. */
5651 chance = ACTPROB_CERTAIN;
5652 break;
5653 case ACTRES_PARADROP:
5654 case ACTRES_PARADROP_CONQUER:
5655 /* TODO */
5656 break;
5657 case ACTRES_AIRLIFT:
5658 /* Possible when not blocked by is_action_possible() */
5659 chance = ACTPROB_CERTAIN;
5660 break;
5661 case ACTRES_ATTACK:
5662 {
5663 struct unit *defender_unit
5664 = get_defender(nmap, actor->unit, target->tile);
5665
5666 if (can_player_see_unit(actor->player, defender_unit)) {
5667 double unconverted
5668 = unit_win_chance(nmap, actor->unit, defender_unit);
5669
5670 chance.min = MAX(ACTPROB_VAL_MIN,
5671 floor((double)ACTPROB_VAL_MAX * unconverted));
5672 chance.max = MIN(ACTPROB_VAL_MAX,
5673 ceil((double)ACTPROB_VAL_MAX * unconverted));
5674 } else if (known == TRI_YES) {
5675 known = TRI_MAYBE;
5676 }
5677 }
5678 break;
5679 case ACTRES_STRIKE_BUILDING:
5680 /* TODO: not implemented yet because:
5681 * - dice roll 100% * Action_Odds_Pct could be handled with
5682 * action_prob_pre_action_dice_roll().
5683 * - sub target building may be missing. May be missing without player
5684 * knowledge if it isn't visible. See is_improvement_visible() and
5685 * can_player_see_city_internals(). */
5686 break;
5687 case ACTRES_STRIKE_PRODUCTION:
5688 /* All uncertainty comes from the (diplchance server setting and the)
5689 * Action_Odds_Pct effect controlled dice roll before the action. */
5690 chance = action_prob_pre_action_dice_roll(actor->player, actor->unit,
5691 target->city, target->player,
5692 paction);
5693 break;
5694 case ACTRES_CONQUER_CITY:
5695 /* No battle is fought first. */
5696 chance = ACTPROB_CERTAIN;
5697 break;
5698 case ACTRES_CONQUER_EXTRAS:
5699 /* No battle is fought first. */
5700 chance = ACTPROB_CERTAIN;
5701 break;
5702 case ACTRES_HEAL_UNIT:
5703 /* No battle is fought first. */
5704 chance = ACTPROB_CERTAIN;
5705 break;
5706 case ACTRES_TRANSFORM_TERRAIN:
5707 case ACTRES_CULTIVATE:
5708 case ACTRES_PLANT:
5709 case ACTRES_PILLAGE:
5710 case ACTRES_CLEAN_POLLUTION:
5711 case ACTRES_CLEAN_FALLOUT:
5712 case ACTRES_FORTIFY:
5713 case ACTRES_ROAD:
5714 case ACTRES_CONVERT:
5715 case ACTRES_BASE:
5716 case ACTRES_MINE:
5717 case ACTRES_IRRIGATE:
5718 chance = ACTPROB_CERTAIN;
5719 break;
5720 case ACTRES_TRANSPORT_ALIGHT:
5721 chance = ACTPROB_CERTAIN;
5722 break;
5723 case ACTRES_TRANSPORT_BOARD:
5724 chance = ACTPROB_CERTAIN;
5725 break;
5726 case ACTRES_TRANSPORT_EMBARK:
5727 chance = ACTPROB_CERTAIN;
5728 break;
5729 case ACTRES_TRANSPORT_UNLOAD:
5730 chance = ACTPROB_CERTAIN;
5731 break;
5732 case ACTRES_TRANSPORT_DISEMBARK:
5733 chance = ACTPROB_CERTAIN;
5734 break;
5735 case ACTRES_HUT_ENTER:
5736 case ACTRES_HUT_FRIGHTEN:
5737 /* Entering the hut happens with a probability of 100%. What happens
5738 * next is probably up to dice rolls in Lua. */
5739 chance = ACTPROB_NOT_IMPLEMENTED;
5740 break;
5741 case ACTRES_UNIT_MOVE:
5742 chance = ACTPROB_CERTAIN;
5743 break;
5744 case ACTRES_NONE:
5745 /* Accommodate ruleset authors that wishes to roll the dice in Lua.
5746 * Would be ACTPROB_CERTAIN if not for that. */
5747 /* TODO: maybe allow the ruleset author to give a probability from
5748 * Lua? */
5749 chance = ACTPROB_NOT_IMPLEMENTED;
5750 break;
5751 }
5752
5753 /* Non signal action probabilities should be in range. */
5754 fc_assert_action((action_prob_is_signal(chance)
5755 || chance.max <= ACTPROB_VAL_MAX),
5756 chance.max = ACTPROB_VAL_MAX);
5757 fc_assert_action((action_prob_is_signal(chance)
5758 || chance.min >= ACTPROB_VAL_MIN),
5759 chance.min = ACTPROB_VAL_MIN);
5760
5761 switch (known) {
5762 case TRI_NO:
5763 return ACTPROB_IMPOSSIBLE;
5764 break;
5765 case TRI_MAYBE:
5766 return ACTPROB_NOT_KNOWN;
5767 break;
5768 case TRI_YES:
5769 return chance;
5770 break;
5771 };
5772
5773 fc_assert_msg(FALSE, "Should be yes, maybe or no");
5774
5775 return ACTPROB_NOT_IMPLEMENTED;
5776}
5777
5778/**********************************************************************/
5782static struct act_prob
5783action_prob_vs_city_full(const struct civ_map *nmap,
5784 const struct unit *actor_unit,
5785 const struct city *actor_home,
5786 const struct tile *actor_tile,
5787 const action_id act_id,
5788 const struct city *target_city)
5789{
5790 const struct impr_type *target_building;
5791 const struct unit_type *target_utype;
5792 const struct action *act = action_by_number(act_id);
5793
5794 if (actor_unit == NULL || target_city == NULL) {
5795 /* Can't do an action when actor or target are missing. */
5796 return ACTPROB_IMPOSSIBLE;
5797 }
5798
5799 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5800 ACTPROB_IMPOSSIBLE,
5801 "Action %s is performed by %s not %s",
5802 action_id_rule_name(act_id),
5803 action_actor_kind_name(
5804 action_id_get_actor_kind(act_id)),
5805 action_actor_kind_name(AAK_UNIT));
5806
5807 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
5808 ACTPROB_IMPOSSIBLE,
5809 "Action %s is against %s not %s",
5810 action_id_rule_name(act_id),
5811 action_target_kind_name(
5812 action_id_get_target_kind(act_id)),
5813 action_target_kind_name(ATK_CITY));
5814
5815 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5816
5817 if (!unit_can_do_action(actor_unit, act_id)) {
5818 /* No point in continuing. */
5819 return ACTPROB_IMPOSSIBLE;
5820 }
5821
5822 /* Doesn't leak information about city position since an unknown city
5823 * can't be targeted and a city can't move. */
5824 if (!action_id_distance_accepted(act_id,
5825 real_map_distance(actor_tile,
5826 city_tile(target_city)))) {
5827 /* No point in continuing. */
5828 return ACTPROB_IMPOSSIBLE;
5829 }
5830
5831 /* Doesn't leak information since it must be 100% certain from the
5832 * player's perspective that the blocking action is legal. */
5833 if (action_is_blocked_by(act, actor_unit,
5834 city_tile(target_city), target_city, NULL)) {
5835 /* Don't offer to perform an action known to be blocked. */
5836 return ACTPROB_IMPOSSIBLE;
5837 }
5838
5839 if (!player_can_see_city_externals(unit_owner(actor_unit), target_city)) {
5840 /* The invisible city at this tile may, as far as the player knows, not
5841 * exist anymore. */
5842 return act_prob_unseen_target(nmap, act_id, actor_unit);
5843 }
5844
5845 target_building = tgt_city_local_building(target_city);
5846 target_utype = tgt_city_local_utype(target_city);
5847
5848 return action_prob(nmap, act_id,
5849 &(const struct req_context) {
5850 .player = unit_owner(actor_unit),
5851 .city = tile_city(actor_tile),
5852 .tile = actor_tile,
5853 .unit = actor_unit,
5854 .unittype = unit_type_get(actor_unit),
5855 },
5856 actor_home,
5857 &(const struct req_context) {
5858 .player = city_owner(target_city),
5859 .city = target_city,
5860 .building = target_building,
5861 .tile = city_tile(target_city),
5862 .unittype = target_utype,
5863 }, NULL);
5864}
5865
5866/**********************************************************************/
5870 struct act_prob action_prob_vs_city(const struct civ_map *nmap,
5871 const struct unit *actor_unit,
5872 const action_id act_id,
5873 const struct city *target_city)
5874{
5875 return action_prob_vs_city_full(nmap, actor_unit,
5876 unit_home(actor_unit),
5877 unit_tile(actor_unit),
5878 act_id, target_city);
5879}
5880
5881/**********************************************************************/
5885static struct act_prob
5886action_prob_vs_unit_full(const struct civ_map *nmap,
5887 const struct unit *actor_unit,
5888 const struct city *actor_home,
5889 const struct tile *actor_tile,
5890 const action_id act_id,
5891 const struct unit *target_unit)
5892{
5893 if (actor_unit == NULL || target_unit == NULL) {
5894 /* Can't do an action when actor or target are missing. */
5895 return ACTPROB_IMPOSSIBLE;
5896 }
5897
5898 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5899 ACTPROB_IMPOSSIBLE,
5900 "Action %s is performed by %s not %s",
5901 action_id_rule_name(act_id),
5902 action_actor_kind_name(
5903 action_id_get_actor_kind(act_id)),
5904 action_actor_kind_name(AAK_UNIT));
5905
5906 fc_assert_ret_val_msg(ATK_UNIT == action_id_get_target_kind(act_id),
5907 ACTPROB_IMPOSSIBLE,
5908 "Action %s is against %s not %s",
5909 action_id_rule_name(act_id),
5910 action_target_kind_name(
5911 action_id_get_target_kind(act_id)),
5912 action_target_kind_name(ATK_UNIT));
5913
5914 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5915
5916 if (!unit_can_do_action(actor_unit, act_id)) {
5917 /* No point in continuing. */
5918 return ACTPROB_IMPOSSIBLE;
5919 }
5920
5921 /* Doesn't leak information about unit position since an unseen unit can't
5922 * be targeted. */
5923 if (!action_id_distance_accepted(act_id,
5924 real_map_distance(actor_tile,
5925 unit_tile(target_unit)))) {
5926 /* No point in continuing. */
5927 return ACTPROB_IMPOSSIBLE;
5928 }
5929
5930 return action_prob(nmap, act_id,
5931 &(const struct req_context) {
5932 .player = unit_owner(actor_unit),
5933 .city = tile_city(actor_tile),
5934 .tile = actor_tile,
5935 .unit = actor_unit,
5936 .unittype = unit_type_get(actor_unit),
5937 },
5938 actor_home,
5939 &(const struct req_context) {
5940 .player = unit_owner(target_unit),
5941 .city = tile_city(unit_tile(target_unit)),
5942 .tile = unit_tile(target_unit),
5943 .unit = target_unit,
5944 .unittype = unit_type_get(target_unit),
5945 },
5946 NULL);
5947}
5948
5949/**********************************************************************/
5953 struct act_prob action_prob_vs_unit(const struct civ_map *nmap,
5954 const struct unit *actor_unit,
5955 const action_id act_id,
5956 const struct unit *target_unit)
5957{
5958 return action_prob_vs_unit_full(nmap, actor_unit,
5959 unit_home(actor_unit),
5960 unit_tile(actor_unit),
5961 act_id,
5962 target_unit);
5963}
5964
5965/**********************************************************************/
5969static struct act_prob
5970action_prob_vs_units_full(const struct civ_map *nmap,
5971 const struct unit *actor_unit,
5972 const struct city *actor_home,
5973 const struct tile *actor_tile,
5974 const action_id act_id,
5975 const struct tile *target_tile)
5976{
5977 struct act_prob prob_all;
5978 const struct req_context *actor_ctxt;
5979 const struct action *act = action_by_number(act_id);
5980
5981 if (actor_unit == NULL || target_tile == NULL) {
5982 /* Can't do an action when actor or target are missing. */
5983 return ACTPROB_IMPOSSIBLE;
5984 }
5985
5986 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5987 ACTPROB_IMPOSSIBLE,
5988 "Action %s is performed by %s not %s",
5989 action_id_rule_name(act_id),
5990 action_actor_kind_name(
5991 action_id_get_actor_kind(act_id)),
5992 action_actor_kind_name(AAK_UNIT));
5993
5994 fc_assert_ret_val_msg(ATK_UNITS == action_id_get_target_kind(act_id),
5995 ACTPROB_IMPOSSIBLE,
5996 "Action %s is against %s not %s",
5997 action_id_rule_name(act_id),
5998 action_target_kind_name(
5999 action_id_get_target_kind(act_id)),
6000 action_target_kind_name(ATK_UNITS));
6001
6002 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
6003
6004 if (!unit_can_do_action(actor_unit, act_id)) {
6005 /* No point in continuing. */
6006 return ACTPROB_IMPOSSIBLE;
6007 }
6008
6009 /* Doesn't leak information about unit stack position since it is
6010 * specified as a tile and an unknown tile's position is known. */
6011 if (!action_id_distance_accepted(act_id,
6012 real_map_distance(actor_tile,
6013 target_tile))) {
6014 /* No point in continuing. */
6015 return ACTPROB_IMPOSSIBLE;
6016 }
6017
6018 /* Doesn't leak information since the actor player can see the target
6019 * tile. */
6020 if (tile_is_seen(target_tile, unit_owner(actor_unit))
6021 && tile_city(target_tile) != NULL
6022 && !utype_can_do_act_if_tgt_citytile(unit_type_get(actor_unit),
6023 act_id,
6024 CITYT_CENTER, TRUE)) {
6025 /* Don't offer to perform actions that never can target a unit stack in
6026 * a city. */
6027 return ACTPROB_IMPOSSIBLE;
6028 }
6029
6030 /* Doesn't leak information since it must be 100% certain from the
6031 * player's perspective that the blocking action is legal. */
6032 unit_list_iterate(target_tile->units, target_unit) {
6033 if (action_is_blocked_by(act, actor_unit,
6034 target_tile, tile_city(target_tile),
6035 target_unit)) {
6036 /* Don't offer to perform an action known to be blocked. */
6037 return ACTPROB_IMPOSSIBLE;
6038 }
6039 } unit_list_iterate_end;
6040
6041 /* Must be done here since an empty unseen tile will result in
6042 * ACTPROB_IMPOSSIBLE. */
6043 if (unit_list_size(target_tile->units) == 0) {
6044 /* Can't act against an empty tile. */
6045
6046 if (player_can_trust_tile_has_no_units(unit_owner(actor_unit),
6047 target_tile)) {
6048 /* Known empty tile. */
6049 return ACTPROB_IMPOSSIBLE;
6050 } else {
6051 /* The player doesn't know that the tile is empty. */
6052 return act_prob_unseen_target(nmap, act_id, actor_unit);
6053 }
6054 }
6055
6056 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK))
6057 && tile_city(target_tile) != NULL
6058 && !pplayers_at_war(city_owner(tile_city(target_tile)),
6059 unit_owner(actor_unit))) {
6060 /* Hard coded rule: can't "Bombard", "Suicide Attack", or "Attack"
6061 * units in non enemy cities. */
6062 return ACTPROB_IMPOSSIBLE;
6063 }
6064
6065 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK)
6066 || action_id_has_result_safe(act_id, ACTRES_NUKE_UNITS))
6067 && !is_native_tile(unit_type_get(actor_unit), target_tile)
6068 && !can_attack_non_native(unit_type_get(actor_unit))) {
6069 /* Hard coded rule: can't "Nuke Units", "Suicide Attack", or "Attack"
6070 * units on non native tile without "AttackNonNative" and not
6071 * "Only_Native_Attack". */
6072 return ACTPROB_IMPOSSIBLE;
6073 }
6074
6075 /* Invisible units at this tile can make the action legal or illegal.
6076 * Invisible units can be stacked with visible units. The possible
6077 * existence of invisible units therefore makes the result uncertain. */
6078 prob_all = (can_player_see_hypotetic_units_at(unit_owner(actor_unit),
6079 target_tile)
6080 ? ACTPROB_CERTAIN : ACTPROB_NOT_KNOWN);
6081
6082 actor_ctxt = &(const struct req_context) {
6083 .player = unit_owner(actor_unit),
6084 .city = tile_city(actor_tile),
6085 .tile = actor_tile,
6086 .unit = actor_unit,
6087 .unittype = unit_type_get(actor_unit),
6088 };
6089
6090 unit_list_iterate(target_tile->units, target_unit) {
6091 struct act_prob prob_unit;
6092
6093 if (!can_player_see_unit(unit_owner(actor_unit), target_unit)) {
6094 /* Only visible units are considered. The invisible units contributed
6095 * their uncertainty to prob_all above. */
6096 continue;
6097 }
6098
6099 prob_unit = action_prob(nmap, act_id, actor_ctxt, actor_home,
6100 &(const struct req_context) {
6101 .player = unit_owner(target_unit),
6102 .city = tile_city(unit_tile(target_unit)),
6103 .tile = unit_tile(target_unit),
6104 .unit = target_unit,
6105 .unittype = unit_type_get(target_unit),
6106 },
6107 NULL);
6108
6109 if (!action_prob_possible(prob_unit)) {
6110 /* One unit makes it impossible for all units. */
6111 return ACTPROB_IMPOSSIBLE;
6112 } else if (action_prob_not_impl(prob_unit)) {
6113 /* Not implemented dominates all except impossible. */
6114 prob_all = ACTPROB_NOT_IMPLEMENTED;
6115 } else {
6116 fc_assert_msg(!action_prob_is_signal(prob_unit),
6117 "Invalid probability [%d, %d]",
6118 prob_unit.min, prob_unit.max);
6119
6120 if (action_prob_is_signal(prob_all)) {
6121 /* Special values dominate regular values. */
6122 continue;
6123 }
6124
6125 /* Probability against all target units considered until this moment
6126 * and the probability against this target unit. */
6127 prob_all.min = (prob_all.min * prob_unit.min) / ACTPROB_VAL_MAX;
6128 prob_all.max = (prob_all.max * prob_unit.max) / ACTPROB_VAL_MAX;
6129 break;
6130 }
6131 } unit_list_iterate_end;
6132
6133 /* Not impossible for any of the units at the tile. */
6134 return prob_all;
6135}
6136
6137/**********************************************************************/
6141 struct act_prob action_prob_vs_units(const struct unit *actor_unit,
6142 const action_id act_id,
6143 const struct tile *target_tile)
6144{
6145 const struct civ_map *nmap = &(wld.map);
6146
6147 return action_prob_vs_units_full(nmap, actor_unit,
6148 unit_home(actor_unit),
6149 unit_tile(actor_unit),
6150 act_id,
6151 target_tile);
6152}
6153
6154/**********************************************************************/
6158static struct act_prob
6159action_prob_vs_tile_full(const struct civ_map *nmap,
6160 const struct unit *actor_unit,
6161 const struct city *actor_home,
6162 const struct tile *actor_tile,
6163 const action_id act_id,
6164 const struct tile *target_tile,
6165 const struct extra_type *target_extra)
6166{
6167 if (actor_unit == NULL || target_tile == NULL) {
6168 /* Can't do an action when actor or target are missing. */
6169 return ACTPROB_IMPOSSIBLE;
6170 }
6171
6172 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
6173 ACTPROB_IMPOSSIBLE,
6174 "Action %s is performed by %s not %s",
6175 action_id_rule_name(act_id),
6176 action_actor_kind_name(
6177 action_id_get_actor_kind(act_id)),
6178 action_actor_kind_name(AAK_UNIT));
6179
6180 fc_assert_ret_val_msg(ATK_TILE == action_id_get_target_kind(act_id),
6181 ACTPROB_IMPOSSIBLE,
6182 "Action %s is against %s not %s",
6183 action_id_rule_name(act_id),
6184 action_target_kind_name(
6185 action_id_get_target_kind(act_id)),
6186 action_target_kind_name(ATK_TILE));
6187
6188 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
6189
6190 if (!unit_can_do_action(actor_unit, act_id)) {
6191 /* No point in continuing. */
6192 return ACTPROB_IMPOSSIBLE;
6193 }
6194
6195 /* Doesn't leak information about tile position since an unknown tile's
6196 * position is known. */
6197 if (!action_id_distance_accepted(act_id,
6198 real_map_distance(actor_tile,
6199 target_tile))) {
6200 /* No point in continuing. */
6201 return ACTPROB_IMPOSSIBLE;
6202 }
6203
6204 return action_prob(nmap, act_id,
6205 &(const struct req_context) {
6206 .player = unit_owner(actor_unit),
6207 .city = tile_city(actor_tile),
6208 .tile = actor_tile,
6209 .unit = actor_unit,
6210 .unittype = unit_type_get(actor_unit),
6211 },
6212 actor_home,
6213 &(const struct req_context) {
6214 .player = tile_owner(target_tile),
6215 .city = tile_city(target_tile),
6216 .tile = target_tile,
6217 },
6218 target_extra);
6219}
6220
6221/**********************************************************************/
6225 struct act_prob action_prob_vs_tile(const struct unit *actor_unit,
6226 const action_id act_id,
6227 const struct tile *target_tile,
6228 const struct extra_type *target_extra)
6229{
6230 const struct civ_map *nmap = &(wld.map);
6231
6232 return action_prob_vs_tile_full(nmap, actor_unit,
6233 unit_home(actor_unit),
6234 unit_tile(actor_unit),
6235 act_id, target_tile, target_extra);
6236}
6237
6238/**********************************************************************/
6242static struct act_prob
6243action_prob_vs_extras_full(const struct civ_map *nmap,
6244 const struct unit *actor_unit,
6245 const struct city *actor_home,
6246 const struct tile *actor_tile,
6247 const action_id act_id,
6248 const struct tile *target_tile,
6249 const struct extra_type *target_extra)
6250{
6251 if (actor_unit == NULL || target_tile == NULL) {
6252 /* Can't do an action when actor or target are missing. */
6253 return ACTPROB_IMPOSSIBLE;
6254 }
6255
6256 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
6257 ACTPROB_IMPOSSIBLE,
6258 "Action %s is performed by %s not %s",
6259 action_id_rule_name(act_id),
6260 action_actor_kind_name(
6261 action_id_get_actor_kind(act_id)),
6262 action_actor_kind_name(AAK_UNIT));
6263
6264 fc_assert_ret_val_msg(ATK_EXTRAS == action_id_get_target_kind(act_id),
6265 ACTPROB_IMPOSSIBLE,
6266 "Action %s is against %s not %s",
6267 action_id_rule_name(act_id),
6268 action_target_kind_name(
6269 action_id_get_target_kind(act_id)),
6270 action_target_kind_name(ATK_EXTRAS));
6271
6272 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
6273
6274 if (!unit_can_do_action(actor_unit, act_id)) {
6275 /* No point in continuing. */
6276 return ACTPROB_IMPOSSIBLE;
6277 }
6278
6279 /* Doesn't leak information about tile position since an unknown tile's
6280 * position is known. */
6281 if (!action_id_distance_accepted(act_id,
6282 real_map_distance(actor_tile,
6283 target_tile))) {
6284 /* No point in continuing. */
6285 return ACTPROB_IMPOSSIBLE;
6286 }
6287
6288 return action_prob(nmap, act_id,
6289 &(const struct req_context) {
6290 .player = unit_owner(actor_unit),
6291 .city = tile_city(actor_tile),
6292 .tile = actor_tile,
6293 .unit = actor_unit,
6294 .unittype = unit_type_get(actor_unit),
6295 },
6296 actor_home,
6297 &(const struct req_context) {
6298 .player = target_tile->extras_owner,
6299 .city = tile_city(target_tile),
6300 .tile = target_tile,
6301 },
6302 target_extra);
6303}
6304
6305/**********************************************************************/
6309 struct act_prob action_prob_vs_extras(const struct unit *actor_unit,
6310 const action_id act_id,
6311 const struct tile *target_tile,
6312 const struct extra_type *target_extra)
6313{
6314 const struct civ_map *nmap = &(wld.map);
6315
6316 return action_prob_vs_extras_full(nmap, actor_unit,
6317 unit_home(actor_unit),
6318 unit_tile(actor_unit),
6319 act_id, target_tile, target_extra);
6320}
6321
6322/**********************************************************************/
6326static struct act_prob
6327action_prob_self_full(const struct civ_map *nmap,
6328 const struct unit *actor_unit,
6329 const struct city *actor_home,
6330 const struct tile *actor_tile,
6331 const action_id act_id)
6332{
6333 if (actor_unit == NULL) {
6334 /* Can't do the action when the actor is missing. */
6335 return ACTPROB_IMPOSSIBLE;
6336 }
6337
6338 /* No point in checking distance to target. It is always 0. */
6339
6340 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
6341 ACTPROB_IMPOSSIBLE,
6342 "Action %s is performed by %s not %s",
6343 action_id_rule_name(act_id),
6344 action_actor_kind_name(
6345 action_id_get_actor_kind(act_id)),
6346 action_actor_kind_name(AAK_UNIT));
6347
6348 fc_assert_ret_val_msg(ATK_SELF == action_id_get_target_kind(act_id),
6349 ACTPROB_IMPOSSIBLE,
6350 "Action %s is against %s not %s",
6351 action_id_rule_name(act_id),
6352 action_target_kind_name(
6353 action_id_get_target_kind(act_id)),
6354 action_target_kind_name(ATK_SELF));
6355
6356 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
6357
6358 if (!unit_can_do_action(actor_unit, act_id)) {
6359 /* No point in continuing. */
6360 return ACTPROB_IMPOSSIBLE;
6361 }
6362
6363 return action_prob(nmap, act_id,
6364 &(const struct req_context) {
6365 .player = unit_owner(actor_unit),
6366 .city = tile_city(actor_tile),
6367 .tile = actor_tile,
6368 .unit = actor_unit,
6369 .unittype = unit_type_get(actor_unit),
6370 },
6371 actor_home,
6372 NULL,
6373 NULL);
6374}
6375
6376/**********************************************************************/
6380 struct act_prob action_prob_self(const struct unit *actor_unit,
6381 const action_id act_id)
6382{
6383 const struct civ_map *nmap = &(wld.map);
6384
6385 return action_prob_self_full(nmap, actor_unit,
6386 unit_home(actor_unit),
6387 unit_tile(actor_unit),
6388 act_id);
6389}
6390
6391/**********************************************************************/
6402 struct act_prob action_prob_unit_vs_tgt(const struct action *paction,
6403 const struct unit *act_unit,
6404 const struct city *tgt_city,
6405 const struct unit *tgt_unit,
6406 const struct tile *tgt_tile,
6407 const struct extra_type *extra_tgt)
6408{
6409 /* Assume impossible until told otherwise. */
6410 struct act_prob prob = ACTPROB_IMPOSSIBLE;
6411 const struct civ_map *nmap = &(wld.map);
6412
6413 fc_assert_ret_val(paction, ACTPROB_IMPOSSIBLE);
6414 fc_assert_ret_val(act_unit, ACTPROB_IMPOSSIBLE);
6415
6416 switch (action_get_target_kind(paction)) {
6417 case ATK_UNITS:
6418 if (tgt_tile) {
6419 prob = action_prob_vs_units(act_unit, paction->id, tgt_tile);
6420 }
6421 break;
6422 case ATK_TILE:
6423 if (tgt_tile) {
6424 prob = action_prob_vs_tile(act_unit, paction->id, tgt_tile, extra_tgt);
6425 }
6426 break;
6427 case ATK_EXTRAS:
6428 if (tgt_tile) {
6429 prob = action_prob_vs_extras(act_unit, paction->id,
6430 tgt_tile, extra_tgt);
6431 }
6432 break;
6433 case ATK_CITY:
6434 if (tgt_city) {
6435 prob = action_prob_vs_city(nmap, act_unit, paction->id, tgt_city);
6436 }
6437 break;
6438 case ATK_UNIT:
6439 if (tgt_unit) {
6440 prob = action_prob_vs_unit(nmap, act_unit, paction->id, tgt_unit);
6441 }
6442 break;
6443 case ATK_SELF:
6444 prob = action_prob_self(act_unit, paction->id);
6445 break;
6446 case ATK_COUNT:
6447 log_error("Invalid action target kind");
6448 break;
6449 }
6450
6451 return prob;
6452}
6453
6454/**********************************************************************/
6459 struct act_prob action_speculate_unit_on_city(const action_id act_id,
6460 const struct unit *actor,
6461 const struct city *actor_home,
6462 const struct tile *actor_tile,
6463 const bool omniscient_cheat,
6464 const struct city* target)
6465{
6466 /* FIXME: some unit state requirements still depend on the actor unit's
6467 * current position rather than on actor_tile. Maybe this function should
6468 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6469 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6470 const struct civ_map *nmap = &(wld.map);
6471
6472 if (omniscient_cheat) {
6473 if (is_action_enabled_unit_on_city_full(nmap, act_id,
6474 actor, actor_home, actor_tile,
6475 target)) {
6476 return ACTPROB_CERTAIN;
6477 } else {
6478 return ACTPROB_IMPOSSIBLE;
6479 }
6480 } else {
6481 /* FIXME: this branch result depends _directly_ on actor's position.
6482 * I.e., like, not adjacent, no action. Other branch ignores radius. */
6483 return action_prob_vs_city_full(nmap, actor, actor_home, actor_tile,
6484 act_id, target);
6485 }
6486}
6487
6488/**********************************************************************/
6493struct act_prob
6494action_speculate_unit_on_unit(action_id act_id,
6495 const struct unit *actor,
6496 const struct city *actor_home,
6497 const struct tile *actor_tile,
6498 bool omniscient_cheat,
6499 const struct unit *target)
6500{
6501 /* FIXME: some unit state requirements still depend on the actor unit's
6502 * current position rather than on actor_tile. Maybe this function should
6503 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6504 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6505 const struct civ_map *nmap = &(wld.map);
6506
6507 if (omniscient_cheat) {
6508 if (is_action_enabled_unit_on_unit_full(nmap, act_id,
6509 actor, actor_home, actor_tile,
6510 target)) {
6511 return ACTPROB_CERTAIN;
6512 } else {
6513 return ACTPROB_IMPOSSIBLE;
6514 }
6515 } else {
6516 return action_prob_vs_unit_full(nmap, actor, actor_home, actor_tile,
6517 act_id, target);
6518 }
6519}
6520
6521/**********************************************************************/
6526struct act_prob
6527action_speculate_unit_on_units(action_id act_id,
6528 const struct unit *actor,
6529 const struct city *actor_home,
6530 const struct tile *actor_tile,
6531 bool omniscient_cheat,
6532 const struct tile *target)
6533{
6534 /* FIXME: some unit state requirements still depend on the actor unit's
6535 * current position rather than on actor_tile. Maybe this function should
6536 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6537 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6538 const struct civ_map *nmap = &(wld.map);
6539
6540 if (omniscient_cheat) {
6541 if (is_action_enabled_unit_on_units_full(nmap, act_id,
6542 actor, actor_home, actor_tile,
6543 target)) {
6544 return ACTPROB_CERTAIN;
6545 } else {
6546 return ACTPROB_IMPOSSIBLE;
6547 }
6548 } else {
6549 return action_prob_vs_units_full(nmap, actor, actor_home, actor_tile,
6550 act_id, target);
6551 }
6552}
6553
6554/**********************************************************************/
6559struct act_prob
6560action_speculate_unit_on_tile(action_id act_id,
6561 const struct unit *actor,
6562 const struct city *actor_home,
6563 const struct tile *actor_tile,
6564 bool omniscient_cheat,
6565 const struct tile *target_tile,
6566 const struct extra_type *target_extra)
6567{
6568 /* FIXME: some unit state requirements still depend on the actor unit's
6569 * current position rather than on actor_tile. Maybe this function should
6570 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6571 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6572 const struct civ_map *nmap = &(wld.map);
6573
6574 if (omniscient_cheat) {
6575 if (is_action_enabled_unit_on_tile_full(nmap, act_id,
6576 actor, actor_home, actor_tile,
6577 target_tile, target_extra)) {
6578 return ACTPROB_CERTAIN;
6579 } else {
6580 return ACTPROB_IMPOSSIBLE;
6581 }
6582 } else {
6583 return action_prob_vs_tile_full(nmap, actor, actor_home, actor_tile,
6584 act_id, target_tile, target_extra);
6585 }
6586}
6587
6588/**********************************************************************/
6593struct act_prob
6594action_speculate_unit_on_extras(action_id act_id,
6595 const struct unit *actor,
6596 const struct city *actor_home,
6597 const struct tile *actor_tile,
6598 bool omniscient_cheat,
6599 const struct tile *target_tile,
6600 const struct extra_type *target_extra)
6601{
6602 /* FIXME: some unit state requirements still depend on the actor unit's
6603 * current position rather than on actor_tile. Maybe this function should
6604 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6605 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6606 const struct civ_map *nmap = &(wld.map);
6607
6608 if (omniscient_cheat) {
6609 if (is_action_enabled_unit_on_extras_full(nmap, act_id,
6610 actor, actor_home, actor_tile,
6611 target_tile, target_extra)) {
6612 return ACTPROB_CERTAIN;
6613 } else {
6614 return ACTPROB_IMPOSSIBLE;
6615 }
6616 } else {
6617 return action_prob_vs_extras_full(nmap, actor, actor_home, actor_tile,
6618 act_id, target_tile, target_extra);
6619 }
6620}
6621
6622/**********************************************************************/
6627struct act_prob
6628action_speculate_unit_on_self(action_id act_id,
6629 const struct unit *actor,
6630 const struct city *actor_home,
6631 const struct tile *actor_tile,
6632 bool omniscient_cheat)
6633{
6634 /* FIXME: some unit state requirements still depend on the actor unit's
6635 * current position rather than on actor_tile. Maybe this function should
6636 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6637 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6638 const struct civ_map *nmap = &(wld.map);
6639
6640 if (omniscient_cheat) {
6641 if (is_action_enabled_unit_on_self_full(nmap, act_id,
6642 actor, actor_home, actor_tile)) {
6643 return ACTPROB_CERTAIN;
6644 } else {
6645 return ACTPROB_IMPOSSIBLE;
6646 }
6647 } else {
6648 return action_prob_self_full(nmap, actor, actor_home, actor_tile,
6649 act_id);
6650 }
6651}
6652
6653/**********************************************************************/
6656 struct act_prob action_prob_new_impossible(void)
6657{
6658 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MIN };
6659
6660 return out;
6661}
6662
6663/**********************************************************************/
6666 struct act_prob action_prob_new_certain(void)
6667{
6668 struct act_prob out = { ACTPROB_VAL_MAX, ACTPROB_VAL_MAX };
6669
6670 return out;
6671}
6672
6673/**********************************************************************/
6676 struct act_prob action_prob_new_not_relevant(void)
6677{
6678 struct act_prob out = { ACTPROB_VAL_NA, ACTPROB_VAL_MIN};
6679
6680 return out;
6681}
6682
6683/**********************************************************************/
6686 struct act_prob action_prob_new_not_impl(void)
6687{
6688 struct act_prob out = { ACTPROB_VAL_NOT_IMPL, ACTPROB_VAL_MIN };
6689
6690 return out;
6691}
6692
6693/**********************************************************************/
6696 struct act_prob action_prob_new_unknown(void)
6697{
6698 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MAX };
6699
6700 return out;
6701}
6702
6703/**********************************************************************/
6707 bool action_prob_possible(const struct act_prob probability)
6708{
6709 return (ACTPROB_VAL_MIN < probability.max
6710 || action_prob_not_impl(probability));
6711}
6712
6713/**********************************************************************/
6717 bool action_prob_certain(const struct act_prob probability)
6718{
6719 return (ACTPROB_VAL_MAX == probability.min
6720 && ACTPROB_VAL_MAX == probability.max);
6721}
6722
6723/**********************************************************************/
6727static inline bool
6728action_prob_not_relevant(const struct act_prob probability)
6729{
6730 return probability.min == ACTPROB_VAL_NA
6731 && probability.max == ACTPROB_VAL_MIN;
6732}
6733
6734/**********************************************************************/
6738static inline bool
6739action_prob_not_impl(const struct act_prob probability)
6740{
6741 return probability.min == ACTPROB_VAL_NOT_IMPL
6742 && probability.max == ACTPROB_VAL_MIN;
6743}
6744
6745/**********************************************************************/
6749static inline bool
6750action_prob_is_signal(const struct act_prob probability)
6751{
6752 return probability.max < probability.min;
6753}
6754
6755/**********************************************************************/
6758 bool are_action_probabilitys_equal(const struct act_prob *ap1,
6759 const struct act_prob *ap2)
6760{
6761 return ap1->min == ap2->min && ap1->max == ap2->max;
6762}
6763
6764/**********************************************************************/
6767 int action_prob_cmp_pessimist(const struct act_prob ap1,
6768 const struct act_prob ap2)
6769{
6770 struct act_prob my_ap1;
6771 struct act_prob my_ap2;
6772
6773 /* The action probabilities are real. */
6774 fc_assert(!action_prob_not_relevant(ap1));
6775 fc_assert(!action_prob_not_relevant(ap2));
6776
6777 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6778 if (action_prob_is_signal(ap1)) {
6779 /* Assert that it is OK to convert the signal. */
6780 fc_assert(action_prob_not_impl(ap1));
6781
6782 my_ap1 = ACTPROB_NOT_KNOWN;
6783 } else {
6784 my_ap1 = ap1;
6785 }
6786
6787 if (action_prob_is_signal(ap2)) {
6788 /* Assert that it is OK to convert the signal. */
6789 fc_assert(action_prob_not_impl(ap2));
6790
6791 my_ap2 = ACTPROB_NOT_KNOWN;
6792 } else {
6793 my_ap2 = ap2;
6794 }
6795
6796 /* The action probabilities now have a comparison friendly form. */
6797 fc_assert(!action_prob_is_signal(my_ap1));
6798 fc_assert(!action_prob_is_signal(my_ap2));
6799
6800 /* Do the comparison. Start with min. Continue with max. */
6801 if (my_ap1.min < my_ap2.min) {
6802 return -1;
6803 } else if (my_ap1.min > my_ap2.min) {
6804 return 1;
6805 } else if (my_ap1.max < my_ap2.max) {
6806 return -1;
6807 } else if (my_ap1.max > my_ap2.max) {
6808 return 1;
6809 } else {
6810 return 0;
6811 }
6812}
6813
6814/**********************************************************************/
6818 double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
6819{
6820 struct act_prob my_ap;
6821
6822 /* The action probability is real. */
6823 fc_assert(!action_prob_not_relevant(ap));
6824
6825 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6826 if (action_prob_is_signal(ap)) {
6827 /* Assert that it is OK to convert the signal. */
6828 fc_assert(action_prob_not_impl(ap));
6829
6830 my_ap = ACTPROB_NOT_KNOWN;
6831 } else {
6832 my_ap = ap;
6833 }
6834
6835 /* The action probability now has a math friendly form. */
6836 fc_assert(!action_prob_is_signal(my_ap));
6837
6838 return (double)my_ap.min / (double) ACTPROB_VAL_MAX;
6839}
6840
6841/**********************************************************************/
6845 struct act_prob action_prob_and(const struct act_prob *ap1,
6846 const struct act_prob *ap2)
6847{
6848 struct act_prob my_ap1;
6849 struct act_prob my_ap2;
6850 struct act_prob out;
6851
6852 /* The action probabilities are real. */
6853 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
6854 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
6855
6856 if (action_prob_is_signal(*ap1)
6857 && are_action_probabilitys_equal(ap1, ap2)) {
6858 /* Keep the information rather than converting the signal to
6859 * ACTPROB_NOT_KNOWN. */
6860
6861 /* Assert that it is OK to convert the signal. */
6862 fc_assert(action_prob_not_impl(*ap1));
6863
6864 out.min = ap1->min;
6865 out.max = ap2->max;
6866
6867 return out;
6868 }
6869
6870 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6871 if (action_prob_is_signal(*ap1)) {
6872 /* Assert that it is OK to convert the signal. */
6873 fc_assert(action_prob_not_impl(*ap1));
6874
6875 my_ap1.min = ACTPROB_VAL_MIN;
6876 my_ap1.max = ACTPROB_VAL_MAX;
6877 } else {
6878 my_ap1.min = ap1->min;
6879 my_ap1.max = ap1->max;
6880 }
6881
6882 if (action_prob_is_signal(*ap2)) {
6883 /* Assert that it is OK to convert the signal. */
6884 fc_assert(action_prob_not_impl(*ap2));
6885
6886 my_ap2.min = ACTPROB_VAL_MIN;
6887 my_ap2.max = ACTPROB_VAL_MAX;
6888 } else {
6889 my_ap2.min = ap2->min;
6890 my_ap2.max = ap2->max;
6891 }
6892
6893 /* The action probabilities now have a math friendly form. */
6894 fc_assert(!action_prob_is_signal(my_ap1));
6895 fc_assert(!action_prob_is_signal(my_ap2));
6896
6897 /* Do the math. */
6898 out.min = (my_ap1.min * my_ap2.min) / ACTPROB_VAL_MAX;
6899 out.max = (my_ap1.max * my_ap2.max) / ACTPROB_VAL_MAX;
6900
6901 /* Cap at 100%. */
6902 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6903 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6904
6905 return out;
6906}
6907
6908/**********************************************************************/
6915 struct act_prob action_prob_fall_back(const struct act_prob *ap1,
6916 const struct act_prob *ap2)
6917{
6918 struct act_prob my_ap1;
6919 struct act_prob my_ap2;
6920 struct act_prob out;
6921
6922 /* The action probabilities are real. */
6923 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
6924 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
6925
6926 if (action_prob_is_signal(*ap1)
6927 && are_action_probabilitys_equal(ap1, ap2)) {
6928 /* Keep the information rather than converting the signal to
6929 * ACTPROB_NOT_KNOWN. */
6930
6931 /* Assert that it is OK to convert the signal. */
6932 fc_assert(action_prob_not_impl(*ap1));
6933
6934 out.min = ap1->min;
6935 out.max = ap2->max;
6936
6937 return out;
6938 }
6939
6940 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6941 if (action_prob_is_signal(*ap1)) {
6942 /* Assert that it is OK to convert the signal. */
6943 fc_assert(action_prob_not_impl(*ap1));
6944
6945 my_ap1.min = ACTPROB_VAL_MIN;
6946 my_ap1.max = ACTPROB_VAL_MAX;
6947 } else {
6948 my_ap1.min = ap1->min;
6949 my_ap1.max = ap1->max;
6950 }
6951
6952 if (action_prob_is_signal(*ap2)) {
6953 /* Assert that it is OK to convert the signal. */
6954 fc_assert(action_prob_not_impl(*ap2));
6955
6956 my_ap2.min = ACTPROB_VAL_MIN;
6957 my_ap2.max = ACTPROB_VAL_MAX;
6958 } else {
6959 my_ap2.min = ap2->min;
6960 my_ap2.max = ap2->max;
6961 }
6962
6963 /* The action probabilities now have a math friendly form. */
6964 fc_assert(!action_prob_is_signal(my_ap1));
6965 fc_assert(!action_prob_is_signal(my_ap2));
6966
6967 /* Do the math. */
6968 out.min = my_ap1.min + (((ACTPROB_VAL_MAX - my_ap1.min) * my_ap2.min)
6969 / ACTPROB_VAL_MAX);
6970 out.max = my_ap1.max + (((ACTPROB_VAL_MAX - my_ap1.max) * my_ap2.max)
6971 / ACTPROB_VAL_MAX);
6972
6973 /* Cap at 100%. */
6974 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6975 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6976
6977 return out;
6978}
6979
6980/**********************************************************************/
6983 int action_dice_roll_initial_odds(const struct action *paction)
6984{
6985 switch (paction->result) {
6986 case ACTRES_STRIKE_BUILDING:
6987 case ACTRES_STRIKE_PRODUCTION:
6988 case ACTRES_SPY_SPREAD_PLAGUE:
6989 case ACTRES_SPY_STEAL_TECH:
6990 case ACTRES_SPY_TARGETED_STEAL_TECH:
6991 case ACTRES_SPY_INCITE_CITY:
6992 case ACTRES_SPY_SABOTAGE_CITY:
6993 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
6994 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
6995 case ACTRES_SPY_STEAL_GOLD:
6996 case ACTRES_STEAL_MAPS:
6997 case ACTRES_SPY_NUKE:
6998 case ACTRES_SPY_POISON:
6999 if (BV_ISSET(game.info.diplchance_initial_odds, paction->id)) {
7000 /* Take the initial odds from the diplchance setting. */
7001 return server_setting_value_int_get(
7002 server_setting_by_name("diplchance"));
7003 } else {
7004 /* No initial odds. */
7005 return 100;
7006 }
7007 case ACTRES_ESTABLISH_EMBASSY:
7008 case ACTRES_SPY_INVESTIGATE_CITY:
7009 case ACTRES_TRADE_ROUTE:
7010 case ACTRES_MARKETPLACE:
7011 case ACTRES_HELP_WONDER:
7012 case ACTRES_SPY_BRIBE_UNIT:
7013 case ACTRES_SPY_SABOTAGE_UNIT:
7014 case ACTRES_CAPTURE_UNITS:
7015 case ACTRES_FOUND_CITY:
7016 case ACTRES_JOIN_CITY:
7017 case ACTRES_BOMBARD:
7018 case ACTRES_NUKE:
7019 case ACTRES_NUKE_UNITS:
7020 case ACTRES_DESTROY_CITY:
7021 case ACTRES_EXPEL_UNIT:
7022 case ACTRES_DISBAND_UNIT_RECOVER:
7023 case ACTRES_DISBAND_UNIT:
7024 case ACTRES_HOME_CITY:
7025 case ACTRES_HOMELESS:
7026 case ACTRES_UPGRADE_UNIT:
7027 case ACTRES_PARADROP:
7028 case ACTRES_PARADROP_CONQUER:
7029 case ACTRES_AIRLIFT:
7030 case ACTRES_ATTACK:
7031 case ACTRES_CONQUER_CITY:
7032 case ACTRES_CONQUER_EXTRAS:
7033 case ACTRES_HEAL_UNIT:
7034 case ACTRES_TRANSFORM_TERRAIN:
7035 case ACTRES_CULTIVATE:
7036 case ACTRES_PLANT:
7037 case ACTRES_PILLAGE:
7038 case ACTRES_CLEAN_POLLUTION:
7039 case ACTRES_CLEAN_FALLOUT:
7040 case ACTRES_FORTIFY:
7041 case ACTRES_ROAD:
7042 case ACTRES_CONVERT:
7043 case ACTRES_BASE:
7044 case ACTRES_MINE:
7045 case ACTRES_IRRIGATE:
7046 case ACTRES_TRANSPORT_ALIGHT:
7047 case ACTRES_TRANSPORT_UNLOAD:
7048 case ACTRES_TRANSPORT_DISEMBARK:
7049 case ACTRES_TRANSPORT_BOARD:
7050 case ACTRES_TRANSPORT_EMBARK:
7051 case ACTRES_SPY_ATTACK:
7052 case ACTRES_HUT_ENTER:
7053 case ACTRES_HUT_FRIGHTEN:
7054 case ACTRES_UNIT_MOVE:
7055 case ACTRES_NONE:
7056 /* No additional dice roll. */
7057 break;
7058 }
7059
7060 /* The odds of the action not being stopped by its dice roll when the dice
7061 * isn't thrown is 100%. ACTION_ODDS_PCT_DICE_ROLL_NA is above 100% */
7062 return ACTION_ODDS_PCT_DICE_ROLL_NA;
7063}
7064
7065/**********************************************************************/
7068 int action_dice_roll_odds(const struct player *act_player,
7069 const struct unit *act_unit,
7070 const struct city *tgt_city,
7071 const struct player *tgt_player,
7072 const struct action *paction)
7073{
7074 int odds = action_dice_roll_initial_odds(paction);
7075
7076 fc_assert_action_msg(odds >= 0 && odds <= 100,
7077 odds = 100,
7078 "Bad initial odds for action number %d."
7079 " Does it roll the dice at all?",
7080 paction->id);
7081
7082 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
7083 * it this way instead of rolling twice is that Action_Odds_Pct can
7084 * increase the odds. */
7085 odds += ((odds * get_target_bonus_effects(
7086 NULL,
7087 &(const struct req_context) {
7088 .player = act_player,
7089 .city = tgt_city,
7090 .unit = act_unit,
7091 .unittype = unit_type_get(act_unit),
7092 .action = paction,
7093 },
7094 tgt_player,
7095 EFT_ACTION_ODDS_PCT))
7096 / 100);
7097
7098 /* Odds are between 0% and 100%. */
7099 return CLIP(0, odds, 100);
7100}
7101
7102/**********************************************************************/
7105 bool action_immune_government(struct government *gov, action_id act)
7106{
7107 struct action *paction = action_by_number(act);
7108
7109 /* Always immune since its not enabled. Doesn't count. */
7110 if (!action_is_in_use(paction)) {
7111 return FALSE;
7112 }
7113
7114 action_enabler_list_iterate(action_enablers_for_action(act), enabler) {
7115 if (requirement_fulfilled_by_government(gov, &(enabler->target_reqs))) {
7116 return FALSE;
7117 }
7118 } action_enabler_list_iterate_end;
7119
7120 return TRUE;
7121}
7122
7123/**********************************************************************/
7128 static bool is_target_possible(const action_id wanted_action,
7129 const struct player *actor_player,
7130 const struct req_context *target)
7131{
7132 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
7133 enabler) {
7134 if (are_reqs_active(target, actor_player,
7135 &enabler->target_reqs, RPT_POSSIBLE)) {
7136 return TRUE;
7137 }
7138 } action_enabler_list_iterate_end;
7139
7140 return FALSE;
7141}
7142
7143/**********************************************************************/
7146 bool is_action_possible_on_city(action_id act_id,
7147 const struct player *actor_player,
7148 const struct city* target_city)
7149{
7150 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
7151 FALSE, "Action %s is against %s not cities",
7152 action_id_rule_name(act_id),
7153 action_target_kind_name(
7154 action_id_get_target_kind(act_id)));
7155
7156 return is_target_possible(act_id, actor_player,
7157 &(const struct req_context) {
7158 .player = city_owner(target_city),
7159 .city = target_city,
7160 .tile = city_tile(target_city),
7161 });
7162}
7163
7164/**********************************************************************/
7169 bool action_maybe_possible_actor_unit(const struct civ_map *nmap,
7170 const action_id act_id,
7171 const struct unit *actor_unit)
7172{
7173 const struct player *actor_player = unit_owner(actor_unit);
7174 const struct req_context actor_ctxt = {
7175 .player = actor_player,
7176 .city = tile_city(unit_tile(actor_unit)),
7177 .tile = unit_tile(actor_unit),
7178 .unit = actor_unit,
7179 .unittype = unit_type_get(actor_unit),
7180 };
7181 const struct action *paction = action_by_number(act_id);
7182
7183 enum fc_tristate result;
7184
7185 fc_assert_ret_val(actor_unit, FALSE);
7186
7187 if (!utype_can_do_action(actor_unit->utype, act_id)) {
7188 /* The unit type can't perform the action. */
7189 return FALSE;
7190 }
7191
7192 result = action_hard_reqs_actor(nmap, paction, &actor_ctxt, FALSE,
7193 unit_home(actor_unit));
7194
7195 if (result == TRI_NO) {
7196 /* The hard requirements aren't fulfilled. */
7197 return FALSE;
7198 }
7199
7200 action_enabler_list_iterate(action_enablers_for_action(act_id),
7201 enabler) {
7202 const enum fc_tristate current
7203 = mke_eval_reqs(actor_player, &actor_ctxt, NULL,
7204 &enabler->actor_reqs,
7205 /* Needed since no player to evaluate DiplRel
7206 * requirements against. */
7207 RPT_POSSIBLE);
7208
7209 if (current == TRI_YES
7210 || current == TRI_MAYBE) {
7211 /* The ruleset requirements may be fulfilled. */
7212 return TRUE;
7213 }
7214 } action_enabler_list_iterate_end;
7215
7216 /* No action enabler allows this action. */
7217 return FALSE;
7218}
7219
7220/**********************************************************************/
7224 bool action_mp_full_makes_legal(const struct unit *actor,
7225 const action_id act_id)
7226{
7227 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
7228
7229 /* Check if full movement points may enable the specified action. */
7230 return !utype_may_act_move_frags(unit_type_get(actor),
7231 act_id,
7232 actor->moves_left)
7233 && utype_may_act_move_frags(unit_type_get(actor),
7234 act_id,
7235 unit_move_rate(actor));
7236}
7237
7238/**********************************************************************/
7247 bool action_enabler_utype_possible_actor(const struct action_enabler *ae,
7248 const struct unit_type *act_utype)
7249{
7250 const struct action *paction = action_by_number(ae->action);
7251 struct universal actor_univ = { .kind = VUT_UTYPE,
7252 .value.utype = act_utype };
7253
7254 fc_assert_ret_val(paction != NULL, FALSE);
7255 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
7256 fc_assert_ret_val(act_utype != NULL, FALSE);
7257
7258 return (action_actor_utype_hard_reqs_ok(paction, act_utype)
7259 && !req_vec_is_impossible_to_fulfill(&ae->actor_reqs)
7260 && universal_fulfills_requirements(FALSE, &ae->actor_reqs,
7261 &actor_univ));
7262}
7263
7264/**********************************************************************/
7274 bool action_enabler_possible_actor(const struct action_enabler *ae)
7275{
7276 const struct action *paction = action_by_number(ae->action);
7277
7278 switch (action_get_actor_kind(paction)) {
7279 case AAK_UNIT:
7280 unit_type_iterate(putype) {
7281 if (action_enabler_utype_possible_actor(ae, putype)) {
7282 /* A possible actor unit type has been found. */
7283 return TRUE;
7284 }
7285 } unit_type_iterate_end;
7286
7287 /* No actor detected. */
7288 return FALSE;
7289 case AAK_COUNT:
7290 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
7291 break;
7292 }
7293
7294 /* No actor detected. */
7295 return FALSE;
7296}
7297
7298/**********************************************************************/
7305 static bool action_has_possible_actor_hard_reqs(struct action *paction)
7306{
7307 switch (action_get_actor_kind(paction)) {
7308 case AAK_UNIT:
7309 unit_type_iterate(putype) {
7310 if (action_actor_utype_hard_reqs_ok(paction, putype)) {
7311 return TRUE;
7312 }
7313 } unit_type_iterate_end;
7314 break;
7315 case AAK_COUNT:
7316 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
7317 break;
7318 }
7319
7320 /* No actor detected. */
7321 return FALSE;
7322}
7323
7324/**********************************************************************/
7330 bool action_is_in_use(struct action *paction)
7331{
7332 struct action_enabler_list *enablers;
7333
7334 if (!action_has_possible_actor_hard_reqs(paction)) {
7335 /* Hard requirements not fulfilled. */
7336 return FALSE;
7337 }
7338
7339 enablers = action_enablers_for_action(paction->id);
7340
7341 action_enabler_list_re_iterate(enablers, ae) {
7342 /* If this iteration finds any entries, action is enabled. */
7343 return TRUE;
7344 } action_enabler_list_re_iterate_end;
7345
7346 /* No non deleted action enabler. */
7347 return FALSE;
7348}
7349
7350/**********************************************************************/
7353 struct action_auto_perf *action_auto_perf_slot_number(const int num)
7354{
7355 fc_assert_ret_val(num >= 0, NULL);
7356 fc_assert_ret_val(num < MAX_NUM_ACTION_AUTO_PERFORMERS, NULL);
7357
7358 return &auto_perfs[num];
7359}
7360
7361/**********************************************************************/
7369 const struct action_auto_perf *action_auto_perf_by_number(const int num)
7370{
7371 return action_auto_perf_slot_number(num);
7372}
7373
7374/**********************************************************************/
7377 bool action_univs_not_blocking(const struct action *paction,
7378 struct universal *actor_uni,
7379 struct universal *target_uni)
7380{
7381 action_enabler_list_iterate(action_enablers_for_action(paction->id),
7382 enab) {
7383 if ((actor_uni == NULL
7384 || universal_fulfills_requirements(FALSE, &(enab->actor_reqs),
7385 actor_uni))
7386 && (target_uni == NULL
7387 || universal_fulfills_requirements(FALSE, &(enab->target_reqs),
7388 target_uni))) {
7389 return TRUE;
7390 }
7391 } action_enabler_list_iterate_end;
7392
7393 return FALSE;
7394}
7395
7396/**********************************************************************/
7401 void action_list_end(action_id *act_list, int size)
7402{
7403 fc_assert_ret(size <= MAX_NUM_ACTIONS);
7404
7405 if (size < MAX_NUM_ACTIONS) {
7406 /* An action list is terminated by ACTION_NONE */
7407 act_list[size] = ACTION_NONE;
7408 }
7409}
7410
7411/**********************************************************************/
7418 void action_list_add_all_by_result(action_id *act_list,
7419 int *position,
7420 enum action_result result)
7421{
7422 action_iterate(act) {
7423 struct action *paction = action_by_number(act);
7424 if (paction->result == result) {
7425 /* Assume one result for each action. */
7426 fc_assert_ret(*position < MAX_NUM_ACTIONS);
7427
7428 act_list[(*position)++] = paction->id;
7429 }
7430 } action_iterate_end;
7431}
7432
7433/**********************************************************************/
7438 const char *action_ui_name_ruleset_var_name(int act)
7439{
7440 switch ((enum gen_action)act) {
7441 case ACTION_SPY_POISON:
7442 return "ui_name_poison_city";
7443 case ACTION_SPY_POISON_ESC:
7444 return "ui_name_poison_city_escape";
7445 case ACTION_SPY_SABOTAGE_UNIT:
7446 return "ui_name_sabotage_unit";
7447 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7448 return "ui_name_sabotage_unit_escape";
7449 case ACTION_SPY_BRIBE_UNIT:
7450 return "ui_name_bribe_unit";
7451 case ACTION_SPY_SABOTAGE_CITY:
7452 return "ui_name_sabotage_city";
7453 case ACTION_SPY_SABOTAGE_CITY_ESC:
7454 return "ui_name_sabotage_city_escape";
7455 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7456 return "ui_name_targeted_sabotage_city";
7457 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7458 return "ui_name_sabotage_city_production";
7459 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7460 return "ui_name_targeted_sabotage_city_escape";
7461 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7462 return "ui_name_sabotage_city_production_escape";
7463 case ACTION_SPY_INCITE_CITY:
7464 return "ui_name_incite_city";
7465 case ACTION_SPY_INCITE_CITY_ESC:
7466 return "ui_name_incite_city_escape";
7467 case ACTION_ESTABLISH_EMBASSY:
7468 return "ui_name_establish_embassy";
7469 case ACTION_ESTABLISH_EMBASSY_STAY:
7470 return "ui_name_establish_embassy_stay";
7471 case ACTION_SPY_STEAL_TECH:
7472 return "ui_name_steal_tech";
7473 case ACTION_SPY_STEAL_TECH_ESC:
7474 return "ui_name_steal_tech_escape";
7475 case ACTION_SPY_TARGETED_STEAL_TECH:
7476 return "ui_name_targeted_steal_tech";
7477 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7478 return "ui_name_targeted_steal_tech_escape";
7479 case ACTION_SPY_INVESTIGATE_CITY:
7480 return "ui_name_investigate_city";
7481 case ACTION_INV_CITY_SPEND:
7482 return "ui_name_investigate_city_spend_unit";
7483 case ACTION_SPY_STEAL_GOLD:
7484 return "ui_name_steal_gold";
7485 case ACTION_SPY_STEAL_GOLD_ESC:
7486 return "ui_name_steal_gold_escape";
7487 case ACTION_SPY_SPREAD_PLAGUE:
7488 return "ui_name_spread_plague";
7489 case ACTION_STEAL_MAPS:
7490 return "ui_name_steal_maps";
7491 case ACTION_STEAL_MAPS_ESC:
7492 return "ui_name_steal_maps_escape";
7493 case ACTION_TRADE_ROUTE:
7494 return "ui_name_establish_trade_route";
7495 case ACTION_MARKETPLACE:
7496 return "ui_name_enter_marketplace";
7497 case ACTION_HELP_WONDER:
7498 return "ui_name_help_wonder";
7499 case ACTION_CAPTURE_UNITS:
7500 return "ui_name_capture_units";
7501 case ACTION_EXPEL_UNIT:
7502 return "ui_name_expel_unit";
7503 case ACTION_FOUND_CITY:
7504 return "ui_name_found_city";
7505 case ACTION_JOIN_CITY:
7506 return "ui_name_join_city";
7507 case ACTION_BOMBARD:
7508 return "ui_name_bombard";
7509 case ACTION_BOMBARD2:
7510 return "ui_name_bombard_2";
7511 case ACTION_BOMBARD3:
7512 return "ui_name_bombard_3";
7513 case ACTION_SPY_NUKE:
7514 return "ui_name_suitcase_nuke";
7515 case ACTION_SPY_NUKE_ESC:
7516 return "ui_name_suitcase_nuke_escape";
7517 case ACTION_NUKE:
7518 return "ui_name_explode_nuclear";
7519 case ACTION_NUKE_CITY:
7520 return "ui_name_nuke_city";
7521 case ACTION_NUKE_UNITS:
7522 return "ui_name_nuke_units";
7523 case ACTION_DESTROY_CITY:
7524 return "ui_name_destroy_city";
7525 case ACTION_DISBAND_UNIT_RECOVER:
7526 return "ui_name_disband_unit_recover";
7527 case ACTION_DISBAND_UNIT:
7528 return "ui_name_disband_unit";
7529 case ACTION_HOME_CITY:
7530 return "ui_name_home_city";
7531 case ACTION_HOMELESS:
7532 return "ui_name_homeless";
7533 case ACTION_UPGRADE_UNIT:
7534 return "ui_name_upgrade_unit";
7535 case ACTION_PARADROP:
7536 return "ui_name_paradrop_unit";
7537 case ACTION_PARADROP_CONQUER:
7538 return "ui_name_paradrop_unit_conquer";
7539 case ACTION_PARADROP_FRIGHTEN:
7540 return "ui_name_paradrop_unit_frighten";
7541 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7542 return "ui_name_paradrop_unit_frighten_conquer";
7543 case ACTION_PARADROP_ENTER:
7544 return "ui_name_paradrop_unit_enter";
7545 case ACTION_PARADROP_ENTER_CONQUER:
7546 return "ui_name_paradrop_unit_enter_conquer";
7547 case ACTION_AIRLIFT:
7548 return "ui_name_airlift_unit";
7549 case ACTION_ATTACK:
7550 return "ui_name_attack";
7551 case ACTION_SUICIDE_ATTACK:
7552 return "ui_name_suicide_attack";
7553 case ACTION_STRIKE_BUILDING:
7554 return "ui_name_surgical_strike_building";
7555 case ACTION_STRIKE_PRODUCTION:
7556 return "ui_name_surgical_strike_production";
7557 case ACTION_CONQUER_CITY:
7558 return "ui_name_conquer_city";
7559 case ACTION_CONQUER_CITY2:
7560 return "ui_name_conquer_city_2";
7561 case ACTION_CONQUER_CITY3:
7562 return "ui_name_conquer_city_3";
7563 case ACTION_CONQUER_CITY4:
7564 return "ui_name_conquer_city_4";
7565 case ACTION_CONQUER_EXTRAS:
7566 return "ui_name_conquer_extras";
7567 case ACTION_CONQUER_EXTRAS2:
7568 return "ui_name_conquer_extras_2";
7569 case ACTION_CONQUER_EXTRAS3:
7570 return "ui_name_conquer_extras_3";
7571 case ACTION_CONQUER_EXTRAS4:
7572 return "ui_name_conquer_extras_4";
7573 case ACTION_HEAL_UNIT:
7574 return "ui_name_heal_unit";
7575 case ACTION_HEAL_UNIT2:
7576 return "ui_name_heal_unit_2";
7577 case ACTION_TRANSFORM_TERRAIN:
7578 return "ui_name_transform_terrain";
7579 case ACTION_CULTIVATE:
7580 return "ui_name_cultivate";
7581 case ACTION_PLANT:
7582 return "ui_name_plant";
7583 case ACTION_PILLAGE:
7584 return "ui_name_pillage";
7585 case ACTION_CLEAN_POLLUTION:
7586 return "ui_name_clean_pollution";
7587 case ACTION_CLEAN_FALLOUT:
7588 return "ui_name_clean_fallout";
7589 case ACTION_FORTIFY:
7590 return "ui_name_fortify";
7591 case ACTION_ROAD:
7592 return "ui_name_road";
7593 case ACTION_CONVERT:
7594 return "ui_name_convert_unit";
7595 case ACTION_BASE:
7596 return "ui_name_build_base";
7597 case ACTION_MINE:
7598 return "ui_name_build_mine";
7599 case ACTION_IRRIGATE:
7600 return "ui_name_irrigate";
7601 case ACTION_TRANSPORT_ALIGHT:
7602 return "ui_name_transport_alight";
7603 case ACTION_TRANSPORT_BOARD:
7604 return "ui_name_transport_board";
7605 case ACTION_TRANSPORT_EMBARK:
7606 return "ui_name_transport_embark";
7607 case ACTION_TRANSPORT_EMBARK2:
7608 return "ui_name_transport_embark_2";
7609 case ACTION_TRANSPORT_EMBARK3:
7610 return "ui_name_transport_embark_3";
7611 case ACTION_TRANSPORT_UNLOAD:
7612 return "ui_name_transport_unload";
7613 case ACTION_TRANSPORT_DISEMBARK1:
7614 return "ui_name_transport_disembark";
7615 case ACTION_TRANSPORT_DISEMBARK2:
7616 return "ui_name_transport_disembark_2";
7617 case ACTION_TRANSPORT_DISEMBARK3:
7618 return "ui_name_transport_disembark_3";
7619 case ACTION_TRANSPORT_DISEMBARK4:
7620 return "ui_name_transport_disembark_4";
7621 case ACTION_HUT_ENTER:
7622 return "ui_name_enter_hut";
7623 case ACTION_HUT_ENTER2:
7624 return "ui_name_enter_hut_2";
7625 case ACTION_HUT_ENTER3:
7626 return "ui_name_enter_hut_3";
7627 case ACTION_HUT_ENTER4:
7628 return "ui_name_enter_hut_4";
7629 case ACTION_HUT_FRIGHTEN:
7630 return "ui_name_frighten_hut";
7631 case ACTION_HUT_FRIGHTEN2:
7632 return "ui_name_frighten_hut_2";
7633 case ACTION_HUT_FRIGHTEN3:
7634 return "ui_name_frighten_hut_3";
7635 case ACTION_HUT_FRIGHTEN4:
7636 return "ui_name_frighten_hut_4";
7637 case ACTION_SPY_ATTACK:
7638 return "ui_name_spy_attack";
7639 case ACTION_UNIT_MOVE:
7640 return "ui_name_unit_move";
7641 case ACTION_UNIT_MOVE2:
7642 return "ui_name_unit_move_2";
7643 case ACTION_UNIT_MOVE3:
7644 return "ui_name_unit_move_3";
7645 case ACTION_USER_ACTION1:
7646 return "ui_name_user_action_1";
7647 case ACTION_USER_ACTION2:
7648 return "ui_name_user_action_2";
7649 case ACTION_USER_ACTION3:
7650 return "ui_name_user_action_3";
7651 case ACTION_USER_ACTION4:
7652 return "ui_name_user_action_4";
7653 case ACTION_COUNT:
7654 break;
7655 }
7656
7657 fc_assert(act >= 0 && act < ACTION_COUNT);
7658 return NULL;
7659}
7660
7661/**********************************************************************/
7664 const char *action_ui_name_default(int act)
7665{
7666 switch ((enum gen_action)act) {
7667 case ACTION_SPY_POISON:
7668 /* TRANS: _Poison City (3% chance of success). */
7669 return N_("%sPoison City%s");
7670 case ACTION_SPY_POISON_ESC:
7671 /* TRANS: _Poison City and Escape (3% chance of success). */
7672 return N_("%sPoison City and Escape%s");
7673 case ACTION_SPY_SABOTAGE_UNIT:
7674 /* TRANS: S_abotage Enemy Unit (3% chance of success). */
7675 return N_("S%sabotage Enemy Unit%s");
7676 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7677 /* TRANS: S_abotage Enemy Unit and Escape (3% chance of success). */
7678 return N_("S%sabotage Enemy Unit and Escape%s");
7679 case ACTION_SPY_BRIBE_UNIT:
7680 /* TRANS: Bribe Enemy _Unit (3% chance of success). */
7681 return N_("Bribe Enemy %sUnit%s");
7682 case ACTION_SPY_SABOTAGE_CITY:
7683 /* TRANS: _Sabotage City (3% chance of success). */
7684 return N_("%sSabotage City%s");
7685 case ACTION_SPY_SABOTAGE_CITY_ESC:
7686 /* TRANS: _Sabotage City and Escape (3% chance of success). */
7687 return N_("%sSabotage City and Escape%s");
7688 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7689 /* TRANS: Industria_l Sabotage (3% chance of success). */
7690 return N_("Industria%sl Sabotage%s");
7691 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7692 /* TRANS: Industria_l Sabotage Production (3% chance of success). */
7693 return N_("Industria%sl Sabotage Production%s");
7694 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7695 /* TRANS: Industria_l Sabotage and Escape (3% chance of success). */
7696 return N_("Industria%sl Sabotage and Escape%s");
7697 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7698 /* TRANS: Industria_l Sabotage Production and Escape (3% chance of success). */
7699 return N_("Industria%sl Sabotage Production and Escape%s");
7700 case ACTION_SPY_INCITE_CITY:
7701 /* TRANS: Incite a Re_volt (3% chance of success). */
7702 return N_("Incite a Re%svolt%s");
7703 case ACTION_SPY_INCITE_CITY_ESC:
7704 /* TRANS: Incite a Re_volt and Escape (3% chance of success). */
7705 return N_("Incite a Re%svolt and Escape%s");
7706 case ACTION_ESTABLISH_EMBASSY:
7707 /* TRANS: Establish _Embassy (100% chance of success). */
7708 return N_("Establish %sEmbassy%s");
7709 case ACTION_ESTABLISH_EMBASSY_STAY:
7710 /* TRANS: Becom_e Ambassador (100% chance of success). */
7711 return N_("Becom%se Ambassador%s");
7712 case ACTION_SPY_STEAL_TECH:
7713 /* TRANS: Steal _Technology (3% chance of success). */
7714 return N_("Steal %sTechnology%s");
7715 case ACTION_SPY_STEAL_TECH_ESC:
7716 /* TRANS: Steal _Technology and Escape (3% chance of success). */
7717 return N_("Steal %sTechnology and Escape%s");
7718 case ACTION_SPY_TARGETED_STEAL_TECH:
7719 /* TRANS: In_dustrial Espionage (3% chance of success). */
7720 return N_("In%sdustrial Espionage%s");
7721 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7722 /* TRANS: In_dustrial Espionage and Escape (3% chance of success). */
7723 return N_("In%sdustrial Espionage and Escape%s");
7724 case ACTION_SPY_INVESTIGATE_CITY:
7725 /* TRANS: _Investigate City (100% chance of success). */
7726 return N_("%sInvestigate City%s");
7727 case ACTION_INV_CITY_SPEND:
7728 /* TRANS: _Investigate City (spends the unit) (100% chance of
7729 * success). */
7730 return N_("%sInvestigate City (spends the unit)%s");
7731 case ACTION_SPY_STEAL_GOLD:
7732 /* TRANS: Steal _Gold (100% chance of success). */
7733 return N_("Steal %sGold%s");
7734 case ACTION_SPY_STEAL_GOLD_ESC:
7735 /* TRANS: Steal _Gold and Escape (100% chance of success). */
7736 return N_("Steal %sGold and Escape%s");
7737 case ACTION_SPY_SPREAD_PLAGUE:
7738 /* TRANS: Spread _Plague (100% chance of success). */
7739 return N_("Spread %sPlague%s");
7740 case ACTION_STEAL_MAPS:
7741 /* TRANS: Steal _Maps (100% chance of success). */
7742 return N_("Steal %sMaps%s");
7743 case ACTION_STEAL_MAPS_ESC:
7744 /* TRANS: Steal _Maps and Escape (100% chance of success). */
7745 return N_("Steal %sMaps and Escape%s");
7746 case ACTION_TRADE_ROUTE:
7747 /* TRANS: Establish Trade _Route (100% chance of success). */
7748 return N_("Establish Trade %sRoute%s");
7749 case ACTION_MARKETPLACE:
7750 /* TRANS: Enter _Marketplace (100% chance of success). */
7751 return N_("Enter %sMarketplace%s");
7752 case ACTION_HELP_WONDER:
7753 /* TRANS: Help _build Wonder (100% chance of success). */
7754 return N_("Help %sbuild Wonder%s");
7755 case ACTION_CAPTURE_UNITS:
7756 /* TRANS: _Capture Units (100% chance of success). */
7757 return N_("%sCapture Units%s");
7758 case ACTION_EXPEL_UNIT:
7759 /* TRANS: _Expel Unit (100% chance of success). */
7760 return N_("%sExpel Unit%s");
7761 case ACTION_FOUND_CITY:
7762 /* TRANS: _Found City (100% chance of success). */
7763 return N_("%sFound City%s");
7764 case ACTION_JOIN_CITY:
7765 /* TRANS: _Join City (100% chance of success). */
7766 return N_("%sJoin City%s");
7767 case ACTION_BOMBARD:
7768 /* TRANS: B_ombard (100% chance of success). */
7769 return N_("B%sombard%s");
7770 case ACTION_BOMBARD2:
7771 /* TRANS: B_ombard 2 (100% chance of success). */
7772 return N_("B%sombard 2%s");
7773 case ACTION_BOMBARD3:
7774 /* TRANS: B_ombard 3 (100% chance of success). */
7775 return N_("B%sombard 3%s");
7776 case ACTION_SPY_NUKE:
7777 /* TRANS: Suitcase _Nuke (100% chance of success). */
7778 return N_("Suitcase %sNuke%s");
7779 case ACTION_SPY_NUKE_ESC:
7780 /* TRANS: Suitcase _Nuke and Escape (100% chance of success). */
7781 return N_("Suitcase %sNuke and Escape%s");
7782 case ACTION_NUKE:
7783 /* TRANS: Explode _Nuclear (100% chance of success). */
7784 return N_("Explode %sNuclear%s");
7785 case ACTION_NUKE_CITY:
7786 /* TRANS: _Nuke City (100% chance of success). */
7787 return N_("%sNuke City%s");
7788 case ACTION_NUKE_UNITS:
7789 /* TRANS: _Nuke Units (100% chance of success). */
7790 return N_("%sNuke Units%s");
7791 case ACTION_DESTROY_CITY:
7792 /* TRANS: Destroy _City (100% chance of success). */
7793 return N_("Destroy %sCity%s");
7794 case ACTION_DISBAND_UNIT_RECOVER:
7795 /* TRANS: Dis_band recovering production (100% chance of success). */
7796 return N_("Dis%sband recovering production%s");
7797 case ACTION_DISBAND_UNIT:
7798 /* TRANS: Dis_band without recovering production (100% chance of success). */
7799 return N_("Dis%sband without recovering production%s");
7800 case ACTION_HOME_CITY:
7801 /* TRANS: Set _Home City (100% chance of success). */
7802 return N_("Set %sHome City%s");
7803 case ACTION_HOMELESS:
7804 /* TRANS: Make _Homeless (100% chance of success). */
7805 return N_("Make %sHomeless%s");
7806 case ACTION_UPGRADE_UNIT:
7807 /* TRANS: _Upgrade Unit (100% chance of success). */
7808 return N_("%sUpgrade Unit%s");
7809 case ACTION_PARADROP:
7810 /* TRANS: Drop _Paratrooper (100% chance of success). */
7811 return N_("Drop %sParatrooper%s");
7812 case ACTION_PARADROP_CONQUER:
7813 /* TRANS: Drop _Paratrooper (100% chance of success). */
7814 return N_("Drop %sParatrooper%s");
7815 case ACTION_PARADROP_FRIGHTEN:
7816 /* TRANS: Drop _Paratrooper (100% chance of success). */
7817 return N_("Drop %sParatrooper%s");
7818 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7819 /* TRANS: Drop _Paratrooper (100% chance of success). */
7820 return N_("Drop %sParatrooper%s");
7821 case ACTION_PARADROP_ENTER:
7822 /* TRANS: Drop _Paratrooper (100% chance of success). */
7823 return N_("Drop %sParatrooper%s");
7824 case ACTION_PARADROP_ENTER_CONQUER:
7825 /* TRANS: Drop _Paratrooper (100% chance of success). */
7826 return N_("Drop %sParatrooper%s");
7827 case ACTION_AIRLIFT:
7828 /* TRANS: _Airlift to City (100% chance of success). */
7829 return N_("%sAirlift to City%s");
7830 case ACTION_ATTACK:
7831 /* TRANS: _Attack (100% chance of success). */
7832 return N_("%sAttack%s");
7833 case ACTION_SUICIDE_ATTACK:
7834 /* TRANS: _Suicide Attack (100% chance of success). */
7835 return N_("%sSuicide Attack%s");
7836 case ACTION_STRIKE_BUILDING:
7837 /* TRANS: Surgical Str_ike Building (100% chance of success). */
7838 return N_("Surgical Str%sike Building%s");
7839 case ACTION_STRIKE_PRODUCTION:
7840 /* TRANS: Surgical Str_ike Production (100% chance of success). */
7841 return N_("Surgical Str%sike Production%s");
7842 case ACTION_CONQUER_CITY:
7843 case ACTION_CONQUER_CITY3:
7844 case ACTION_CONQUER_CITY4:
7845 /* TRANS: _Conquer City (100% chance of success). */
7846 return N_("%sConquer City%s");
7847 case ACTION_CONQUER_CITY2:
7848 /* TRANS: _Conquer City 2 (100% chance of success). */
7849 return N_("%sConquer City 2%s");
7850 case ACTION_CONQUER_EXTRAS:
7851 case ACTION_CONQUER_EXTRAS3:
7852 case ACTION_CONQUER_EXTRAS4:
7853 /* TRANS: _Conquer Extras (100% chance of success). */
7854 return N_("%sConquer Extras%s");
7855 case ACTION_CONQUER_EXTRAS2:
7856 /* TRANS: _Conquer Extras 2 (100% chance of success). */
7857 return N_("%sConquer Extras 2%s");
7858 case ACTION_HEAL_UNIT:
7859 case ACTION_HEAL_UNIT2:
7860 /* TRANS: Heal _Unit (3% chance of success). */
7861 return N_("Heal %sUnit%s");
7862 case ACTION_TRANSFORM_TERRAIN:
7863 /* TRANS: _Transform Terrain (3% chance of success). */
7864 return N_("%sTransform Terrain%s");
7865 case ACTION_CULTIVATE:
7866 /* TRANS: Transform by _Cultivating (3% chance of success). */
7867 return N_("Transform by %sCultivating%s");
7868 case ACTION_PLANT:
7869 /* TRANS: Transform by _Planting (3% chance of success). */
7870 return N_("Transform by %sPlanting%s");
7871 case ACTION_PILLAGE:
7872 /* TRANS: Pilla_ge (100% chance of success). */
7873 return N_("Pilla%sge%s");
7874 case ACTION_CLEAN_POLLUTION:
7875 /* TRANS: Clean _Pollution (100% chance of success). */
7876 return N_("Clean %sPollution%s");
7877 case ACTION_CLEAN_FALLOUT:
7878 /* TRANS: Clean _Fallout (100% chance of success). */
7879 return N_("Clean %sFallout%s");
7880 case ACTION_FORTIFY:
7881 /* TRANS: _Fortify (100% chance of success). */
7882 return N_("%sFortify%s");
7883 case ACTION_ROAD:
7884 /* TRANS: Build _Road (100% chance of success). */
7885 return N_("Build %sRoad%s");
7886 case ACTION_CONVERT:
7887 /* TRANS: _Convert Unit (100% chance of success). */
7888 return N_("%sConvert Unit%s");
7889 case ACTION_BASE:
7890 /* TRANS: _Build Base (100% chance of success). */
7891 return N_("%sBuild Base%s");
7892 case ACTION_MINE:
7893 /* TRANS: Build _Mine (100% chance of success). */
7894 return N_("Build %sMine%s");
7895 case ACTION_IRRIGATE:
7896 /* TRANS: Build _Irrigation (100% chance of success). */
7897 return N_("Build %sIrrigation%s");
7898 case ACTION_TRANSPORT_ALIGHT:
7899 /* TRANS: _Deboard (100% chance of success). */
7900 return N_("%sDeboard%s");
7901 case ACTION_TRANSPORT_BOARD:
7902 /* TRANS: _Board (100% chance of success). */
7903 return N_("%sBoard%s");
7904 case ACTION_TRANSPORT_EMBARK:
7905 case ACTION_TRANSPORT_EMBARK2:
7906 case ACTION_TRANSPORT_EMBARK3:
7907 /* TRANS: _Embark (100% chance of success). */
7908 return N_("%sEmbark%s");
7909 case ACTION_TRANSPORT_UNLOAD:
7910 /* TRANS: _Unload (100% chance of success). */
7911 return N_("%sUnload%s");
7912 case ACTION_TRANSPORT_DISEMBARK1:
7913 case ACTION_TRANSPORT_DISEMBARK3:
7914 case ACTION_TRANSPORT_DISEMBARK4:
7915 /* TRANS: _Disembark (100% chance of success). */
7916 return N_("%sDisembark%s");
7917 case ACTION_TRANSPORT_DISEMBARK2:
7918 /* TRANS: _Disembark 2 (100% chance of success). */
7919 return N_("%sDisembark 2%s");
7920 case ACTION_SPY_ATTACK:
7921 /* TRANS: _Eliminate Diplomat (100% chance of success). */
7922 return N_("%sEliminate Diplomat%s");
7923 case ACTION_HUT_ENTER:
7924 case ACTION_HUT_ENTER2:
7925 case ACTION_HUT_ENTER3:
7926 case ACTION_HUT_ENTER4:
7927 /* TRANS: Enter _Hut (100% chance of success). */
7928 return N_("Enter %sHut%s");
7929 case ACTION_HUT_FRIGHTEN:
7930 case ACTION_HUT_FRIGHTEN2:
7931 case ACTION_HUT_FRIGHTEN3:
7932 case ACTION_HUT_FRIGHTEN4:
7933 /* TRANS: Frighten _Hut (100% chance of success). */
7934 return N_("Frighten %sHut%s");
7935 case ACTION_UNIT_MOVE:
7936 case ACTION_UNIT_MOVE2:
7937 case ACTION_UNIT_MOVE3:
7938 /* TRANS: Regular _Move (100% chance of success). */
7939 return N_("Regular %sMove%s");
7940 case ACTION_USER_ACTION1:
7941 /* TRANS: _User Action 1 (100% chance of success). */
7942 return N_("%sUser Action 1%s");
7943 case ACTION_USER_ACTION2:
7944 /* TRANS: _User Action 2 (100% chance of success). */
7945 return N_("%sUser Action 2%s");
7946 case ACTION_USER_ACTION3:
7947 /* TRANS: _User Action 3 (100% chance of success). */
7948 return N_("%sUser Action 3%s");
7949 case ACTION_USER_ACTION4:
7950 /* TRANS: _User Action 4 (100% chance of success). */
7951 return N_("%sUser Action 4%s");
7952 case ACTION_COUNT:
7953 fc_assert(act != ACTION_COUNT);
7954 break;
7955 }
7956
7957 return NULL;
7958}
7959
7960/**********************************************************************/
7966 const char *action_min_range_ruleset_var_name(int act)
7967{
7968 switch ((enum gen_action)act) {
7969 case ACTION_SPY_POISON:
7970 case ACTION_SPY_POISON_ESC:
7971 case ACTION_SPY_SABOTAGE_UNIT:
7972 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7973 case ACTION_SPY_BRIBE_UNIT:
7974 case ACTION_SPY_SABOTAGE_CITY:
7975 case ACTION_SPY_SABOTAGE_CITY_ESC:
7976 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7977 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7978 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7979 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7980 case ACTION_SPY_INCITE_CITY:
7981 case ACTION_SPY_INCITE_CITY_ESC:
7982 case ACTION_ESTABLISH_EMBASSY:
7983 case ACTION_ESTABLISH_EMBASSY_STAY:
7984 case ACTION_SPY_STEAL_TECH:
7985 case ACTION_SPY_STEAL_TECH_ESC:
7986 case ACTION_SPY_TARGETED_STEAL_TECH:
7987 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7988 case ACTION_SPY_INVESTIGATE_CITY:
7989 case ACTION_INV_CITY_SPEND:
7990 case ACTION_SPY_STEAL_GOLD:
7991 case ACTION_SPY_STEAL_GOLD_ESC:
7992 case ACTION_SPY_SPREAD_PLAGUE:
7993 case ACTION_STEAL_MAPS:
7994 case ACTION_STEAL_MAPS_ESC:
7995 case ACTION_TRADE_ROUTE:
7996 case ACTION_MARKETPLACE:
7997 case ACTION_HELP_WONDER:
7998 case ACTION_CAPTURE_UNITS:
7999 case ACTION_EXPEL_UNIT:
8000 case ACTION_FOUND_CITY:
8001 case ACTION_JOIN_CITY:
8002 case ACTION_SPY_NUKE:
8003 case ACTION_SPY_NUKE_ESC:
8004 case ACTION_DESTROY_CITY:
8005 case ACTION_DISBAND_UNIT_RECOVER:
8006 case ACTION_DISBAND_UNIT:
8007 case ACTION_HOME_CITY:
8008 case ACTION_HOMELESS:
8009 case ACTION_UPGRADE_UNIT:
8010 case ACTION_PARADROP:
8011 case ACTION_PARADROP_CONQUER:
8012 case ACTION_PARADROP_FRIGHTEN:
8013 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8014 case ACTION_PARADROP_ENTER:
8015 case ACTION_PARADROP_ENTER_CONQUER:
8016 case ACTION_AIRLIFT:
8017 case ACTION_ATTACK:
8018 case ACTION_SUICIDE_ATTACK:
8019 case ACTION_STRIKE_BUILDING:
8020 case ACTION_STRIKE_PRODUCTION:
8021 case ACTION_CONQUER_CITY:
8022 case ACTION_CONQUER_CITY2:
8023 case ACTION_CONQUER_CITY3:
8024 case ACTION_CONQUER_CITY4:
8025 case ACTION_HEAL_UNIT:
8026 case ACTION_HEAL_UNIT2:
8027 case ACTION_TRANSFORM_TERRAIN:
8028 case ACTION_CULTIVATE:
8029 case ACTION_PLANT:
8030 case ACTION_PILLAGE:
8031 case ACTION_CLEAN_POLLUTION:
8032 case ACTION_CLEAN_FALLOUT:
8033 case ACTION_FORTIFY:
8034 case ACTION_ROAD:
8035 case ACTION_CONVERT:
8036 case ACTION_BASE:
8037 case ACTION_MINE:
8038 case ACTION_IRRIGATE:
8039 case ACTION_TRANSPORT_ALIGHT:
8040 case ACTION_TRANSPORT_BOARD:
8041 case ACTION_TRANSPORT_EMBARK:
8042 case ACTION_TRANSPORT_EMBARK2:
8043 case ACTION_TRANSPORT_EMBARK3:
8044 case ACTION_TRANSPORT_UNLOAD:
8045 case ACTION_TRANSPORT_DISEMBARK1:
8046 case ACTION_TRANSPORT_DISEMBARK2:
8047 case ACTION_TRANSPORT_DISEMBARK3:
8048 case ACTION_TRANSPORT_DISEMBARK4:
8049 case ACTION_BOMBARD:
8050 case ACTION_BOMBARD2:
8051 case ACTION_BOMBARD3:
8052 case ACTION_SPY_ATTACK:
8053 case ACTION_CONQUER_EXTRAS:
8054 case ACTION_CONQUER_EXTRAS2:
8055 case ACTION_CONQUER_EXTRAS3:
8056 case ACTION_CONQUER_EXTRAS4:
8057 case ACTION_HUT_ENTER:
8058 case ACTION_HUT_ENTER2:
8059 case ACTION_HUT_ENTER3:
8060 case ACTION_HUT_ENTER4:
8061 case ACTION_HUT_FRIGHTEN:
8062 case ACTION_HUT_FRIGHTEN2:
8063 case ACTION_HUT_FRIGHTEN4:
8064 case ACTION_HUT_FRIGHTEN3:
8065 case ACTION_UNIT_MOVE:
8066 case ACTION_UNIT_MOVE2:
8067 case ACTION_UNIT_MOVE3:
8068 /* Min range is not ruleset changeable */
8069 return NULL;
8070 case ACTION_NUKE:
8071 return "explode_nuclear_min_range";
8072 case ACTION_NUKE_CITY:
8073 return "nuke_city_min_range";
8074 case ACTION_NUKE_UNITS:
8075 return "nuke_units_min_range";
8076 case ACTION_USER_ACTION1:
8077 return "user_action_1_min_range";
8078 case ACTION_USER_ACTION2:
8079 return "user_action_2_min_range";
8080 case ACTION_USER_ACTION3:
8081 return "user_action_3_min_range";
8082 case ACTION_USER_ACTION4:
8083 return "user_action_4_min_range";
8084 case ACTION_COUNT:
8085 break;
8086 }
8087
8088 fc_assert(act >= 0 && act < ACTION_COUNT);
8089 return NULL;
8090}
8091
8092/**********************************************************************/
8095 int action_min_range_default(enum action_result result)
8096{
8097 switch (result) {
8098 case ACTRES_ESTABLISH_EMBASSY:
8099 case ACTRES_SPY_INVESTIGATE_CITY:
8100 case ACTRES_SPY_POISON:
8101 case ACTRES_SPY_STEAL_GOLD:
8102 case ACTRES_SPY_SABOTAGE_CITY:
8103 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8104 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8105 case ACTRES_SPY_STEAL_TECH:
8106 case ACTRES_SPY_TARGETED_STEAL_TECH:
8107 case ACTRES_SPY_INCITE_CITY:
8108 case ACTRES_TRADE_ROUTE:
8109 case ACTRES_MARKETPLACE:
8110 case ACTRES_HELP_WONDER:
8111 case ACTRES_SPY_BRIBE_UNIT:
8112 case ACTRES_SPY_SABOTAGE_UNIT:
8113 case ACTRES_CAPTURE_UNITS:
8114 case ACTRES_FOUND_CITY:
8115 case ACTRES_JOIN_CITY:
8116 case ACTRES_STEAL_MAPS:
8117 case ACTRES_BOMBARD:
8118 case ACTRES_SPY_NUKE:
8119 case ACTRES_DESTROY_CITY:
8120 case ACTRES_EXPEL_UNIT:
8121 case ACTRES_DISBAND_UNIT_RECOVER:
8122 case ACTRES_DISBAND_UNIT:
8123 case ACTRES_HOME_CITY:
8124 case ACTRES_HOMELESS:
8125 case ACTRES_UPGRADE_UNIT:
8126 case ACTRES_PARADROP:
8127 case ACTRES_PARADROP_CONQUER:
8128 case ACTRES_AIRLIFT:
8129 case ACTRES_STRIKE_BUILDING:
8130 case ACTRES_STRIKE_PRODUCTION:
8131 case ACTRES_ATTACK:
8132 case ACTRES_CONQUER_CITY:
8133 case ACTRES_HEAL_UNIT:
8134 case ACTRES_TRANSFORM_TERRAIN:
8135 case ACTRES_CULTIVATE:
8136 case ACTRES_PLANT:
8137 case ACTRES_PILLAGE:
8138 case ACTRES_CLEAN_POLLUTION:
8139 case ACTRES_CLEAN_FALLOUT:
8140 case ACTRES_FORTIFY:
8141 case ACTRES_ROAD:
8142 case ACTRES_CONVERT:
8143 case ACTRES_BASE:
8144 case ACTRES_MINE:
8145 case ACTRES_IRRIGATE:
8146 case ACTRES_TRANSPORT_ALIGHT:
8147 case ACTRES_TRANSPORT_UNLOAD:
8148 case ACTRES_TRANSPORT_DISEMBARK:
8149 case ACTRES_TRANSPORT_BOARD:
8150 case ACTRES_TRANSPORT_EMBARK:
8151 case ACTRES_SPY_ATTACK:
8152 case ACTRES_SPY_SPREAD_PLAGUE:
8153 case ACTRES_CONQUER_EXTRAS:
8154 case ACTRES_HUT_ENTER:
8155 case ACTRES_HUT_FRIGHTEN:
8156 case ACTRES_UNIT_MOVE:
8157 /* Non ruleset defined action min range not supported here */
8158 fc_assert_msg(FALSE, "Probably wrong value.");
8159 return RS_DEFAULT_ACTION_MIN_RANGE;
8160 case ACTRES_NUKE:
8161 case ACTRES_NUKE_UNITS:
8162 return RS_DEFAULT_ACTION_MIN_RANGE;
8163 case ACTRES_NONE:
8164 return RS_DEFAULT_ACTION_MIN_RANGE;
8165 }
8166
8167 fc_assert(action_result_is_valid(result) || result == ACTRES_NONE);
8168 return 0;
8169}
8170
8171/**********************************************************************/
8177 const char *action_max_range_ruleset_var_name(int act)
8178{
8179 switch ((enum gen_action)act) {
8180 case ACTION_SPY_POISON:
8181 case ACTION_SPY_POISON_ESC:
8182 case ACTION_SPY_SABOTAGE_UNIT:
8183 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8184 case ACTION_SPY_BRIBE_UNIT:
8185 case ACTION_SPY_SABOTAGE_CITY:
8186 case ACTION_SPY_SABOTAGE_CITY_ESC:
8187 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8188 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8189 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8190 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8191 case ACTION_SPY_INCITE_CITY:
8192 case ACTION_SPY_INCITE_CITY_ESC:
8193 case ACTION_ESTABLISH_EMBASSY:
8194 case ACTION_ESTABLISH_EMBASSY_STAY:
8195 case ACTION_SPY_STEAL_TECH:
8196 case ACTION_SPY_STEAL_TECH_ESC:
8197 case ACTION_SPY_TARGETED_STEAL_TECH:
8198 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8199 case ACTION_SPY_INVESTIGATE_CITY:
8200 case ACTION_INV_CITY_SPEND:
8201 case ACTION_SPY_STEAL_GOLD:
8202 case ACTION_SPY_STEAL_GOLD_ESC:
8203 case ACTION_SPY_SPREAD_PLAGUE:
8204 case ACTION_STEAL_MAPS:
8205 case ACTION_STEAL_MAPS_ESC:
8206 case ACTION_TRADE_ROUTE:
8207 case ACTION_MARKETPLACE:
8208 case ACTION_CAPTURE_UNITS:
8209 case ACTION_EXPEL_UNIT:
8210 case ACTION_FOUND_CITY:
8211 case ACTION_JOIN_CITY:
8212 case ACTION_SPY_NUKE:
8213 case ACTION_SPY_NUKE_ESC:
8214 case ACTION_DESTROY_CITY:
8215 case ACTION_DISBAND_UNIT:
8216 case ACTION_HOME_CITY:
8217 case ACTION_HOMELESS:
8218 case ACTION_UPGRADE_UNIT:
8219 case ACTION_PARADROP:
8220 case ACTION_PARADROP_CONQUER:
8221 case ACTION_PARADROP_FRIGHTEN:
8222 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8223 case ACTION_PARADROP_ENTER:
8224 case ACTION_PARADROP_ENTER_CONQUER:
8225 case ACTION_ATTACK:
8226 case ACTION_SUICIDE_ATTACK:
8227 case ACTION_STRIKE_BUILDING:
8228 case ACTION_STRIKE_PRODUCTION:
8229 case ACTION_CONQUER_CITY:
8230 case ACTION_CONQUER_CITY2:
8231 case ACTION_CONQUER_CITY3:
8232 case ACTION_CONQUER_CITY4:
8233 case ACTION_HEAL_UNIT:
8234 case ACTION_HEAL_UNIT2:
8235 case ACTION_TRANSFORM_TERRAIN:
8236 case ACTION_CULTIVATE:
8237 case ACTION_PLANT:
8238 case ACTION_PILLAGE:
8239 case ACTION_CLEAN_POLLUTION:
8240 case ACTION_CLEAN_FALLOUT:
8241 case ACTION_FORTIFY:
8242 case ACTION_ROAD:
8243 case ACTION_CONVERT:
8244 case ACTION_BASE:
8245 case ACTION_MINE:
8246 case ACTION_IRRIGATE:
8247 case ACTION_TRANSPORT_ALIGHT:
8248 case ACTION_TRANSPORT_BOARD:
8249 case ACTION_TRANSPORT_EMBARK:
8250 case ACTION_TRANSPORT_EMBARK2:
8251 case ACTION_TRANSPORT_EMBARK3:
8252 case ACTION_TRANSPORT_UNLOAD:
8253 case ACTION_TRANSPORT_DISEMBARK1:
8254 case ACTION_TRANSPORT_DISEMBARK2:
8255 case ACTION_TRANSPORT_DISEMBARK3:
8256 case ACTION_TRANSPORT_DISEMBARK4:
8257 case ACTION_SPY_ATTACK:
8258 case ACTION_CONQUER_EXTRAS:
8259 case ACTION_CONQUER_EXTRAS2:
8260 case ACTION_CONQUER_EXTRAS3:
8261 case ACTION_CONQUER_EXTRAS4:
8262 case ACTION_HUT_ENTER:
8263 case ACTION_HUT_ENTER2:
8264 case ACTION_HUT_ENTER3:
8265 case ACTION_HUT_ENTER4:
8266 case ACTION_HUT_FRIGHTEN:
8267 case ACTION_HUT_FRIGHTEN2:
8268 case ACTION_HUT_FRIGHTEN3:
8269 case ACTION_HUT_FRIGHTEN4:
8270 case ACTION_UNIT_MOVE:
8271 case ACTION_UNIT_MOVE2:
8272 case ACTION_UNIT_MOVE3:
8273 /* Max range is not ruleset changeable */
8274 return NULL;
8275 case ACTION_HELP_WONDER:
8276 return "help_wonder_max_range";
8277 case ACTION_DISBAND_UNIT_RECOVER:
8278 return "disband_unit_recover_max_range";
8279 case ACTION_BOMBARD:
8280 return "bombard_max_range";
8281 case ACTION_BOMBARD2:
8282 return "bombard_2_max_range";
8283 case ACTION_BOMBARD3:
8284 return "bombard_3_max_range";
8285 case ACTION_NUKE:
8286 return "explode_nuclear_max_range";
8287 case ACTION_NUKE_CITY:
8288 return "nuke_city_max_range";
8289 case ACTION_NUKE_UNITS:
8290 return "nuke_units_max_range";
8291 case ACTION_AIRLIFT:
8292 return "airlift_max_range";
8293 case ACTION_USER_ACTION1:
8294 return "user_action_1_max_range";
8295 case ACTION_USER_ACTION2:
8296 return "user_action_2_max_range";
8297 case ACTION_USER_ACTION3:
8298 return "user_action_3_max_range";
8299 case ACTION_USER_ACTION4:
8300 return "user_action_4_max_range";
8301 case ACTION_COUNT:
8302 break;
8303 }
8304
8305 fc_assert(act >= 0 && act < ACTION_COUNT);
8306 return NULL;
8307}
8308
8309/**********************************************************************/
8312 int action_max_range_default(enum action_result result)
8313{
8314 switch (result) {
8315 case ACTRES_ESTABLISH_EMBASSY:
8316 case ACTRES_SPY_INVESTIGATE_CITY:
8317 case ACTRES_SPY_POISON:
8318 case ACTRES_SPY_STEAL_GOLD:
8319 case ACTRES_SPY_SABOTAGE_CITY:
8320 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8321 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8322 case ACTRES_SPY_STEAL_TECH:
8323 case ACTRES_SPY_TARGETED_STEAL_TECH:
8324 case ACTRES_SPY_INCITE_CITY:
8325 case ACTRES_TRADE_ROUTE:
8326 case ACTRES_MARKETPLACE:
8327 case ACTRES_SPY_BRIBE_UNIT:
8328 case ACTRES_SPY_SABOTAGE_UNIT:
8329 case ACTRES_CAPTURE_UNITS:
8330 case ACTRES_FOUND_CITY:
8331 case ACTRES_JOIN_CITY:
8332 case ACTRES_STEAL_MAPS:
8333 case ACTRES_SPY_NUKE:
8334 case ACTRES_DESTROY_CITY:
8335 case ACTRES_EXPEL_UNIT:
8336 case ACTRES_DISBAND_UNIT:
8337 case ACTRES_HOME_CITY:
8338 case ACTRES_HOMELESS:
8339 case ACTRES_UPGRADE_UNIT:
8340 case ACTRES_PARADROP:
8341 case ACTRES_PARADROP_CONQUER:
8342 case ACTRES_STRIKE_BUILDING:
8343 case ACTRES_STRIKE_PRODUCTION:
8344 case ACTRES_ATTACK:
8345 case ACTRES_CONQUER_CITY:
8346 case ACTRES_HEAL_UNIT:
8347 case ACTRES_TRANSFORM_TERRAIN:
8348 case ACTRES_CULTIVATE:
8349 case ACTRES_PLANT:
8350 case ACTRES_PILLAGE:
8351 case ACTRES_CLEAN_POLLUTION:
8352 case ACTRES_CLEAN_FALLOUT:
8353 case ACTRES_FORTIFY:
8354 case ACTRES_ROAD:
8355 case ACTRES_CONVERT:
8356 case ACTRES_BASE:
8357 case ACTRES_MINE:
8358 case ACTRES_IRRIGATE:
8359 case ACTRES_TRANSPORT_ALIGHT:
8360 case ACTRES_TRANSPORT_UNLOAD:
8361 case ACTRES_TRANSPORT_DISEMBARK:
8362 case ACTRES_TRANSPORT_BOARD:
8363 case ACTRES_TRANSPORT_EMBARK:
8364 case ACTRES_SPY_ATTACK:
8365 case ACTRES_SPY_SPREAD_PLAGUE:
8366 case ACTRES_CONQUER_EXTRAS:
8367 case ACTRES_HUT_ENTER:
8368 case ACTRES_HUT_FRIGHTEN:
8369 case ACTRES_UNIT_MOVE:
8370 /* Non ruleset defined action max range not supported here */
8371 fc_assert_msg(FALSE, "Probably wrong value.");
8372 return RS_DEFAULT_ACTION_MAX_RANGE;
8373 case ACTRES_HELP_WONDER:
8374 case ACTRES_DISBAND_UNIT_RECOVER:
8375 return RS_DEFAULT_ACTION_MAX_RANGE;
8376 case ACTRES_BOMBARD:
8377 return RS_DEFAULT_ACTION_MAX_RANGE;
8378 case ACTRES_NUKE:
8379 return RS_DEFAULT_EXPLODE_NUCLEAR_MAX_RANGE;
8380 case ACTRES_NUKE_UNITS:
8381 return RS_DEFAULT_ACTION_MAX_RANGE;
8382 case ACTRES_AIRLIFT:
8383 return ACTION_DISTANCE_UNLIMITED;
8384 case ACTRES_NONE:
8385 return RS_DEFAULT_ACTION_MAX_RANGE;
8386 }
8387
8388 fc_assert(action_result_is_valid(result) || result == ACTRES_NONE);
8389 return 0;
8390}
8391
8392/**********************************************************************/
8398 const char *action_target_kind_ruleset_var_name(int act)
8399{
8400 switch ((enum gen_action)act) {
8401 case ACTION_SPY_POISON:
8402 case ACTION_SPY_POISON_ESC:
8403 case ACTION_SPY_SABOTAGE_UNIT:
8404 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8405 case ACTION_SPY_BRIBE_UNIT:
8406 case ACTION_SPY_SABOTAGE_CITY:
8407 case ACTION_SPY_SABOTAGE_CITY_ESC:
8408 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8409 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8410 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8411 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8412 case ACTION_SPY_INCITE_CITY:
8413 case ACTION_SPY_INCITE_CITY_ESC:
8414 case ACTION_ESTABLISH_EMBASSY:
8415 case ACTION_ESTABLISH_EMBASSY_STAY:
8416 case ACTION_SPY_STEAL_TECH:
8417 case ACTION_SPY_STEAL_TECH_ESC:
8418 case ACTION_SPY_TARGETED_STEAL_TECH:
8419 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8420 case ACTION_SPY_INVESTIGATE_CITY:
8421 case ACTION_INV_CITY_SPEND:
8422 case ACTION_SPY_STEAL_GOLD:
8423 case ACTION_SPY_STEAL_GOLD_ESC:
8424 case ACTION_SPY_SPREAD_PLAGUE:
8425 case ACTION_STEAL_MAPS:
8426 case ACTION_STEAL_MAPS_ESC:
8427 case ACTION_TRADE_ROUTE:
8428 case ACTION_MARKETPLACE:
8429 case ACTION_HELP_WONDER:
8430 case ACTION_CAPTURE_UNITS:
8431 case ACTION_EXPEL_UNIT:
8432 case ACTION_FOUND_CITY:
8433 case ACTION_JOIN_CITY:
8434 case ACTION_SPY_NUKE:
8435 case ACTION_SPY_NUKE_ESC:
8436 case ACTION_NUKE_UNITS:
8437 case ACTION_DESTROY_CITY:
8438 case ACTION_DISBAND_UNIT_RECOVER:
8439 case ACTION_DISBAND_UNIT:
8440 case ACTION_HOME_CITY:
8441 case ACTION_HOMELESS:
8442 case ACTION_UPGRADE_UNIT:
8443 case ACTION_PARADROP:
8444 case ACTION_PARADROP_CONQUER:
8445 case ACTION_PARADROP_FRIGHTEN:
8446 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8447 case ACTION_PARADROP_ENTER:
8448 case ACTION_PARADROP_ENTER_CONQUER:
8449 case ACTION_AIRLIFT:
8450 case ACTION_ATTACK:
8451 case ACTION_SUICIDE_ATTACK:
8452 case ACTION_STRIKE_BUILDING:
8453 case ACTION_STRIKE_PRODUCTION:
8454 case ACTION_CONQUER_CITY:
8455 case ACTION_CONQUER_CITY2:
8456 case ACTION_CONQUER_CITY3:
8457 case ACTION_CONQUER_CITY4:
8458 case ACTION_HEAL_UNIT:
8459 case ACTION_HEAL_UNIT2:
8460 case ACTION_TRANSFORM_TERRAIN:
8461 case ACTION_CULTIVATE:
8462 case ACTION_PLANT:
8463 case ACTION_CLEAN_POLLUTION:
8464 case ACTION_CLEAN_FALLOUT:
8465 case ACTION_FORTIFY:
8466 case ACTION_ROAD:
8467 case ACTION_CONVERT:
8468 case ACTION_BASE:
8469 case ACTION_MINE:
8470 case ACTION_IRRIGATE:
8471 case ACTION_TRANSPORT_ALIGHT:
8472 case ACTION_TRANSPORT_BOARD:
8473 case ACTION_TRANSPORT_EMBARK:
8474 case ACTION_TRANSPORT_EMBARK2:
8475 case ACTION_TRANSPORT_EMBARK3:
8476 case ACTION_TRANSPORT_UNLOAD:
8477 case ACTION_TRANSPORT_DISEMBARK1:
8478 case ACTION_TRANSPORT_DISEMBARK2:
8479 case ACTION_TRANSPORT_DISEMBARK3:
8480 case ACTION_TRANSPORT_DISEMBARK4:
8481 case ACTION_BOMBARD:
8482 case ACTION_BOMBARD2:
8483 case ACTION_BOMBARD3:
8484 case ACTION_SPY_ATTACK:
8485 case ACTION_CONQUER_EXTRAS:
8486 case ACTION_CONQUER_EXTRAS2:
8487 case ACTION_CONQUER_EXTRAS3:
8488 case ACTION_CONQUER_EXTRAS4:
8489 case ACTION_HUT_ENTER:
8490 case ACTION_HUT_ENTER2:
8491 case ACTION_HUT_ENTER3:
8492 case ACTION_HUT_ENTER4:
8493 case ACTION_HUT_FRIGHTEN:
8494 case ACTION_HUT_FRIGHTEN2:
8495 case ACTION_HUT_FRIGHTEN3:
8496 case ACTION_HUT_FRIGHTEN4:
8497 case ACTION_UNIT_MOVE:
8498 case ACTION_UNIT_MOVE2:
8499 case ACTION_UNIT_MOVE3:
8500 /* Target kind is not ruleset changeable */
8501 return NULL;
8502 case ACTION_NUKE:
8503 return "explode_nuclear_target_kind";
8504 case ACTION_NUKE_CITY:
8505 return "nuke_city_target_kind";
8506 case ACTION_PILLAGE:
8507 return "pillage_target_kind";
8508 case ACTION_USER_ACTION1:
8509 return "user_action_1_target_kind";
8510 case ACTION_USER_ACTION2:
8511 return "user_action_2_target_kind";
8512 case ACTION_USER_ACTION3:
8513 return "user_action_3_target_kind";
8514 case ACTION_USER_ACTION4:
8515 return "user_action_4_target_kind";
8516 case ACTION_COUNT:
8517 break;
8518 }
8519
8520 fc_assert(act >= 0 && act < ACTION_COUNT);
8521 return NULL;
8522}
8523
8524/**********************************************************************/
8527enum action_target_kind
8528action_target_kind_default(enum action_result result)
8529{
8530 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8531 RS_DEFAULT_USER_ACTION_TARGET_KIND);
8532
8533 switch (result) {
8534 case ACTRES_ESTABLISH_EMBASSY:
8535 case ACTRES_SPY_INVESTIGATE_CITY:
8536 case ACTRES_SPY_POISON:
8537 case ACTRES_SPY_STEAL_GOLD:
8538 case ACTRES_SPY_SABOTAGE_CITY:
8539 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8540 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8541 case ACTRES_SPY_STEAL_TECH:
8542 case ACTRES_SPY_TARGETED_STEAL_TECH:
8543 case ACTRES_SPY_INCITE_CITY:
8544 case ACTRES_TRADE_ROUTE:
8545 case ACTRES_MARKETPLACE:
8546 case ACTRES_HELP_WONDER:
8547 case ACTRES_JOIN_CITY:
8548 case ACTRES_STEAL_MAPS:
8549 case ACTRES_SPY_NUKE:
8550 case ACTRES_DESTROY_CITY:
8551 case ACTRES_DISBAND_UNIT_RECOVER:
8552 case ACTRES_HOME_CITY:
8553 case ACTRES_UPGRADE_UNIT:
8554 case ACTRES_AIRLIFT:
8555 case ACTRES_STRIKE_BUILDING:
8556 case ACTRES_STRIKE_PRODUCTION:
8557 case ACTRES_CONQUER_CITY:
8558 case ACTRES_SPY_SPREAD_PLAGUE:
8559 return ATK_CITY;
8560 case ACTRES_SPY_BRIBE_UNIT:
8561 case ACTRES_SPY_SABOTAGE_UNIT:
8562 case ACTRES_EXPEL_UNIT:
8563 case ACTRES_HEAL_UNIT:
8564 case ACTRES_TRANSPORT_ALIGHT:
8565 case ACTRES_TRANSPORT_UNLOAD:
8566 case ACTRES_TRANSPORT_BOARD:
8567 case ACTRES_TRANSPORT_EMBARK:
8568 return ATK_UNIT;
8569 case ACTRES_BOMBARD:
8570 case ACTRES_ATTACK:
8571 case ACTRES_CAPTURE_UNITS:
8572 case ACTRES_NUKE_UNITS:
8573 case ACTRES_SPY_ATTACK:
8574 return ATK_UNITS;
8575 case ACTRES_FOUND_CITY:
8576 case ACTRES_NUKE:
8577 case ACTRES_PARADROP:
8578 case ACTRES_PARADROP_CONQUER:
8579 case ACTRES_TRANSFORM_TERRAIN:
8580 case ACTRES_CULTIVATE:
8581 case ACTRES_PLANT:
8582 case ACTRES_PILLAGE:
8583 case ACTRES_CLEAN_POLLUTION:
8584 case ACTRES_CLEAN_FALLOUT:
8585 case ACTRES_ROAD:
8586 case ACTRES_BASE:
8587 case ACTRES_MINE:
8588 case ACTRES_IRRIGATE:
8589 case ACTRES_TRANSPORT_DISEMBARK:
8590 case ACTRES_HUT_ENTER:
8591 case ACTRES_HUT_FRIGHTEN:
8592 case ACTRES_UNIT_MOVE:
8593 return ATK_TILE;
8594 case ACTRES_CONQUER_EXTRAS:
8595 return ATK_EXTRAS;
8596 case ACTRES_DISBAND_UNIT:
8597 case ACTRES_CONVERT:
8598 case ACTRES_FORTIFY:
8599 case ACTRES_HOMELESS:
8600 return ATK_SELF;
8601 case ACTRES_NONE:
8602 return RS_DEFAULT_USER_ACTION_TARGET_KIND;
8603 }
8604
8605 /* Should never be reached. */
8606 return RS_DEFAULT_USER_ACTION_TARGET_KIND;
8607}
8608
8609/**********************************************************************/
8613 bool action_result_legal_target_kind(enum action_result result,
8614 enum action_target_kind tgt_kind)
8615{
8616 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8617 FALSE);
8618 fc_assert_ret_val(action_target_kind_is_valid(tgt_kind),
8619 FALSE);
8620
8621 switch (result) {
8622 case ACTRES_ESTABLISH_EMBASSY:
8623 case ACTRES_SPY_INVESTIGATE_CITY:
8624 case ACTRES_SPY_POISON:
8625 case ACTRES_SPY_STEAL_GOLD:
8626 case ACTRES_SPY_SABOTAGE_CITY:
8627 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8628 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8629 case ACTRES_SPY_STEAL_TECH:
8630 case ACTRES_SPY_TARGETED_STEAL_TECH:
8631 case ACTRES_SPY_INCITE_CITY:
8632 case ACTRES_TRADE_ROUTE:
8633 case ACTRES_MARKETPLACE:
8634 case ACTRES_HELP_WONDER:
8635 case ACTRES_JOIN_CITY:
8636 case ACTRES_STEAL_MAPS:
8637 case ACTRES_SPY_NUKE:
8638 case ACTRES_DESTROY_CITY:
8639 case ACTRES_DISBAND_UNIT_RECOVER:
8640 case ACTRES_HOME_CITY:
8641 case ACTRES_UPGRADE_UNIT:
8642 case ACTRES_AIRLIFT:
8643 case ACTRES_STRIKE_BUILDING:
8644 case ACTRES_STRIKE_PRODUCTION:
8645 case ACTRES_CONQUER_CITY:
8646 case ACTRES_SPY_SPREAD_PLAGUE:
8647 return tgt_kind == ATK_CITY;
8648 case ACTRES_SPY_BRIBE_UNIT:
8649 case ACTRES_SPY_SABOTAGE_UNIT:
8650 case ACTRES_EXPEL_UNIT:
8651 case ACTRES_HEAL_UNIT:
8652 case ACTRES_TRANSPORT_ALIGHT:
8653 case ACTRES_TRANSPORT_UNLOAD:
8654 case ACTRES_TRANSPORT_BOARD:
8655 case ACTRES_TRANSPORT_EMBARK:
8656 return tgt_kind == ATK_UNIT;
8657 case ACTRES_CAPTURE_UNITS:
8658 case ACTRES_BOMBARD:
8659 case ACTRES_NUKE_UNITS:
8660 case ACTRES_ATTACK:
8661 case ACTRES_SPY_ATTACK:
8662 return tgt_kind == ATK_UNITS;
8663 case ACTRES_FOUND_CITY:
8664 case ACTRES_PARADROP:
8665 case ACTRES_PARADROP_CONQUER:
8666 case ACTRES_TRANSFORM_TERRAIN:
8667 case ACTRES_CULTIVATE:
8668 case ACTRES_PLANT:
8669 case ACTRES_CLEAN_POLLUTION:
8670 case ACTRES_CLEAN_FALLOUT:
8671 case ACTRES_ROAD:
8672 case ACTRES_BASE:
8673 case ACTRES_MINE:
8674 case ACTRES_IRRIGATE:
8675 case ACTRES_TRANSPORT_DISEMBARK:
8676 case ACTRES_HUT_ENTER:
8677 case ACTRES_HUT_FRIGHTEN:
8678 case ACTRES_UNIT_MOVE:
8679 return tgt_kind == ATK_TILE;
8680 case ACTRES_CONQUER_EXTRAS:
8681 return tgt_kind == ATK_EXTRAS;
8682 case ACTRES_DISBAND_UNIT:
8683 case ACTRES_CONVERT:
8684 case ACTRES_FORTIFY:
8685 case ACTRES_HOMELESS:
8686 return tgt_kind == ATK_SELF;
8687 case ACTRES_PILLAGE:
8688 return (tgt_kind == ATK_TILE || tgt_kind == ATK_EXTRAS);
8689 case ACTRES_NUKE:
8690 return (tgt_kind == ATK_TILE || tgt_kind == ATK_CITY);
8691 case ACTRES_NONE:
8692 switch (tgt_kind) {
8693 case ATK_CITY:
8694 case ATK_UNIT:
8695 case ATK_UNITS:
8696 case ATK_TILE:
8697 case ATK_EXTRAS:
8698 case ATK_SELF:
8699 /* Works with all existing target kinds. */
8700 return TRUE;
8701 case ATK_COUNT:
8702 fc_assert_ret_val(tgt_kind != ATK_COUNT, FALSE);
8703 break;
8704 }
8705 break;
8706 }
8707
8708 /* Should never be reached. */
8709 return FALSE;
8710}
8711
8712/**********************************************************************/
8715static enum action_sub_target_kind
8716action_sub_target_kind_default(enum action_result result)
8717{
8718 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8719 ASTK_NONE);
8720
8721 switch (result) {
8722 case ACTRES_ESTABLISH_EMBASSY:
8723 case ACTRES_SPY_INVESTIGATE_CITY:
8724 case ACTRES_SPY_POISON:
8725 case ACTRES_SPY_STEAL_GOLD:
8726 case ACTRES_SPY_SABOTAGE_CITY:
8727 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8728 case ACTRES_SPY_STEAL_TECH:
8729 case ACTRES_SPY_INCITE_CITY:
8730 case ACTRES_TRADE_ROUTE:
8731 case ACTRES_MARKETPLACE:
8732 case ACTRES_HELP_WONDER:
8733 case ACTRES_JOIN_CITY:
8734 case ACTRES_STEAL_MAPS:
8735 case ACTRES_SPY_NUKE:
8736 case ACTRES_DESTROY_CITY:
8737 case ACTRES_DISBAND_UNIT_RECOVER:
8738 case ACTRES_HOME_CITY:
8739 case ACTRES_HOMELESS:
8740 case ACTRES_UPGRADE_UNIT:
8741 case ACTRES_AIRLIFT:
8742 case ACTRES_STRIKE_PRODUCTION:
8743 case ACTRES_CONQUER_CITY:
8744 case ACTRES_SPY_SPREAD_PLAGUE:
8745 return ASTK_NONE;
8746 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8747 case ACTRES_STRIKE_BUILDING:
8748 return ASTK_BUILDING;
8749 case ACTRES_SPY_TARGETED_STEAL_TECH:
8750 return ASTK_TECH;
8751 case ACTRES_SPY_BRIBE_UNIT:
8752 case ACTRES_SPY_SABOTAGE_UNIT:
8753 case ACTRES_EXPEL_UNIT:
8754 case ACTRES_HEAL_UNIT:
8755 case ACTRES_TRANSPORT_ALIGHT:
8756 case ACTRES_TRANSPORT_UNLOAD:
8757 case ACTRES_TRANSPORT_BOARD:
8758 case ACTRES_TRANSPORT_EMBARK:
8759 return ASTK_NONE;
8760 case ACTRES_CAPTURE_UNITS:
8761 case ACTRES_BOMBARD:
8762 case ACTRES_NUKE_UNITS:
8763 case ACTRES_ATTACK:
8764 case ACTRES_SPY_ATTACK:
8765 return ASTK_NONE;
8766 case ACTRES_FOUND_CITY:
8767 case ACTRES_NUKE:
8768 case ACTRES_PARADROP:
8769 case ACTRES_PARADROP_CONQUER:
8770 case ACTRES_TRANSFORM_TERRAIN:
8771 case ACTRES_CULTIVATE:
8772 case ACTRES_PLANT:
8773 case ACTRES_TRANSPORT_DISEMBARK:
8774 case ACTRES_HUT_ENTER:
8775 case ACTRES_HUT_FRIGHTEN:
8776 case ACTRES_UNIT_MOVE:
8777 return ASTK_NONE;
8778 case ACTRES_PILLAGE:
8779 case ACTRES_CLEAN_POLLUTION:
8780 case ACTRES_CLEAN_FALLOUT:
8781 return ASTK_EXTRA;
8782 case ACTRES_ROAD:
8783 case ACTRES_BASE:
8784 case ACTRES_MINE:
8785 case ACTRES_IRRIGATE:
8786 return ASTK_EXTRA_NOT_THERE;
8787 case ACTRES_CONQUER_EXTRAS:
8788 return ASTK_NONE;
8789 case ACTRES_DISBAND_UNIT:
8790 case ACTRES_CONVERT:
8791 case ACTRES_FORTIFY:
8792 return ASTK_NONE;
8793 case ACTRES_NONE:
8794 return ASTK_NONE;
8795 }
8796
8797 /* Should never be reached. */
8798 return ASTK_NONE;
8799}
8800
8801/**********************************************************************/
8805static enum act_tgt_compl
8806action_target_compl_calc(enum action_result result,
8807 enum action_target_kind tgt_kind,
8808 enum action_sub_target_kind sub_tgt_kind)
8809{
8810 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8811 ACT_TGT_COMPL_SIMPLE);
8812
8813 switch (result) {
8814 case ACTRES_ESTABLISH_EMBASSY:
8815 case ACTRES_SPY_INVESTIGATE_CITY:
8816 case ACTRES_SPY_POISON:
8817 case ACTRES_SPY_STEAL_GOLD:
8818 case ACTRES_SPY_SABOTAGE_CITY:
8819 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8820 case ACTRES_SPY_STEAL_TECH:
8821 case ACTRES_SPY_INCITE_CITY:
8822 case ACTRES_TRADE_ROUTE:
8823 case ACTRES_MARKETPLACE:
8824 case ACTRES_HELP_WONDER:
8825 case ACTRES_JOIN_CITY:
8826 case ACTRES_STEAL_MAPS:
8827 case ACTRES_SPY_NUKE:
8828 case ACTRES_DESTROY_CITY:
8829 case ACTRES_DISBAND_UNIT_RECOVER:
8830 case ACTRES_HOME_CITY:
8831 case ACTRES_HOMELESS:
8832 case ACTRES_UPGRADE_UNIT:
8833 case ACTRES_AIRLIFT:
8834 case ACTRES_STRIKE_PRODUCTION:
8835 case ACTRES_CONQUER_CITY:
8836 case ACTRES_SPY_SPREAD_PLAGUE:
8837 return ACT_TGT_COMPL_SIMPLE;
8838 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8839 case ACTRES_STRIKE_BUILDING:
8840 case ACTRES_SPY_TARGETED_STEAL_TECH:
8841 return ACT_TGT_COMPL_MANDATORY;
8842 case ACTRES_SPY_BRIBE_UNIT:
8843 case ACTRES_SPY_SABOTAGE_UNIT:
8844 case ACTRES_EXPEL_UNIT:
8845 case ACTRES_HEAL_UNIT:
8846 case ACTRES_TRANSPORT_ALIGHT:
8847 case ACTRES_TRANSPORT_UNLOAD:
8848 case ACTRES_TRANSPORT_BOARD:
8849 case ACTRES_TRANSPORT_EMBARK:
8850 return ACT_TGT_COMPL_SIMPLE;
8851 case ACTRES_CAPTURE_UNITS:
8852 case ACTRES_BOMBARD:
8853 case ACTRES_NUKE_UNITS:
8854 case ACTRES_ATTACK:
8855 case ACTRES_SPY_ATTACK:
8856 return ACT_TGT_COMPL_SIMPLE;
8857 case ACTRES_FOUND_CITY:
8858 case ACTRES_NUKE:
8859 case ACTRES_PARADROP:
8860 case ACTRES_PARADROP_CONQUER:
8861 case ACTRES_TRANSFORM_TERRAIN:
8862 case ACTRES_CULTIVATE:
8863 case ACTRES_PLANT:
8864 case ACTRES_TRANSPORT_DISEMBARK:
8865 case ACTRES_HUT_ENTER:
8866 case ACTRES_HUT_FRIGHTEN:
8867 case ACTRES_UNIT_MOVE:
8868 return ACT_TGT_COMPL_SIMPLE;
8869 case ACTRES_PILLAGE:
8870 case ACTRES_CLEAN_POLLUTION:
8871 case ACTRES_CLEAN_FALLOUT:
8872 return ACT_TGT_COMPL_FLEXIBLE;
8873 case ACTRES_ROAD:
8874 case ACTRES_BASE:
8875 case ACTRES_MINE:
8876 case ACTRES_IRRIGATE:
8877 return ACT_TGT_COMPL_MANDATORY;
8878 case ACTRES_CONQUER_EXTRAS:
8879 return ACT_TGT_COMPL_SIMPLE;
8880 case ACTRES_DISBAND_UNIT:
8881 case ACTRES_CONVERT:
8882 case ACTRES_FORTIFY:
8883 return ACT_TGT_COMPL_SIMPLE;
8884 case ACTRES_NONE:
8885 return ACT_TGT_COMPL_SIMPLE;
8886 }
8887
8888 /* Should never be reached. */
8889 return ACT_TGT_COMPL_SIMPLE;
8890}
8891
8892/**********************************************************************/
8899 const char *action_actor_consuming_always_ruleset_var_name(action_id act)
8900{
8901 switch ((enum gen_action)act) {
8902 case ACTION_SPY_POISON:
8903 case ACTION_SPY_POISON_ESC:
8904 case ACTION_SPY_SABOTAGE_UNIT:
8905 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8906 case ACTION_SPY_BRIBE_UNIT:
8907 case ACTION_SPY_SABOTAGE_CITY:
8908 case ACTION_SPY_SABOTAGE_CITY_ESC:
8909 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8910 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8911 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8912 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8913 case ACTION_SPY_INCITE_CITY:
8914 case ACTION_SPY_INCITE_CITY_ESC:
8915 case ACTION_ESTABLISH_EMBASSY:
8916 case ACTION_ESTABLISH_EMBASSY_STAY:
8917 case ACTION_SPY_STEAL_TECH:
8918 case ACTION_SPY_STEAL_TECH_ESC:
8919 case ACTION_SPY_TARGETED_STEAL_TECH:
8920 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8921 case ACTION_SPY_INVESTIGATE_CITY:
8922 case ACTION_INV_CITY_SPEND:
8923 case ACTION_SPY_STEAL_GOLD:
8924 case ACTION_SPY_STEAL_GOLD_ESC:
8925 case ACTION_STEAL_MAPS:
8926 case ACTION_STEAL_MAPS_ESC:
8927 case ACTION_TRADE_ROUTE:
8928 case ACTION_MARKETPLACE:
8929 case ACTION_HELP_WONDER:
8930 case ACTION_CAPTURE_UNITS:
8931 case ACTION_EXPEL_UNIT:
8932 case ACTION_JOIN_CITY:
8933 case ACTION_SPY_NUKE:
8934 case ACTION_SPY_NUKE_ESC:
8935 case ACTION_DESTROY_CITY:
8936 case ACTION_DISBAND_UNIT_RECOVER:
8937 case ACTION_DISBAND_UNIT:
8938 case ACTION_HOME_CITY:
8939 case ACTION_HOMELESS:
8940 case ACTION_UPGRADE_UNIT:
8941 case ACTION_PARADROP:
8942 case ACTION_PARADROP_CONQUER:
8943 case ACTION_PARADROP_FRIGHTEN:
8944 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8945 case ACTION_PARADROP_ENTER:
8946 case ACTION_PARADROP_ENTER_CONQUER:
8947 case ACTION_AIRLIFT:
8948 case ACTION_ATTACK:
8949 case ACTION_SUICIDE_ATTACK:
8950 case ACTION_STRIKE_BUILDING:
8951 case ACTION_STRIKE_PRODUCTION:
8952 case ACTION_CONQUER_CITY:
8953 case ACTION_CONQUER_CITY2:
8954 case ACTION_CONQUER_CITY3:
8955 case ACTION_CONQUER_CITY4:
8956 case ACTION_HEAL_UNIT:
8957 case ACTION_HEAL_UNIT2:
8958 case ACTION_TRANSFORM_TERRAIN:
8959 case ACTION_CULTIVATE:
8960 case ACTION_PLANT:
8961 case ACTION_PILLAGE:
8962 case ACTION_CLEAN_POLLUTION:
8963 case ACTION_CLEAN_FALLOUT:
8964 case ACTION_FORTIFY:
8965 case ACTION_ROAD:
8966 case ACTION_CONVERT:
8967 case ACTION_BASE:
8968 case ACTION_MINE:
8969 case ACTION_IRRIGATE:
8970 case ACTION_TRANSPORT_ALIGHT:
8971 case ACTION_TRANSPORT_BOARD:
8972 case ACTION_TRANSPORT_EMBARK:
8973 case ACTION_TRANSPORT_EMBARK2:
8974 case ACTION_TRANSPORT_EMBARK3:
8975 case ACTION_TRANSPORT_UNLOAD:
8976 case ACTION_TRANSPORT_DISEMBARK1:
8977 case ACTION_TRANSPORT_DISEMBARK2:
8978 case ACTION_TRANSPORT_DISEMBARK3:
8979 case ACTION_TRANSPORT_DISEMBARK4:
8980 case ACTION_BOMBARD:
8981 case ACTION_BOMBARD2:
8982 case ACTION_BOMBARD3:
8983 case ACTION_SPY_ATTACK:
8984 case ACTION_CONQUER_EXTRAS:
8985 case ACTION_CONQUER_EXTRAS2:
8986 case ACTION_CONQUER_EXTRAS3:
8987 case ACTION_CONQUER_EXTRAS4:
8988 case ACTION_HUT_ENTER:
8989 case ACTION_HUT_ENTER2:
8990 case ACTION_HUT_ENTER3:
8991 case ACTION_HUT_ENTER4:
8992 case ACTION_HUT_FRIGHTEN:
8993 case ACTION_HUT_FRIGHTEN2:
8994 case ACTION_HUT_FRIGHTEN3:
8995 case ACTION_HUT_FRIGHTEN4:
8996 case ACTION_UNIT_MOVE:
8997 case ACTION_UNIT_MOVE2:
8998 case ACTION_UNIT_MOVE3:
8999 /* actor consuming always is not ruleset changeable */
9000 return NULL;
9001 case ACTION_FOUND_CITY:
9002 return "found_city_consuming_always";
9003 case ACTION_NUKE:
9004 return "explode_nuclear_consuming_always";
9005 case ACTION_NUKE_CITY:
9006 return "nuke_city_consuming_always";
9007 case ACTION_NUKE_UNITS:
9008 return "nuke_units_consuming_always";
9009 case ACTION_SPY_SPREAD_PLAGUE:
9010 return "spread_plague_actor_consuming_always";
9011 case ACTION_USER_ACTION1:
9012 return "user_action_1_actor_consuming_always";
9013 case ACTION_USER_ACTION2:
9014 return "user_action_2_actor_consuming_always";
9015 case ACTION_USER_ACTION3:
9016 return "user_action_3_actor_consuming_always";
9017 case ACTION_USER_ACTION4:
9018 return "user_action_4_actor_consuming_always";
9019 case ACTION_COUNT:
9020 break;
9021 }
9022
9023 fc_assert(act >= 0 && act < ACTION_COUNT);
9024 return NULL;
9025}
9026
9027/**********************************************************************/
9034 const char *action_blocked_by_ruleset_var_name(const struct action *act)
9035{
9036 fc_assert_ret_val(act != NULL, NULL);
9037
9038 switch ((enum gen_action)action_number(act)) {
9039 case ACTION_MARKETPLACE:
9040 return "enter_marketplace_blocked_by";
9041 case ACTION_BOMBARD:
9042 return "bombard_blocked_by";
9043 case ACTION_BOMBARD2:
9044 return "bombard_2_blocked_by";
9045 case ACTION_BOMBARD3:
9046 return "bombard_3_blocked_by";
9047 case ACTION_NUKE:
9048 return "explode_nuclear_blocked_by";
9049 case ACTION_NUKE_CITY:
9050 return "nuke_city_blocked_by";
9051 case ACTION_NUKE_UNITS:
9052 return "nuke_units_blocked_by";
9053 case ACTION_ATTACK:
9054 return "attack_blocked_by";
9055 case ACTION_SUICIDE_ATTACK:
9056 return "suicide_attack_blocked_by";
9057 case ACTION_CONQUER_CITY:
9058 return "conquer_city_blocked_by";
9059 case ACTION_CONQUER_CITY2:
9060 return "conquer_city_2_blocked_by";
9061 case ACTION_CONQUER_CITY3:
9062 return "conquer_city_3_blocked_by";
9063 case ACTION_CONQUER_CITY4:
9064 return "conquer_city_4_blocked_by";
9065 case ACTION_UNIT_MOVE:
9066 return "move_blocked_by";
9067 case ACTION_UNIT_MOVE2:
9068 return "move_2_blocked_by";
9069 case ACTION_UNIT_MOVE3:
9070 return "move_3_blocked_by";
9071 case ACTION_SPY_POISON:
9072 case ACTION_SPY_POISON_ESC:
9073 case ACTION_SPY_SABOTAGE_UNIT:
9074 case ACTION_SPY_SABOTAGE_UNIT_ESC:
9075 case ACTION_SPY_BRIBE_UNIT:
9076 case ACTION_SPY_SABOTAGE_CITY:
9077 case ACTION_SPY_SABOTAGE_CITY_ESC:
9078 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
9079 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
9080 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
9081 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
9082 case ACTION_SPY_INCITE_CITY:
9083 case ACTION_SPY_INCITE_CITY_ESC:
9084 case ACTION_ESTABLISH_EMBASSY:
9085 case ACTION_ESTABLISH_EMBASSY_STAY:
9086 case ACTION_SPY_STEAL_TECH:
9087 case ACTION_SPY_STEAL_TECH_ESC:
9088 case ACTION_SPY_TARGETED_STEAL_TECH:
9089 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
9090 case ACTION_SPY_INVESTIGATE_CITY:
9091 case ACTION_INV_CITY_SPEND:
9092 case ACTION_SPY_STEAL_GOLD:
9093 case ACTION_SPY_STEAL_GOLD_ESC:
9094 case ACTION_STEAL_MAPS:
9095 case ACTION_STEAL_MAPS_ESC:
9096 case ACTION_TRADE_ROUTE:
9097 case ACTION_HELP_WONDER:
9098 case ACTION_CAPTURE_UNITS:
9099 case ACTION_EXPEL_UNIT:
9100 case ACTION_FOUND_CITY:
9101 case ACTION_JOIN_CITY:
9102 case ACTION_SPY_NUKE:
9103 case ACTION_SPY_NUKE_ESC:
9104 case ACTION_DESTROY_CITY:
9105 case ACTION_DISBAND_UNIT_RECOVER:
9106 case ACTION_DISBAND_UNIT:
9107 case ACTION_HOME_CITY:
9108 case ACTION_HOMELESS:
9109 case ACTION_UPGRADE_UNIT:
9110 case ACTION_PARADROP:
9111 case ACTION_PARADROP_CONQUER:
9112 case ACTION_PARADROP_FRIGHTEN:
9113 case ACTION_PARADROP_FRIGHTEN_CONQUER:
9114 case ACTION_PARADROP_ENTER:
9115 case ACTION_PARADROP_ENTER_CONQUER:
9116 case ACTION_AIRLIFT:
9117 case ACTION_STRIKE_BUILDING:
9118 case ACTION_STRIKE_PRODUCTION:
9119 case ACTION_HEAL_UNIT:
9120 case ACTION_HEAL_UNIT2:
9121 case ACTION_TRANSFORM_TERRAIN:
9122 case ACTION_CULTIVATE:
9123 case ACTION_PLANT:
9124 case ACTION_PILLAGE:
9125 case ACTION_CLEAN_POLLUTION:
9126 case ACTION_CLEAN_FALLOUT:
9127 case ACTION_FORTIFY:
9128 case ACTION_ROAD:
9129 case ACTION_CONVERT:
9130 case ACTION_BASE:
9131 case ACTION_MINE:
9132 case ACTION_IRRIGATE:
9133 case ACTION_TRANSPORT_ALIGHT:
9134 case ACTION_TRANSPORT_BOARD:
9135 case ACTION_TRANSPORT_EMBARK:
9136 case ACTION_TRANSPORT_EMBARK2:
9137 case ACTION_TRANSPORT_EMBARK3:
9138 case ACTION_TRANSPORT_UNLOAD:
9139 case ACTION_TRANSPORT_DISEMBARK1:
9140 case ACTION_TRANSPORT_DISEMBARK2:
9141 case ACTION_TRANSPORT_DISEMBARK3:
9142 case ACTION_TRANSPORT_DISEMBARK4:
9143 case ACTION_SPY_SPREAD_PLAGUE:
9144 case ACTION_SPY_ATTACK:
9145 case ACTION_CONQUER_EXTRAS:
9146 case ACTION_CONQUER_EXTRAS2:
9147 case ACTION_CONQUER_EXTRAS3:
9148 case ACTION_CONQUER_EXTRAS4:
9149 case ACTION_HUT_ENTER:
9150 case ACTION_HUT_ENTER2:
9151 case ACTION_HUT_ENTER3:
9152 case ACTION_HUT_ENTER4:
9153 case ACTION_HUT_FRIGHTEN:
9154 case ACTION_HUT_FRIGHTEN2:
9155 case ACTION_HUT_FRIGHTEN3:
9156 case ACTION_HUT_FRIGHTEN4:
9157 case ACTION_USER_ACTION1:
9158 case ACTION_USER_ACTION2:
9159 case ACTION_USER_ACTION3:
9160 case ACTION_USER_ACTION4:
9161 /* blocked_by is not ruleset changeable */
9162 return NULL;
9163 case ACTION_COUNT:
9164 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
9165 break;
9166 }
9167
9168 return NULL;
9169}
9170
9171/**********************************************************************/
9175const char *
9176action_post_success_forced_ruleset_var_name(const struct action *act)
9177{
9178 fc_assert_ret_val(act != NULL, NULL);
9179
9180 if (!(action_has_result(act, ACTRES_SPY_BRIBE_UNIT)
9181 ||action_has_result(act, ACTRES_ATTACK))) {
9182 /* No support in the action performer function */
9183 return NULL;
9184 }
9185
9186 switch ((enum gen_action)action_number(act)) {
9187 case ACTION_SPY_BRIBE_UNIT:
9188 return "bribe_unit_post_success_forced_actions";
9189 case ACTION_ATTACK:
9190 return "attack_post_success_forced_actions";
9191 case ACTION_MARKETPLACE:
9192 case ACTION_BOMBARD:
9193 case ACTION_BOMBARD2:
9194 case ACTION_BOMBARD3:
9195 case ACTION_NUKE:
9196 case ACTION_NUKE_CITY:
9197 case ACTION_NUKE_UNITS:
9198 case ACTION_SUICIDE_ATTACK:
9199 case ACTION_CONQUER_CITY:
9200 case ACTION_CONQUER_CITY2:
9201 case ACTION_CONQUER_CITY3:
9202 case ACTION_CONQUER_CITY4:
9203 case ACTION_SPY_POISON:
9204 case ACTION_SPY_POISON_ESC:
9205 case ACTION_SPY_SABOTAGE_UNIT:
9206 case ACTION_SPY_SABOTAGE_UNIT_ESC:
9207 case ACTION_SPY_SABOTAGE_CITY:
9208 case ACTION_SPY_SABOTAGE_CITY_ESC:
9209 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
9210 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
9211 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
9212 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
9213 case ACTION_SPY_INCITE_CITY:
9214 case ACTION_SPY_INCITE_CITY_ESC:
9215 case ACTION_ESTABLISH_EMBASSY:
9216 case ACTION_ESTABLISH_EMBASSY_STAY:
9217 case ACTION_SPY_STEAL_TECH:
9218 case ACTION_SPY_STEAL_TECH_ESC:
9219 case ACTION_SPY_TARGETED_STEAL_TECH:
9220 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
9221 case ACTION_SPY_INVESTIGATE_CITY:
9222 case ACTION_INV_CITY_SPEND:
9223 case ACTION_SPY_STEAL_GOLD:
9224 case ACTION_SPY_STEAL_GOLD_ESC:
9225 case ACTION_STEAL_MAPS:
9226 case ACTION_STEAL_MAPS_ESC:
9227 case ACTION_TRADE_ROUTE:
9228 case ACTION_HELP_WONDER:
9229 case ACTION_CAPTURE_UNITS:
9230 case ACTION_EXPEL_UNIT:
9231 case ACTION_FOUND_CITY:
9232 case ACTION_JOIN_CITY:
9233 case ACTION_SPY_NUKE:
9234 case ACTION_SPY_NUKE_ESC:
9235 case ACTION_DESTROY_CITY:
9236 case ACTION_DISBAND_UNIT_RECOVER:
9237 case ACTION_DISBAND_UNIT:
9238 case ACTION_HOME_CITY:
9239 case ACTION_HOMELESS:
9240 case ACTION_UPGRADE_UNIT:
9241 case ACTION_PARADROP:
9242 case ACTION_PARADROP_CONQUER:
9243 case ACTION_PARADROP_FRIGHTEN:
9244 case ACTION_PARADROP_FRIGHTEN_CONQUER:
9245 case ACTION_PARADROP_ENTER:
9246 case ACTION_PARADROP_ENTER_CONQUER:
9247 case ACTION_AIRLIFT:
9248 case ACTION_STRIKE_BUILDING:
9249 case ACTION_STRIKE_PRODUCTION:
9250 case ACTION_HEAL_UNIT:
9251 case ACTION_HEAL_UNIT2:
9252 case ACTION_TRANSFORM_TERRAIN:
9253 case ACTION_CULTIVATE:
9254 case ACTION_PLANT:
9255 case ACTION_PILLAGE:
9256 case ACTION_CLEAN_POLLUTION:
9257 case ACTION_CLEAN_FALLOUT:
9258 case ACTION_FORTIFY:
9259 case ACTION_ROAD:
9260 case ACTION_CONVERT:
9261 case ACTION_BASE:
9262 case ACTION_MINE:
9263 case ACTION_IRRIGATE:
9264 case ACTION_TRANSPORT_ALIGHT:
9265 case ACTION_TRANSPORT_BOARD:
9266 case ACTION_TRANSPORT_EMBARK:
9267 case ACTION_TRANSPORT_EMBARK2:
9268 case ACTION_TRANSPORT_EMBARK3:
9269 case ACTION_TRANSPORT_UNLOAD:
9270 case ACTION_TRANSPORT_DISEMBARK1:
9271 case ACTION_TRANSPORT_DISEMBARK2:
9272 case ACTION_TRANSPORT_DISEMBARK3:
9273 case ACTION_TRANSPORT_DISEMBARK4:
9274 case ACTION_SPY_SPREAD_PLAGUE:
9275 case ACTION_SPY_ATTACK:
9276 case ACTION_CONQUER_EXTRAS:
9277 case ACTION_CONQUER_EXTRAS2:
9278 case ACTION_CONQUER_EXTRAS3:
9279 case ACTION_CONQUER_EXTRAS4:
9280 case ACTION_HUT_ENTER:
9281 case ACTION_HUT_ENTER2:
9282 case ACTION_HUT_ENTER3:
9283 case ACTION_HUT_ENTER4:
9284 case ACTION_HUT_FRIGHTEN:
9285 case ACTION_HUT_FRIGHTEN2:
9286 case ACTION_HUT_FRIGHTEN3:
9287 case ACTION_HUT_FRIGHTEN4:
9288 case ACTION_UNIT_MOVE:
9289 case ACTION_UNIT_MOVE2:
9290 case ACTION_UNIT_MOVE3:
9291 case ACTION_USER_ACTION1:
9292 case ACTION_USER_ACTION2:
9293 case ACTION_USER_ACTION3:
9294 case ACTION_USER_ACTION4:
9295 /* not ruleset changeable */
9296 return NULL;
9297 case ACTION_COUNT:
9298 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
9299 break;
9300 }
9301
9302 return NULL;
9303}
9304
9305/**********************************************************************/
9309 bool action_ever_possible(action_id action)
9310{
9311 return action_enabler_list_size(action_enablers_for_action(action)) > 0;
9312}
9313
9314/**********************************************************************/
9317 const char *gen_action_name_update_cb(const char *old_name)
9318{
9319 if (is_ruleset_compat_mode()) {
9320 if (!strcasecmp("Recycle Unit", old_name)) {
9321 return "Disband Unit Recover";
9322 }
9323 }
9324
9325 return old_name;
9326}
9327
9328 const char *atk_helpnames[ATK_COUNT] =
9329{
9330 N_("individual cities"), /* ATK_CITY */
9331 N_("individual units"), /* ATK_UNIT */
9332 N_("unit stacks"), /* ATK_UNITS */
9333 N_("tiles"), /* ATK_TILE */
9334 N_("tile extras"), /* ATK_EXTRAS */
9335 N_("itself") /* ATK_SELF */
9336};
9337
9338/**********************************************************************/
9342 const char *action_target_kind_help(enum action_target_kind kind)
9343{
9344 fc_assert(kind >= 0 && kind < ATK_COUNT);
9345
9346 return _(atk_helpnames[kind]);
9347}
9348
9349/************************************************************************/
9352 struct action_list *action_list_by_result(enum action_result result)
9353{
9354 fc_assert(result < ACTRES_LAST);
9355
9356 return actlist_by_result[result];
9357}
9358
9359/************************************************************************/
9362 struct action_list *action_list_by_activity(enum unit_activity activity)
9363{
9364 fc_assert(activity < ACTIVITY_LAST);
9365
9366 return actlist_by_activity[activity];
9367}
action_removes_extra
bool action_removes_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2312
is_action_possible_on_city
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:7146
actions
static struct action * actions[MAX_NUM_ACTIONS]
Definition actions.c:96
action_prepare_ui_name
const char * action_prepare_ui_name(action_id act_id, const char *mnemonic, const struct act_prob prob, const char *custom)
Definition actions.c:1972
action_name_translation
const char * action_name_translation(const struct action *action)
Definition actions.c:1890
action_distance_inside_max
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1833
oblig_hard_req_reg
static void oblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:247
is_action_possible
static enum fc_tristate is_action_possible(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct req_context *target, const struct extra_type *target_extra, const bool omniscient, const struct city *homecity)
Definition actions.c:3718
voblig_hard_req_reg
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:208
action_prob_explain
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:2083
action_mp_full_makes_legal
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:7224
action_prob_battle_then_dice_roll
static struct act_prob action_prob_battle_then_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct player *tgt_player, const struct action *paction)
Definition actions.c:5433
is_action_enabled_unit_on_self_full
static bool is_action_enabled_unit_on_self_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile)
Definition actions.c:5093
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
action_prob_certain
bool action_prob_certain(const struct act_prob probability)
Definition actions.c:6717
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
action_auto_perf_slot_number
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:7353
action_enabler_vector_number
req_vec_num_in_item action_enabler_vector_number(const void *enabler, const struct requirement_vector *vec)
Definition actions.c:2968
action_has_complex_target
bool action_has_complex_target(const struct action *paction)
Definition actions.c:1792
action_actor_utype_hard_reqs_ok_full
static bool action_actor_utype_hard_reqs_ok_full(const struct action *paction, const struct unit_type *actor_unittype, bool ignore_third_party)
Definition actions.c:3327
oblig_hard_reqs_r
static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE]
Definition actions.c:104
action_prob_self
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:6380
action_enabler_suggest_repair
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2838
is_action_enabled_unit_on_tile_full
static bool is_action_enabled_unit_on_tile_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4938
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6707
ACTPROB_VAL_NOT_IMPL
#define ACTPROB_VAL_NOT_IMPL
Definition actions.c:94
auto_perfs
struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS]
Definition actions.c:98
action_actor_utype_hard_reqs_ok
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3520
action_prob_new_not_impl
struct act_prob action_prob_new_not_impl(void)
Definition actions.c:6686
action_enabler_suggest_improvement
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2904
action_enabled_local
static enum fc_tristate action_enabled_local(const action_id wanted_action, const struct req_context *actor, const struct req_context *target)
Definition actions.c:5173
actions_rs_pre_san_gen
void actions_rs_pre_san_gen(void)
Definition actions.c:1520
action_min_range_ruleset_var_name
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:7966
action_list_end
void action_list_end(action_id *act_list, int size)
Definition actions.c:7401
action_blocked_by_ruleset_var_name
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:9034
is_action_enabled
static bool is_action_enabled(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct req_context *target, const struct extra_type *target_extra, const struct city *actor_home)
Definition actions.c:4651
ACTPROB_VAL_MAX
#define ACTPROB_VAL_MAX
Definition actions.c:88
action_prob
static struct act_prob action_prob(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct city *actor_home, const struct req_context *target, const struct extra_type *target_extra)
Definition actions.c:5480
action_enabler_suggest_repair_oblig
struct req_vec_problem * action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
Definition actions.c:2598
action_dice_roll_odds
int action_dice_roll_odds(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Definition actions.c:7068
req_contradiction_or
static struct ae_contra_or * req_contradiction_or(int alternatives,...)
Definition actions.c:160
action_prob_pre_action_dice_roll
static struct act_prob action_prob_pre_action_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Definition actions.c:5396
atk_helpnames
const char * atk_helpnames[ATK_COUNT]
Definition actions.c:9328
action_get_act_time
int action_get_act_time(const struct action *paction, const struct unit *actor_unit, const struct tile *tgt_tile, const struct extra_type *tgt_extra)
Definition actions.c:2173
action_hard_reqs_actor
static enum fc_tristate action_hard_reqs_actor(const struct civ_map *nmap, const struct action *paction, const struct req_context *actor, const bool omniscient, const struct city *homecity)
Definition actions.c:3540
hard_code_actions
static void hard_code_actions(void)
Definition actions.c:914
is_action_enabled_unit_on_city_full
static bool is_action_enabled_unit_on_city_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct city *target_city)
Definition actions.c:4690
action_is_in_use
bool action_is_in_use(struct action *paction)
Definition actions.c:7330
action_prob_unit_vs_tgt
struct act_prob action_prob_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:6402
enabler_tile_tgt_local_diplrel_implies_claimed
static struct req_vec_problem * enabler_tile_tgt_local_diplrel_implies_claimed(const struct action_enabler *enabler)
Definition actions.c:2693
action_ever_possible
bool action_ever_possible(action_id action)
Definition actions.c:9309
action_result_legal_target_kind
bool action_result_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actions.c:8613
action_enabler_vector_by_number_name
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:3015
are_action_probabilitys_equal
bool are_action_probabilitys_equal(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6758
action_prob_self_full
static struct act_prob action_prob_self_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id)
Definition actions.c:6327
action_post_success_forced_ruleset_var_name
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:9176
action_by_rule_name
struct action * action_by_rule_name(const char *name)
Definition actions.c:1708
action_has_possible_actor_hard_reqs
static bool action_has_possible_actor_hard_reqs(struct action *paction)
Definition actions.c:7305
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
action_id_rule_name
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
action_get_battle_kind
enum action_battle_kind action_get_battle_kind(const struct action *pact)
Definition actions.c:1762
action_get_sub_target_kind
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1751
blocked_find_target_tile
static const struct tile * blocked_find_target_tile(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city, const struct unit *target_unit)
Definition actions.c:3102
action_prob_not_relevant
static bool action_prob_not_relevant(const struct act_prob probability)
Definition actions.c:6728
actions_free
void actions_free(void)
Definition actions.c:1530
is_action_enabled_unit_on_extras_full
static bool is_action_enabled_unit_on_extras_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5015
action_enabler_free
void action_enabler_free(struct action_enabler *enabler)
Definition actions.c:2415
action_prob_vs_tile
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6225
ae_contra_close
static void ae_contra_close(struct ae_contra_or *contra)
Definition actions.c:189
tech_can_be_stolen
static enum fc_tristate tech_can_be_stolen(const struct player *actor_player, const struct player *target_player)
Definition actions.c:5239
actlist_by_result
static struct action_list * actlist_by_result[ACTRES_LAST]
Definition actions.c:146
oblig_hard_reqs_sr
static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT]
Definition actions.c:105
oblig_hard_req_reg_sub_res
static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:336
action_prob_vs_units
struct act_prob action_prob_vs_units(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:6141
action_list_by_activity
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:9362
action_number
int action_number(const struct action *action)
Definition actions.c:1868
action_prob_new_unknown
struct act_prob action_prob_new_unknown(void)
Definition actions.c:6696
action_would_be_blocked_by
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1856
ACTPROB_VAL_NA
#define ACTPROB_VAL_NA
Definition actions.c:92
enabler_first_clarification
static struct req_vec_problem * enabler_first_clarification(const struct action_enabler *enabler)
Definition actions.c:2886
is_action_enabled_unit_on_units_full
static bool is_action_enabled_unit_on_units_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct tile *target_tile)
Definition actions.c:4850
action_speculate_unit_on_self
struct act_prob action_speculate_unit_on_self(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat)
Definition actions.c:6628
is_effect_val_known
static bool is_effect_val_known(enum effect_type effect_type, const struct player *pov_player, const struct req_context *context, const struct player *other_player)
Definition actions.c:5219
action_prob_not_impl
static bool action_prob_not_impl(const struct act_prob probability)
Definition actions.c:6739
is_action_enabled_unit_on_tile
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4996
action_prob_and
struct act_prob action_prob_and(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6845
actions_initialized
static bool actions_initialized
Definition actions.c:99
action_actor_consuming_always_ruleset_var_name
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:8899
action_immune_government
bool action_immune_government(struct government *gov, action_id act)
Definition actions.c:7105
voblig_hard_req_reg_sub_res
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:294
is_target_possible
static bool is_target_possible(const action_id wanted_action, const struct player *actor_player, const struct req_context *target)
Definition actions.c:7128
is_action_enabled_unit_on_units
bool is_action_enabled_unit_on_units(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:4920
ap_dipl_battle_win
static struct act_prob ap_dipl_battle_win(const struct unit *pattacker, const struct unit *pdefender)
Definition actions.c:5275
action_is_blocked_by
struct action * action_is_blocked_by(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:3214
actres_get_activity
enum unit_activity actres_get_activity(enum action_result result)
Definition actions.c:2136
action_prob_new_certain
struct act_prob action_prob_new_certain(void)
Definition actions.c:6666
action_max_range_ruleset_var_name
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:8177
action_prob_vs_city_full
static struct act_prob action_prob_vs_city_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct city *target_city)
Definition actions.c:5783
action_dice_roll_initial_odds
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:6983
action_prob_fall_back
struct act_prob action_prob_fall_back(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6915
obligatory_req_vector_iterate_end
#define obligatory_req_vector_iterate_end
Definition actions.c:76
tgt_city_local_utype
static const struct unit_type * tgt_city_local_utype(const struct city *target_city)
Definition actions.c:3077
req_vec_first_local_diplrel
static struct requirement * req_vec_first_local_diplrel(const struct requirement_vector *vec)
Definition actions.c:2649
action_target_kind_default
enum action_target_kind action_target_kind_default(enum action_result result)
Definition actions.c:8528
action_prob_vs_tile_full
static struct act_prob action_prob_vs_tile_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6159
plr_sees_tile
static bool plr_sees_tile(const struct player *plr, const struct tile *ttile)
Definition actions.c:3042
action_speculate_unit_on_extras
struct act_prob action_speculate_unit_on_extras(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6594
is_action_enabled_unit_on_city
bool is_action_enabled_unit_on_city(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Definition actions.c:4755
action_list_by_result
struct action_list * action_list_by_result(enum action_result result)
Definition actions.c:9352
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:7418
action_speculate_unit_on_units
struct act_prob action_speculate_unit_on_units(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target)
Definition actions.c:6527
action_univs_not_blocking
bool action_univs_not_blocking(const struct action *paction, struct universal *actor_uni, struct universal *target_uni)
Definition actions.c:7377
req_vec_first_contradiction_in_vec
static struct requirement * req_vec_first_contradiction_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition actions.c:2670
actions_are_ready
bool actions_are_ready(void)
Definition actions.c:1583
is_action_enabled_unit_on_unit
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:4832
action_speculate_unit_on_city
struct act_prob action_speculate_unit_on_city(const action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, const bool omniscient_cheat, const struct city *target)
Definition actions.c:6459
action_target_compl_calc
static enum act_tgt_compl action_target_compl_calc(enum action_result result, enum action_target_kind tgt_kind, enum action_sub_target_kind sub_tgt_kind)
Definition actions.c:8806
action_min_range_default
int action_min_range_default(enum action_result result)
Definition actions.c:8095
action_prob_vs_city
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:5870
action_target_kind_ruleset_var_name
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:8398
obligatory_req_vector_iterate
#define obligatory_req_vector_iterate(obreq_vec, pobreq)
Definition actions.c:74
action_prob_vs_unit_full
static struct act_prob action_prob_vs_unit_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5886
action_maybe_possible_actor_unit
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:7169
is_enabler_active
static bool is_enabler_active(const struct action_enabler *enabler, const struct req_context *actor, const struct req_context *target)
Definition actions.c:4632
action_enablers_by_action
static struct action_enabler_list * action_enablers_by_action[MAX_NUM_ACTIONS]
Definition actions.c:101
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2442
action_prob_vs_units_full
static struct act_prob action_prob_vs_units_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct tile *target_tile)
Definition actions.c:5970
hard_code_oblig_hard_reqs
static void hard_code_oblig_hard_reqs(void)
Definition actions.c:354
action_ui_name_default
const char * action_ui_name_default(int act)
Definition actions.c:7664
ACTPROB_VAL_1_PCT
#define ACTPROB_VAL_1_PCT
Definition actions.c:90
action_enabler_utype_possible_actor
bool action_enabler_utype_possible_actor(const struct action_enabler *ae, const struct unit_type *act_utype)
Definition actions.c:7247
act_prob_unseen_target
static struct act_prob act_prob_unseen_target(const struct civ_map *nmap, action_id act_id, const struct unit *actor_unit)
Definition actions.c:5378
action_enabler_new
struct action_enabler * action_enabler_new(void)
Definition actions.c:2396
action_requires_details
bool action_requires_details(const struct action *paction)
Definition actions.c:1805
action_prob_new_not_relevant
struct act_prob action_prob_new_not_relevant(void)
Definition actions.c:6676
action_target_kind_help
const char * action_target_kind_help(enum action_target_kind kind)
Definition actions.c:9342
enabler_first_self_contradiction
static struct req_vec_problem * enabler_first_self_contradiction(const struct action_enabler *enabler)
Definition actions.c:2766
action_get_role
int action_get_role(const struct action *paction)
Definition actions.c:2123
action_prob_vs_extras
struct act_prob action_prob_vs_extras(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6309
unit_action_new
static struct action * unit_action_new(action_id id, enum action_result result, bool rare_pop_up, bool unitwaittime_controlled, enum moves_actor_kind moves_actor, const int min_distance, const int max_distance, bool actor_consuming_always)
Definition actions.c:1672
action_speculate_unit_on_unit
struct act_prob action_speculate_unit_on_unit(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct unit *target)
Definition actions.c:6494
action_auto_perf_by_number
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:7369
action_prob_new_impossible
struct act_prob action_prob_new_impossible(void)
Definition actions.c:6656
action_enabler_possible_actor
bool action_enabler_possible_actor(const struct action_enabler *ae)
Definition actions.c:7274
blocked_find_target_city
static const struct city * blocked_find_target_city(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:3160
_actions
struct action ** _actions
Definition actions.c:97
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
action_enabler_remove
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:2459
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
action_sub_target_kind_default
static enum action_sub_target_kind action_sub_target_kind_default(enum action_result result)
Definition actions.c:8716
action_prob_is_signal
static bool action_prob_is_signal(const struct act_prob probability)
Definition actions.c:6750
action_enabler_copy
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2427
plr_knows_tile
static bool plr_knows_tile(const struct player *plr, const struct tile *ttile)
Definition actions.c:3033
action_creates_extra
bool action_creates_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2224
action_prob_to_text
static const char * action_prob_to_text(const struct act_prob prob)
Definition actions.c:1931
action_prob_cmp_pessimist
int action_prob_cmp_pessimist(const struct act_prob ap1, const struct act_prob ap2)
Definition actions.c:6767
is_action_enabled_unit_on_self
bool is_action_enabled_unit_on_self(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit)
Definition actions.c:5145
action_id_is_rare_pop_up
bool action_id_is_rare_pop_up(action_id act_id)
Definition actions.c:1820
actions_init
void actions_init(void)
Definition actions.c:1460
action_speculate_unit_on_tile
struct act_prob action_speculate_unit_on_tile(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6560
action_new
static struct action * action_new(action_id id, enum action_result result, const int min_distance, const int max_distance, bool actor_consuming_always)
Definition actions.c:1607
hard_code_oblig_hard_reqs_ruleset
static void hard_code_oblig_hard_reqs_ruleset(void)
Definition actions.c:877
ae_suggest_repair_if_no_oblig
static struct req_vec_problem * ae_suggest_repair_if_no_oblig(const struct action_enabler *enabler, const struct obligatory_req_vector *oblig)
Definition actions.c:2494
action_prob_vs_unit
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5953
tgt_city_local_building
static const struct impr_type * tgt_city_local_building(const struct city *target_city)
Definition actions.c:3054
ui_name_str
static struct astring ui_name_str
Definition actions.c:107
is_action_enabled_unit_on_extras
bool is_action_enabled_unit_on_extras(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5073
is_action_enabled_unit_on_unit_full
static bool is_action_enabled_unit_on_unit_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct unit *target_unit)
Definition actions.c:4773
action_prob_to_0_to_1_pessimist
double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
Definition actions.c:6818
oblig_hard_req_register
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition actions.c:267
gen_action_name_update_cb
const char * gen_action_name_update_cb(const char *old_name)
Definition actions.c:9317
actlist_by_activity
static struct action_list * actlist_by_activity[ACTIVITY_LAST]
Definition actions.c:147
ap_diplomat_battle
static struct act_prob ap_diplomat_battle(const struct unit *pattacker, const struct unit *pvictim, const struct tile *tgt_tile) fc__attribute((nonnull(3)))
Definition actions.c:5352
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
action_distance_accepted
bool action_distance_accepted(const struct action *action, const int distance)
Definition actions.c:1844
action_prob_vs_extras_full
static struct act_prob action_prob_vs_extras_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6243
action_ui_name_ruleset_var_name
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:7438
action_get_ui_name_mnemonic
const char * action_get_ui_name_mnemonic(action_id act_id, const char *mnemonic)
Definition actions.c:1918
action_max_range_default
int action_max_range_default(enum action_result result)
Definition actions.c:8312
ACTPROB_VAL_MIN
#define ACTPROB_VAL_MIN
Definition actions.c:86
actions.h
ACTION_DISTANCE_MAX
#define ACTION_DISTANCE_MAX
Definition actions.h:354
ACTPROB_CERTAIN
#define ACTPROB_CERTAIN
Definition actions.h:928
ACTPROB_NA
#define ACTPROB_NA
Definition actions.h:929
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
action_enabler_list_re_iterate_end
#define action_enabler_list_re_iterate_end
Definition actions.h:463
ACTION_DISTANCE_LAST_NON_SIGNAL
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:350
action_enabler_list_re_iterate
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:459
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:448
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:457
ACTION_DISTANCE_UNLIMITED
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:352
action_iterate_end
#define action_iterate_end
Definition actions.h:472
MAX_NUM_ACTIONS
#define MAX_NUM_ACTIONS
Definition actions.h:296
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
ACTPROB_NOT_KNOWN
#define ACTPROB_NOT_KNOWN
Definition actions.h:931
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
action_id_distance_accepted
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:696
ACTPROB_IMPOSSIBLE
#define ACTPROB_IMPOSSIBLE
Definition actions.h:927
ACTPROB_NOT_IMPLEMENTED
#define ACTPROB_NOT_IMPLEMENTED
Definition actions.h:930
action_iterate
#define action_iterate(_act_)
Definition actions.h:467
ACTION_ANY
#define ACTION_ANY
Definition actions.h:290
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:655
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:668
ACTION_ODDS_PCT_DICE_ROLL_NA
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:934
ACTION_NONE
#define ACTION_NONE
Definition actions.h:293
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
astr_clear
void astr_clear(struct astring *astr)
Definition astring.c:205
astr_add
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
can_build_base
bool can_build_base(const struct unit *punit, const struct base_type *pbase, const struct tile *ptile)
Definition base.c:53
territory_claiming_base
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_ISSET_ANY
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
city_production_build_shield_cost
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:722
city_unit_slots_available
int city_unit_slots_available(const struct city *pcity)
Definition city.c:1023
citymindist_prevents_city_on_tile
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1434
city_can_grow_to
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:1981
city.h
is_non_allied_city_tile
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:741
is_non_attack_city_tile
static bool is_non_attack_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:729
city_tile
#define city_tile(_pcity_)
Definition city.h:544
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
city_owner
#define city_owner(_pcity_)
Definition city.h:543
is_unit_reachable_at
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:85
unit_attack_units_at_tile_result
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:256
get_diplomatic_defender
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile)
Definition combat.c:882
unit_win_chance
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender)
Definition combat.c:438
can_unit_attack_tile
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:271
get_defender
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile)
Definition combat.c:781
combat.h
ATT_OK
@ ATT_OK
Definition combat.h:35
enablers
char * enablers
Definition comments.c:47
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:55
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:54
actor
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:72
target_tile
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:56
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
target_city
struct unit struct city * target_city
Definition dialogs_g.h:55
target_extra
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:56
id
int int id
Definition editgui_g.h:28
reqs
struct @21::@22 reqs
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
get_effects
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:136
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:375
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
unit_can_displace_hut
bool unit_can_displace_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:713
prev_extra_in_tile
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:765
can_remove_extra
bool can_remove_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:586
extra_type_list_of_terr_claimers
struct extra_type_list * extra_type_list_of_terr_claimers(void)
Definition extras.c:259
is_extra_removed_by
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:327
can_build_extra
bool can_build_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:507
is_native_extra_to_uclass
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:792
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:291
extra_deps_iterate
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:338
extra_type_list_iterate
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:159
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:297
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:196
extra_index
#define extra_index(_e_)
Definition extras.h:177
extra_deps_iterate_end
#define extra_deps_iterate_end
Definition extras.h:346
extra_type_list_iterate_end
#define extra_type_list_iterate_end
Definition extras.h:161
extra_base_get
#define extra_base_get(_e_)
Definition extras.h:184
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:185
fc_funcs
const struct functions * fc_funcs
Definition fc_interface.c:38
fc_interface.h
Tech_type_id
int Tech_type_id
Definition fc_types.h:347
ACT_TIME_INSTANTANEOUS
#define ACT_TIME_INSTANTANEOUS
Definition fc_types.h:319
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:586
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:585
action_id
int action_id
Definition fc_types.h:359
ACTRES_LAST
#define ACTRES_LAST
Definition fc_types.h:300
MAX_NUM_ACTION_AUTO_PERFORMERS
#define MAX_NUM_ACTION_AUTO_PERFORMERS
Definition fc_types.h:54
_
#define _(String)
Definition fcintl.h:67
N_
#define N_(String)
Definition fcintl.h:69
game
struct civ_game game
Definition game.c:57
wld
struct world wld
Definition game.c:58
game.h
is_ruleset_compat_mode
static bool is_ruleset_compat_mode(void)
Definition game.h:340
RS_DEFAULT_EXPLODE_NUCLEAR_MAX_RANGE
#define RS_DEFAULT_EXPLODE_NUCLEAR_MAX_RANGE
Definition game.h:864
RS_DEFAULT_ACTION_MIN_RANGE
#define RS_DEFAULT_ACTION_MIN_RANGE
Definition game.h:862
RS_DEFAULT_USER_ACTION_TARGET_KIND
#define RS_DEFAULT_USER_ACTION_TARGET_KIND
Definition game.h:861
RS_DEFAULT_ACTION_MAX_RANGE
#define RS_DEFAULT_ACTION_MAX_RANGE
Definition game.h:863
name
const char * name
Definition inputfile.c:127
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_msg
#define fc_assert_ret_msg(condition, message,...)
Definition log.h:205
fc_assert_action_msg
#define fc_assert_action_msg(condition, action, message,...)
Definition log.h:201
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
fc_assert_action
#define fc_assert_action(condition, action)
Definition log.h:187
log_error
#define log_error(message,...)
Definition log.h:103
FC_STATIC_ASSERT
#define FC_STATIC_ASSERT(cond, tag)
Definition log.h:235
fc_assert_ret_val_msg
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
get_tile_infrastructure_set
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
Definition map.c:101
terrain_surroundings_allow_change
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:740
real_map_distance
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
map.h
MAP_DISTANCE_MAX
#define MAP_DISTANCE_MAX
Definition map.h:612
square_iterate
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:385
square_iterate_end
#define square_iterate_end
Definition map.h:388
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
can_see_techs_of_target
bool can_see_techs_of_target(const struct player *pow_player, const struct player *target_player)
Definition metaknowledge.c:688
mke_eval_reqs
enum fc_tristate mke_eval_reqs(const struct player *pov_player, const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition metaknowledge.c:662
can_unit_exist_at_tile
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:304
is_native_tile
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:316
unit_move_rate
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
unit_could_load_at
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:869
unit_can_move_to_tile
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_transport, bool enter_enemy_city)
Definition movement.c:557
can_unit_type_transport
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:826
can_attack_non_native
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
movement.h
nation_number
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:485
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
can_player_see_unit
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1084
pplayers_at_war
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
player_can_see_city_externals
bool player_can_see_city_externals(const struct player *pow_player, const struct city *target_city)
Definition player.c:1143
pplayers_allied
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
can_player_see_hypotetic_units_at
bool can_player_see_hypotetic_units_at(const struct player *pplayer, const struct tile *ptile)
Definition player.c:984
slots
struct player_slot * slots
Definition player.c:50
can_player_see_city_internals
bool can_player_see_city_internals(const struct player *pplayer, const struct city *pcity)
Definition player.c:1129
player_can_trust_tile_has_no_units
bool player_can_trust_tile_has_no_units(const struct player *pplayer, const struct tile *ptile)
Definition player.c:958
universal_never_there
bool universal_never_there(const struct universal *source)
Definition requirements.c:4685
req_context_empty
const struct req_context * req_context_empty(void)
Definition requirements.c:901
req_to_fstring
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
Definition requirements.c:916
universal_fulfills_requirements
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Definition requirements.c:5971
req_vec_suggest_repair
struct req_vec_problem * req_vec_suggest_repair(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:5079
req_from_values
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Definition requirements.c:1249
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:4361
are_requirements_contradictions
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
Definition requirements.c:1438
req_vec_problem_new
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *descr,...)
Definition requirements.c:4969
does_req_contradicts_reqs
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:1539
req_vec_is_impossible_to_fulfill
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
Definition requirements.c:4769
req_vec_suggest_improvement
struct req_vec_problem * req_vec_suggest_improvement(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:5251
requirement_fulfilled_by_unit_type
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition requirements.h:418
req_vec_num_in_item
signed char req_vec_num_in_item
req_vec_num_in_item a requirement vectors number in an item.
Definition requirements.h:229
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_fulfilled_by_government
#define requirement_fulfilled_by_government(_gov_, _rqs_)
Definition requirements.h:401
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:126
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
research_invention_gettable
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
research.h
can_build_road
bool can_build_road(const struct civ_map *nmap, struct road_type *proad, const struct unit *punit, const struct tile *ptile)
Definition road.c:295
server_setting_by_name
server_setting_id server_setting_by_name(const char *name)
Definition server_settings.c:29
server_setting_value_int_get
int server_setting_value_int_get(server_setting_id id)
Definition server_settings.c:82
server_settings.h
fc_tristate_and
enum fc_tristate fc_tristate_and(enum fc_tristate one, enum fc_tristate two)
Definition shared.c:124
fc_tristate
fc_tristate
Definition shared.h:46
TRI_YES
@ TRI_YES
Definition shared.h:46
TRI_NO
@ TRI_NO
Definition shared.h:46
TRI_MAYBE
@ TRI_MAYBE
Definition shared.h:46
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
specvec.h
size
size_t size
Definition specvec.h:72
act_prob
Definition fc_types.h:1092
act_prob::max
int max
Definition fc_types.h:1094
act_prob::min
int min
Definition fc_types.h:1093
action_auto_perf
Definition actions.h:568
action_auto_perf::cause
enum action_auto_perf_cause cause
Definition actions.h:570
action_auto_perf::alternatives
action_id alternatives[MAX_NUM_ACTIONS]
Definition actions.h:578
action_enabler_contradiction
Definition actions.c:40
action_enabler_contradiction::is_target
bool is_target
Definition actions.c:46
action_enabler_contradiction::req
struct requirement req
Definition actions.c:42
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::unitwaittime_controlled
bool unitwaittime_controlled
Definition actions.h:428
action::id
action_id id
Definition actions.h:380
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:412
action::rare_pop_up
bool rare_pop_up
Definition actions.h:425
action::max_distance
int max_distance
Definition actions.h:395
action::quiet
bool quiet
Definition actions.h:402
action::sub_target_kind
enum action_sub_target_kind sub_target_kind
Definition actions.h:387
action::moves_actor
enum moves_actor_kind moves_actor
Definition actions.h:432
action::is_unit
struct action::@12::@13 is_unit
action::result
enum action_result result
Definition actions.h:382
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:398
action::sub_results
bv_action_sub_results sub_results
Definition actions.h:383
action::actor_kind
enum action_actor_kind actor_kind
Definition actions.h:385
action::target_complexity
enum act_tgt_compl target_complexity
Definition actions.h:390
action::blocked_by
bv_actions blocked_by
Definition actions.h:406
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
ae_contra_or
Definition actions.c:50
ae_contra_or::alternative
struct action_enabler_contradiction * alternative
Definition actions.c:54
ae_contra_or::alternatives
int alternatives
Definition actions.c:51
ae_contra_or::users
int users
Definition actions.c:57
astring
Definition astring.h:36
city
Definition city.h:309
city::id
int id
Definition city.h:315
city::tile
struct tile * tile
Definition city.h:311
city::shield_stock
int shield_stock
Definition city.h:355
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::scenario
struct packet_scenario_info scenario
Definition game.h:87
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:85
extra_type::buildable
bool buildable
Definition extras.h:112
functions::player_tile_city_id_get
int(* player_tile_city_id_get)(const struct tile *ptile, const struct player *pplayer)
Definition fc_interface.h:52
functions::player_tile_vision_get
bool(* player_tile_vision_get)(const struct tile *ptile, const struct player *pplayer, enum vision_layer vision)
Definition fc_interface.h:46
government
Definition government.h:52
impr_type
Definition improvement.h:68
obligatory_req
Definition actions.c:61
obligatory_req::contras
struct ae_contra_or * contras
Definition actions.c:64
obligatory_req::error_msg
const char * error_msg
Definition actions.c:68
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:211
packet_game_info::add_to_size_limit
int add_to_size_limit
Definition packets_gen.h:120
packet_game_info::airlifting_style
enum airlifting_style airlifting_style
Definition packets_gen.h:123
packet_game_info::airlift_from_always_enabled
bool airlift_from_always_enabled
Definition packets_gen.h:124
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:150
packet_game_info::pillage_select
bool pillage_select
Definition packets_gen.h:208
packet_game_info::citymindist
int citymindist
Definition packets_gen.h:147
packet_scenario_info::prevent_new_cities
bool prevent_new_cities
Definition packets_gen.h:1611
player_economic::gold
int gold
Definition player.h:70
player
Definition player.h:249
player::economic
struct player_economic economic
Definition player.h:284
req_context
Definition requirements.h:99
req_context::tile
const struct tile * tile
Definition requirements.h:102
req_context::player
const struct player * player
Definition requirements.h:100
req_context::unittype
const struct unit_type * unittype
Definition requirements.h:106
req_context::unit
const struct unit * unit
Definition requirements.h:105
req_context::city
const struct city * city
Definition requirements.h:101
req_vec_change::vector_number
req_vec_num_in_item vector_number
Definition requirements.h:284
req_vec_change::operation
enum req_vec_change_operation operation
Definition requirements.h:281
req_vec_change::req
struct requirement req
Definition requirements.h:282
req_vec_problem
Definition requirements.h:287
req_vec_problem::suggested_solutions
struct req_vec_change * suggested_solutions
Definition requirements.h:294
requirement
Definition requirements.h:80
requirement::quiet
bool quiet
Definition requirements.h:85
requirement::survives
bool survives
Definition requirements.h:83
requirement::present
bool present
Definition requirements.h:84
requirement::range
enum req_range range
Definition requirements.h:82
requirement::source
struct universal source
Definition requirements.h:81
research
Definition research.h:39
terrain
Definition terrain.h:176
terrain::cultivate_result
struct terrain * cultivate_result
Definition terrain.h:203
terrain::plant_result
struct terrain * plant_result
Definition terrain.h:206
terrain::clean_fallout_time
int clean_fallout_time
Definition terrain.h:220
terrain::pillage_time
int pillage_time
Definition terrain.h:221
terrain::clean_pollution_time
int clean_pollution_time
Definition terrain.h:219
terrain::transform_result
struct terrain * transform_result
Definition terrain.h:217
tile
Definition tile.h:49
tile::units
struct unit_list * units
Definition tile.h:57
unit_class
Definition unittype.h:136
unit_class::cache
struct unit_class::@85 cache
unit_class::native_bases
struct extra_type_list * native_bases
Definition unittype.h:157
unit_type
Definition unittype.h:481
unit_type::transport_capacity
int transport_capacity
Definition unittype.h:504
unit_type::pop_cost
int pop_cost
Definition unittype.h:493
unit_type::paratroopers_range
int paratroopers_range
Definition unittype.h:522
unit_type::convert_time
int convert_time
Definition unittype.h:512
unit_type::veteran
struct veteran_system * veteran
Definition unittype.h:525
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:510
unit_type::bombard_rate
int bombard_rate
Definition unittype.h:528
unit_type::city_slots
int city_slots
Definition unittype.h:533
unit_type::hp
int hp
Definition unittype.h:505
unit_type::converted_to
const struct unit_type * converted_to
Definition unittype.h:511
unit_type::attack_strength
int attack_strength
Definition unittype.h:495
unit
Definition unit.h:138
unit::moves_left
int moves_left
Definition unit.h:150
unit::hp
int hp
Definition unit.h:151
unit::tile
struct tile * tile
Definition unit.h:140
unit::activity_target
struct extra_type * activity_target
Definition unit.h:164
unit::paradropped
bool paradropped
Definition unit.h:174
unit::utype
const struct unit_type * utype
Definition unit.h:139
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
universal::value
universals_u value
Definition fc_types.h:757
veteran_level
Definition unittype.h:467
veteran_level::power_fact
int power_fact
Definition unittype.h:469
world::map
struct civ_map map
Definition world_object.h:38
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc__attribute
#define fc__attribute(x)
Definition support.h:89
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:109
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
advance_iterate
#define advance_iterate(_start, _p)
Definition tech.h:264
A_FIRST
#define A_FIRST
Definition tech.h:44
advance_iterate_end
#define advance_iterate_end
Definition tech.h:270
get_preferred_pillage
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:538
T_NONE
#define T_NONE
Definition terrain.h:56
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
tile_has_claimable_base
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:209
tile_is_seen
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:401
tile_activity_time
int tile_activity_time(enum unit_activity activity, const struct tile *ptile, const struct extra_type *tgt)
Definition tile.c:412
tile_get_known
enum known_type tile_get_known(const struct tile *ptile, const struct player *pplayer)
Definition tile.c:386
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile.h
TILE_UNKNOWN
@ TILE_UNKNOWN
Definition tile.h:35
TILE_KNOWN_SEEN
@ TILE_KNOWN_SEEN
Definition tile.h:37
ACTIVITY_FACTOR
#define ACTIVITY_FACTOR
Definition tile.h:164
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:109
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
tile_owner
#define tile_owner(_tile)
Definition tile.h:95
can_cities_trade
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:214
can_establish_trade_route
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:275
universals_u::citytile
enum citytile_type citytile
Definition fc_types.h:613
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2427
unit_contained_in
bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2506
test_unit_can_airlift_to
enum unit_airlift_result test_unit_can_airlift_to(const struct civ_map *nmap, const struct player *restriction, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:83
could_unit_load
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:719
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:331
get_unit_tile_pillage_set
bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
Definition unit.c:1158
get_transporter_capacity
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:302
unit_upgrade_test
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1974
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2411
can_unit_unload
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:771
unit_can_convert
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2021
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:388
unit_owner
#define unit_owner(_pu)
Definition unit.h:387
UU_OK
@ UU_OK
Definition unit.h:61
unit_home
#define unit_home(_pu_)
Definition unit.h:386
is_non_allied_unit_tile
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:423
AR_SRC_NO_FLIGHTS
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
AR_OK_SRC_UNKNOWN
@ AR_OK_SRC_UNKNOWN
Definition unit.h:75
AR_OK_DST_UNKNOWN
@ AR_OK_DST_UNKNOWN
Definition unit.h:76
AR_NO_MOVES
@ AR_NO_MOVES
Definition unit.h:78
AR_BAD_DST_CITY
@ AR_BAD_DST_CITY
Definition unit.h:83
AR_NOT_IN_CITY
@ AR_NOT_IN_CITY
Definition unit.h:81
AR_OCCUPIED
@ AR_OCCUPIED
Definition unit.h:80
AR_OK
@ AR_OK
Definition unit.h:74
AR_DST_NO_FLIGHTS
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
AR_WRONG_UNITTYPE
@ AR_WRONG_UNITTYPE
Definition unit.h:79
AR_BAD_SRC_CITY
@ AR_BAD_SRC_CITY
Definition unit.h:82
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
utype_may_act_move_frags
bool utype_may_act_move_frags(const struct unit_type *punit_type, const action_id act_id, const int move_fragments)
Definition unittype.c:1110
utype_player_already_has_this_unique
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
utype_veteran_level
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2631
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
unit_pop_value
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1595
utype_can_do_act_if_tgt_citytile
bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1048
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
utype_class
#define utype_class(_t_)
Definition unittype.h:736
L_LAST
#define L_LAST
Definition unittype.h:420
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:838
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:845
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:509