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. */
41 /* A requirement that contradicts the obligatory hard requirement. */
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. */
47};
48
49/* One or more alternative obligatory hard requirement contradictions. */
52 /* The obligatory hard requirement is fulfilled if a contradiction exists
53 * that doesn't contradict the action enabler. */
55
56 /* How many obligatory reqs use this */
57 int users;
58};
59
60/* An obligatory hard action requirement */
62 /* The requirement is fulfilled if the action enabler doesn't contradict
63 * one of the contradictions listed here. */
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
100
101static struct action_enabler_list *action_enablers_by_action[MAX_NUM_ACTIONS];
102
103/* Hard requirements relates to action result. */
104static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE];
105static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT];
106
108
109static struct action *
111 enum action_result result,
112 bool rare_pop_up,
114 enum moves_actor_kind moves_actor,
115 const int min_distance,
116 const int max_distance,
118
119static enum action_sub_target_kind
120action_sub_target_kind_default(enum action_result result);
121static enum act_tgt_compl
122action_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
131action_prob_is_signal(const struct act_prob probability);
132static inline bool
133action_prob_not_relevant(const struct act_prob probability);
134static inline bool
135action_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. */
144 action_range_can_not_cover_the_whole_map);
145
146static struct action_list *actlist_by_result[ACTRES_LAST];
147static struct action_list *actlist_by_activity[ACTIVITY_LAST];
148
149/**********************************************************************/
161{
162 struct ae_contra_or *out;
163 int i;
164 va_list args;
165
167 out = fc_malloc(sizeof(*out));
168 out->users = 0;
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/**********************************************************************/
189static 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/**********************************************************************/
208static 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/**********************************************************************/
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/**********************************************************************/
267static 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/**********************************************************************/
294static 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/**********************************************************************/
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/**********************************************************************/
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. */
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. */
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. */
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. */
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);
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);
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);
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 */
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);
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/**********************************************************************/
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);
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 }
909}
910
911/**********************************************************************/
914static 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. */
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. */
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. */
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. */
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. */
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. */
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. */
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/**********************************************************************/
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 */
1473
1474 /* Initialize the action enabler list */
1475 action_iterate(act) {
1476 action_enablers_by_action[act] = action_enabler_list_new();
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. */
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. */
1508 }
1509 }
1510
1511 /* The actions them self are now initialized. */
1513}
1514
1515/**********************************************************************/
1521{
1522 /* Some obligatory hard requirements needs access to the rest of the
1523 * ruleset. */
1525}
1526
1527/**********************************************************************/
1531{
1532 int i;
1533
1534 /* Don't consider the actions to be initialized any longer. */
1536
1537 action_iterate(act) {
1539 action_enabler_free(enabler);
1541
1542 action_enabler_list_destroy(action_enablers_by_action[act]);
1543
1544 FC_FREE(actions[act]);
1546
1547 /* Free the obligatory hard action requirements. */
1548 for (i = 0; i < ACTRES_NONE; i++) {
1550 ae_contra_close(oreq->contras);
1552 obligatory_req_vector_free(&oblig_hard_reqs_r[i]);
1553 }
1554 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
1556 ae_contra_close(oreq->contras);
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
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/**********************************************************************/
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 }
1599
1600 /* The actions should be ready for use. */
1601 return TRUE;
1602}
1603
1604/**********************************************************************/
1607static struct action *action_new(action_id id,
1608 enum action_result result,
1609 const int min_distance,
1610 const int max_distance,
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 */
1633
1634 action->actor_kind = AAK_UNIT;
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.",
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
1656
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;
1664
1665 return action;
1666}
1667
1668/**********************************************************************/
1671static struct action *
1673 enum action_result result,
1674 bool rare_pop_up,
1676 enum moves_actor_kind moves_actor,
1677 const int min_distance,
1678 const int max_distance,
1680{
1681 struct action *act = action_new(id, result,
1684
1686
1688
1690
1691 return act;
1692}
1693
1694/**********************************************************************/
1697bool 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/**********************************************************************/
1708struct 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/**********************************************************************/
1730enum 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/**********************************************************************/
1740enum 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/**********************************************************************/
1751enum 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/**********************************************************************/
1762enum 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/**********************************************************************/
1792bool 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/**********************************************************************/
1805bool 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/**********************************************************************/
1821{
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/**********************************************************************/
1834 const int distance)
1835{
1836 return (distance <= action->max_distance
1838}
1839
1840/**********************************************************************/
1845 const int distance)
1846{
1848
1849 return (distance >= action->min_distance
1850 && action_distance_inside_max(action, distance));
1851}
1852
1853/**********************************************************************/
1856bool 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/**********************************************************************/
1868int action_number(const struct action *action)
1869{
1870 return action->id;
1871}
1872
1873/**********************************************************************/
1876const 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/**********************************************************************/
1890const char *action_name_translation(const struct action *action)
1891{
1892 /* Use action_id_name_translation() to format the UI name. */
1894}
1895
1896/**********************************************************************/
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/**********************************************************************/
1911{
1912 return action_prepare_ui_name(act_id, "", ACTPROB_NA, NULL);
1913}
1914
1915/**********************************************************************/
1919 const char *mnemonic)
1920{
1921 return action_prepare_ui_name(act_id, mnemonic, ACTPROB_NA, NULL);
1922}
1923
1924/**********************************************************************/
1931static 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)) {
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/**********************************************************************/
1972const 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 */
1986
1987 /* but the action should be valid */
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 string 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 string 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 string 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/**********************************************************************/
2083const 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)) {
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/**********************************************************************/
2123int 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/**********************************************************************/
2136enum 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/**********************************************************************/
2173int 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. */
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:
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
2219}
2220
2221/**********************************************************************/
2224bool 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/**********************************************************************/
2312bool 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/**********************************************************************/
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/**********************************************************************/
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 *
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/**********************************************************************/
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. */
2448
2449 action_enabler_list_append(
2451 enabler);
2452}
2453
2454/**********************************************************************/
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. */
2465
2466 return action_enabler_list_remove(
2468 enabler);
2469}
2470
2471/**********************************************************************/
2474struct action_enabler_list *
2476{
2477 /* Sanity check: a non existing action doesn't have enablers. */
2479
2481}
2482
2483/**********************************************************************/
2493static struct req_vec_problem *
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
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;
2563 = action_enabler_vector_number(enabler, ae_vec);
2564
2565 /* Change the requirement from what should conflict to what is
2566 * wanted. */
2568 = !obreq->contras->alternative[i].req.present;
2570 = obreq->contras->alternative[i].req.source;
2572 = obreq->contras->alternative[i].req.range;
2574 = obreq->contras->alternative[i].req.survives;
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;
2583
2584 /* No obligatory req problems found. */
2585 return NULL;
2586}
2587
2588/**********************************************************************/
2597struct req_vec_problem *
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 }
2657
2658 return NULL;
2659}
2660
2661/**********************************************************************/
2669static struct requirement *
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 }
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 *
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;
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 *
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;
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;
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 *
2839{
2840 struct req_vec_problem *out;
2841
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,
2850 enabler);
2851 if (out != NULL) {
2852 return out;
2853 }
2854
2855 out = req_vec_suggest_repair(&enabler->target_reqs,
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. */
2870 if (out != NULL) {
2871 return out;
2872 }
2873
2874 /* No problems found. */
2875 return NULL;
2876}
2877
2878/**********************************************************************/
2885static struct req_vec_problem *
2887{
2888 struct req_vec_problem *out;
2889
2890 out = NULL;
2891
2892 return out;
2893}
2894
2895/**********************************************************************/
2903struct req_vec_problem *
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. */
2920 enabler);
2921 if (out) {
2922 return out;
2923 }
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)
2938 &(enabler->actor_reqs))) {
2939 has_user = TRUE;
2940 break;
2941 }
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/**********************************************************************/
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 *
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/*********************************************************************/
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/**********************************************************************/
3033static 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/**********************************************************************/
3042static 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 *
3055{
3056 /* Only used with city targets */
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 *
3078{
3079 /* Only used with city targets */
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 *
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:
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
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:
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",
3147 return NULL;
3148}
3149
3150/**********************************************************************/
3159static const struct city *
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:
3182 case ATK_UNITS:
3184 if (target_unit) {
3187 }
3188
3190 case ATK_TILE:
3191 case ATK_EXTRAS:
3193 return tile_city(target_tile);
3194 case ATK_SELF:
3198 case ATK_COUNT:
3199 /* Handled below. */
3200 break;
3201 }
3202
3203 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
3205 return NULL;
3206}
3207
3208/**********************************************************************/
3214struct action *action_is_blocked_by(const struct civ_map *nmap,
3215 const struct action *act,
3216 const struct unit *actor_unit,
3217 const struct tile *target_tile_arg,
3218 const struct city *target_city_arg,
3219 const struct unit *target_unit)
3220{
3221 const struct tile *target_tile
3222 = blocked_find_target_tile(act, actor_unit, target_tile_arg,
3223 target_city_arg, target_unit);
3224 const struct city *target_city
3226 target_city_arg, target_unit);
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,
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,
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,
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 }
3301
3302 /* Not blocked. */
3303 return NULL;
3304}
3305
3306/**********************************************************************/
3326static bool
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 }
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;
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;
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
3521 const struct unit_type *actor_unittype)
3522{
3524 actor_unittype, FALSE);
3525}
3526
3527/**********************************************************************/
3539static enum fc_tristate
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) {
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)
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) {
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,
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?) */
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(nmap, 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
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
3909 return TRI_NO;
3910 }
3911
3912 break;
3913
3914 case ACTRES_FOUND_CITY:
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 }
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 }
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 }
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. */
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 }
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 }
4279 }
4280 if (required) {
4281 break;
4282 }
4284
4285 if (!required) {
4286 BV_SET(pspossible, idx);
4287 }
4288 }
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 }
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 }
4472 }
4473 break;
4474
4475 case ACTRES_SPY_ATTACK:
4476 {
4477 bool found;
4478
4479 if (!omniscient
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 }
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 }
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 }
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 }
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/**********************************************************************/
4632static 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/**********************************************************************/
4651static 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
4674 enabler) {
4675 if (is_enabler_active(enabler, actor, target)) {
4676 return TRUE;
4677 }
4679
4680 return FALSE;
4681}
4682
4683/**********************************************************************/
4689static bool
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/**********************************************************************/
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,
4763 target_city);
4764}
4765
4766/**********************************************************************/
4772static bool
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),
4819 .unit = target_unit,
4820 .unittype = unit_type_get(target_unit),
4821 },
4822 NULL,
4823 actor_home);
4824}
4825
4826/**********************************************************************/
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,
4840 target_unit);
4841}
4842
4843/**********************************************************************/
4849static bool
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) {
4889 .city = tile_city(actor_tile),
4890 .tile = actor_tile,
4891 .unit = actor_unit,
4892 .unittype = unit_type_get(actor_unit),
4893 };
4894
4896 if (!is_action_enabled(nmap, wanted_action, actor_ctxt,
4897 &(const struct req_context) {
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 }
4909
4910 /* Not impossible for any of the units at the tile. */
4911 return TRUE;
4912}
4913
4914/**********************************************************************/
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,
4928 target_tile);
4929}
4930
4931/**********************************************************************/
4937static bool
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 },
4987 actor_home);
4988}
4989
4990/**********************************************************************/
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,
5006}
5007
5008/**********************************************************************/
5014static bool
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 },
5064 actor_home);
5065}
5066
5067/**********************************************************************/
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,
5083}
5084
5085/**********************************************************************/
5092static bool
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/**********************************************************************/
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,
5152}
5153
5154/**********************************************************************/
5172static enum fc_tristate
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;
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 }
5206
5207 return result;
5208}
5209
5210/**********************************************************************/
5219static 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 }
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,
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 }
5259 } else {
5260 return TRI_MAYBE;
5261 }
5262 }
5263
5264 return TRI_NO;
5265}
5266
5267/**********************************************************************/
5275static 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/**********************************************************************/
5352static 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
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/**********************************************************************/
5378static 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
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
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 enum fc_tristate known;
5488 struct act_prob chance;
5489 const struct action *paction = action_by_number(wanted_action);
5490
5491 if (actor == NULL) {
5493 }
5494 if (target == NULL) {
5495 target = req_context_empty();
5496 }
5497
5498 known = is_action_possible(nmap, wanted_action, actor, target,
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. */
5755 || chance.max <= ACTPROB_VAL_MAX),
5756 chance.max = ACTPROB_VAL_MAX);
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
5776}
5777
5778/**********************************************************************/
5782static struct act_prob
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
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
5809 "Action %s is against %s not %s",
5810 action_id_rule_name(act_id),
5811 action_target_kind_name(
5813 action_target_kind_name(ATK_CITY));
5814
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,
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(nmap, act, actor_unit,
5835 /* Don't offer to perform an action known to be blocked. */
5836 return ACTPROB_IMPOSSIBLE;
5837 }
5838
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/**********************************************************************/
5870struct 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{
5878 act_id, target_city);
5879}
5880
5881/**********************************************************************/
5885static struct act_prob
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
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
5908 "Action %s is against %s not %s",
5909 action_id_rule_name(act_id),
5910 action_target_kind_name(
5912 action_target_kind_name(ATK_UNIT));
5913
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,
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),
5943 .unit = target_unit,
5944 .unittype = unit_type_get(target_unit),
5945 },
5946 NULL);
5947}
5948
5949/**********************************************************************/
5953struct 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{
5961 act_id,
5962 target_unit);
5963}
5964
5965/**********************************************************************/
5969static struct act_prob
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
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
5996 "Action %s is against %s not %s",
5997 action_id_rule_name(act_id),
5998 action_target_kind_name(
6000 action_target_kind_name(ATK_UNITS));
6001
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. */
6021 && tile_city(target_tile) != NULL
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. */
6033 if (action_is_blocked_by(nmap, act, actor_unit,
6035 target_unit)) {
6036 /* Don't offer to perform an action known to be blocked. */
6037 return ACTPROB_IMPOSSIBLE;
6038 }
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
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
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))
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. */
6081
6082 actor_ctxt = &(const struct req_context) {
6084 .city = tile_city(actor_tile),
6085 .tile = actor_tile,
6086 .unit = actor_unit,
6087 .unittype = unit_type_get(actor_unit),
6088 };
6089
6091 struct act_prob prob_unit;
6092
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),
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 {
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 }
6132
6133 /* Not impossible for any of the units at the tile. */
6134 return prob_all;
6135}
6136
6137/**********************************************************************/
6141struct act_prob action_prob_vs_units(const struct civ_map *nmap,
6142 const struct unit *actor_unit,
6143 const action_id act_id,
6144 const struct tile *target_tile)
6145{
6149 act_id,
6150 target_tile);
6151}
6152
6153/**********************************************************************/
6157static struct act_prob
6159 const struct unit *actor_unit,
6160 const struct city *actor_home,
6161 const struct tile *actor_tile,
6162 const action_id act_id,
6163 const struct tile *target_tile,
6164 const struct extra_type *target_extra)
6165{
6166 if (actor_unit == NULL || target_tile == NULL) {
6167 /* Can't do an action when actor or target are missing. */
6168 return ACTPROB_IMPOSSIBLE;
6169 }
6170
6173 "Action %s is performed by %s not %s",
6174 action_id_rule_name(act_id),
6175 action_actor_kind_name(
6176 action_id_get_actor_kind(act_id)),
6177 action_actor_kind_name(AAK_UNIT));
6178
6181 "Action %s is against %s not %s",
6182 action_id_rule_name(act_id),
6183 action_target_kind_name(
6185 action_target_kind_name(ATK_TILE));
6186
6188
6189 if (!unit_can_do_action(actor_unit, act_id)) {
6190 /* No point in continuing. */
6191 return ACTPROB_IMPOSSIBLE;
6192 }
6193
6194 /* Doesn't leak information about tile position since an unknown tile's
6195 * position is known. */
6196 if (!action_id_distance_accepted(act_id,
6197 real_map_distance(actor_tile,
6198 target_tile))) {
6199 /* No point in continuing. */
6200 return ACTPROB_IMPOSSIBLE;
6201 }
6202
6203 return action_prob(nmap, act_id,
6204 &(const struct req_context) {
6205 .player = unit_owner(actor_unit),
6206 .city = tile_city(actor_tile),
6207 .tile = actor_tile,
6208 .unit = actor_unit,
6209 .unittype = unit_type_get(actor_unit),
6210 },
6211 actor_home,
6212 &(const struct req_context) {
6213 .player = tile_owner(target_tile),
6214 .city = tile_city(target_tile),
6215 .tile = target_tile,
6216 },
6217 target_extra);
6218}
6219
6220/**********************************************************************/
6224struct act_prob action_prob_vs_tile(const struct civ_map *nmap,
6225 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{
6233 act_id, target_tile, target_extra);
6234}
6235
6236/**********************************************************************/
6240static struct act_prob
6242 const struct unit *actor_unit,
6243 const struct city *actor_home,
6244 const struct tile *actor_tile,
6245 const action_id act_id,
6246 const struct tile *target_tile,
6247 const struct extra_type *target_extra)
6248{
6249 if (actor_unit == NULL || target_tile == NULL) {
6250 /* Can't do an action when actor or target are missing. */
6251 return ACTPROB_IMPOSSIBLE;
6252 }
6253
6256 "Action %s is performed by %s not %s",
6257 action_id_rule_name(act_id),
6258 action_actor_kind_name(
6259 action_id_get_actor_kind(act_id)),
6260 action_actor_kind_name(AAK_UNIT));
6261
6264 "Action %s is against %s not %s",
6265 action_id_rule_name(act_id),
6266 action_target_kind_name(
6268 action_target_kind_name(ATK_EXTRAS));
6269
6271
6272 if (!unit_can_do_action(actor_unit, act_id)) {
6273 /* No point in continuing. */
6274 return ACTPROB_IMPOSSIBLE;
6275 }
6276
6277 /* Doesn't leak information about tile position since an unknown tile's
6278 * position is known. */
6279 if (!action_id_distance_accepted(act_id,
6280 real_map_distance(actor_tile,
6281 target_tile))) {
6282 /* No point in continuing. */
6283 return ACTPROB_IMPOSSIBLE;
6284 }
6285
6286 return action_prob(nmap, act_id,
6287 &(const struct req_context) {
6288 .player = unit_owner(actor_unit),
6289 .city = tile_city(actor_tile),
6290 .tile = actor_tile,
6291 .unit = actor_unit,
6292 .unittype = unit_type_get(actor_unit),
6293 },
6294 actor_home,
6295 &(const struct req_context) {
6296 .player = target_tile->extras_owner,
6297 .city = tile_city(target_tile),
6298 .tile = target_tile,
6299 },
6300 target_extra);
6301}
6302
6303/**********************************************************************/
6307struct act_prob action_prob_vs_extras(const struct civ_map *nmap,
6308 const struct unit *actor_unit,
6309 const action_id act_id,
6310 const struct tile *target_tile,
6311 const struct extra_type *target_extra)
6312{
6316 act_id, target_tile, target_extra);
6317}
6318
6319/**********************************************************************/
6323static struct act_prob
6325 const struct unit *actor_unit,
6326 const struct city *actor_home,
6327 const struct tile *actor_tile,
6328 const action_id act_id)
6329{
6330 if (actor_unit == NULL) {
6331 /* Can't do the action when the actor is missing. */
6332 return ACTPROB_IMPOSSIBLE;
6333 }
6334
6335 /* No point in checking distance to target. It is always 0. */
6336
6339 "Action %s is performed by %s not %s",
6340 action_id_rule_name(act_id),
6341 action_actor_kind_name(
6342 action_id_get_actor_kind(act_id)),
6343 action_actor_kind_name(AAK_UNIT));
6344
6347 "Action %s is against %s not %s",
6348 action_id_rule_name(act_id),
6349 action_target_kind_name(
6351 action_target_kind_name(ATK_SELF));
6352
6354
6355 if (!unit_can_do_action(actor_unit, act_id)) {
6356 /* No point in continuing. */
6357 return ACTPROB_IMPOSSIBLE;
6358 }
6359
6360 return action_prob(nmap, act_id,
6361 &(const struct req_context) {
6362 .player = unit_owner(actor_unit),
6363 .city = tile_city(actor_tile),
6364 .tile = actor_tile,
6365 .unit = actor_unit,
6366 .unittype = unit_type_get(actor_unit),
6367 },
6368 actor_home,
6369 NULL,
6370 NULL);
6371}
6372
6373/**********************************************************************/
6377struct act_prob action_prob_self(const struct civ_map *nmap,
6378 const struct unit *actor_unit,
6379 const action_id act_id)
6380{
6381 return action_prob_self_full(nmap, actor_unit,
6384 act_id);
6385}
6386
6387/**********************************************************************/
6399struct act_prob action_prob_unit_vs_tgt(const struct civ_map *nmap,
6400 const struct action *paction,
6401 const struct unit *act_unit,
6402 const struct city *tgt_city,
6403 const struct unit *tgt_unit,
6404 const struct tile *tgt_tile,
6405 const struct extra_type *extra_tgt)
6406{
6407 /* Assume impossible until told otherwise. */
6408 struct act_prob prob = ACTPROB_IMPOSSIBLE;
6409
6412
6413 switch (action_get_target_kind(paction)) {
6414 case ATK_UNITS:
6415 if (tgt_tile) {
6416 prob = action_prob_vs_units(nmap, act_unit, paction->id, tgt_tile);
6417 }
6418 break;
6419 case ATK_TILE:
6420 if (tgt_tile) {
6421 prob = action_prob_vs_tile(nmap, act_unit, paction->id, tgt_tile, extra_tgt);
6422 }
6423 break;
6424 case ATK_EXTRAS:
6425 if (tgt_tile) {
6426 prob = action_prob_vs_extras(nmap, act_unit, paction->id,
6427 tgt_tile, extra_tgt);
6428 }
6429 break;
6430 case ATK_CITY:
6431 if (tgt_city) {
6432 prob = action_prob_vs_city(nmap, act_unit, paction->id, tgt_city);
6433 }
6434 break;
6435 case ATK_UNIT:
6436 if (tgt_unit) {
6437 prob = action_prob_vs_unit(nmap, act_unit, paction->id, tgt_unit);
6438 }
6439 break;
6440 case ATK_SELF:
6441 prob = action_prob_self(nmap, act_unit, paction->id);
6442 break;
6443 case ATK_COUNT:
6444 log_error("Invalid action target kind");
6445 break;
6446 }
6447
6448 return prob;
6449}
6450
6451/**********************************************************************/
6457 const action_id act_id,
6458 const struct unit *actor,
6459 const struct city *actor_home,
6460 const struct tile *actor_tile,
6461 const bool omniscient_cheat,
6462 const struct city* target)
6463{
6464 /* FIXME: some unit state requirements still depend on the actor unit's
6465 * current position rather than on actor_tile. Maybe this function should
6466 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6467 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6468
6469 if (omniscient_cheat) {
6470 if (is_action_enabled_unit_on_city_full(nmap, act_id,
6471 actor, actor_home, actor_tile,
6472 target)) {
6473 return ACTPROB_CERTAIN;
6474 } else {
6475 return ACTPROB_IMPOSSIBLE;
6476 }
6477 } else {
6478 /* FIXME: this branch result depends _directly_ on actor's position.
6479 * I.e., like, not adjacent, no action. Other branch ignores radius. */
6480 return action_prob_vs_city_full(nmap, actor, actor_home, actor_tile,
6481 act_id, target);
6482 }
6483}
6484
6485/**********************************************************************/
6490struct act_prob
6492 action_id act_id,
6493 const struct unit *actor,
6494 const struct city *actor_home,
6495 const struct tile *actor_tile,
6496 bool omniscient_cheat,
6497 const struct unit *target)
6498{
6499 /* FIXME: some unit state requirements still depend on the actor unit's
6500 * current position rather than on actor_tile. Maybe this function should
6501 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6502 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6503
6504 if (omniscient_cheat) {
6505 if (is_action_enabled_unit_on_unit_full(nmap, act_id,
6506 actor, actor_home, actor_tile,
6507 target)) {
6508 return ACTPROB_CERTAIN;
6509 } else {
6510 return ACTPROB_IMPOSSIBLE;
6511 }
6512 } else {
6513 return action_prob_vs_unit_full(nmap, actor, actor_home, actor_tile,
6514 act_id, target);
6515 }
6516}
6517
6518/**********************************************************************/
6523struct act_prob
6525 action_id act_id,
6526 const struct unit *actor,
6527 const struct city *actor_home,
6528 const struct tile *actor_tile,
6529 bool omniscient_cheat,
6530 const struct tile *target)
6531{
6532 /* FIXME: some unit state requirements still depend on the actor unit's
6533 * current position rather than on actor_tile. Maybe this function should
6534 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6535 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6536
6537 if (omniscient_cheat) {
6538 if (is_action_enabled_unit_on_units_full(nmap, act_id,
6539 actor, actor_home, actor_tile,
6540 target)) {
6541 return ACTPROB_CERTAIN;
6542 } else {
6543 return ACTPROB_IMPOSSIBLE;
6544 }
6545 } else {
6546 return action_prob_vs_units_full(nmap, actor, actor_home, actor_tile,
6547 act_id, target);
6548 }
6549}
6550
6551/**********************************************************************/
6556struct act_prob
6558 action_id act_id,
6559 const struct unit *actor,
6560 const struct city *actor_home,
6561 const struct tile *actor_tile,
6562 bool omniscient_cheat,
6563 const struct tile *target_tile,
6564 const struct extra_type *target_extra)
6565{
6566 /* FIXME: some unit state requirements still depend on the actor unit's
6567 * current position rather than on actor_tile. Maybe this function should
6568 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6569 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6570
6571 if (omniscient_cheat) {
6572 if (is_action_enabled_unit_on_tile_full(nmap, act_id,
6573 actor, actor_home, actor_tile,
6575 return ACTPROB_CERTAIN;
6576 } else {
6577 return ACTPROB_IMPOSSIBLE;
6578 }
6579 } else {
6580 return action_prob_vs_tile_full(nmap, actor, actor_home, actor_tile,
6581 act_id, target_tile, target_extra);
6582 }
6583}
6584
6585/**********************************************************************/
6590struct act_prob
6592 action_id act_id,
6593 const struct unit *actor,
6594 const struct city *actor_home,
6595 const struct tile *actor_tile,
6596 bool omniscient_cheat,
6597 const struct tile *target_tile,
6598 const struct extra_type *target_extra)
6599{
6600 /* FIXME: some unit state requirements still depend on the actor unit's
6601 * current position rather than on actor_tile. Maybe this function should
6602 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6603 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6604
6605 if (omniscient_cheat) {
6607 actor, actor_home, actor_tile,
6609 return ACTPROB_CERTAIN;
6610 } else {
6611 return ACTPROB_IMPOSSIBLE;
6612 }
6613 } else {
6614 return action_prob_vs_extras_full(nmap, actor, actor_home, actor_tile,
6615 act_id, target_tile, target_extra);
6616 }
6617}
6618
6619/**********************************************************************/
6624struct act_prob
6626 action_id act_id,
6627 const struct unit *actor,
6628 const struct city *actor_home,
6629 const struct tile *actor_tile,
6630 bool omniscient_cheat)
6631{
6632 /* FIXME: some unit state requirements still depend on the actor unit's
6633 * current position rather than on actor_tile. Maybe this function should
6634 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
6635 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
6636 if (omniscient_cheat) {
6637 if (is_action_enabled_unit_on_self_full(nmap, act_id,
6638 actor, actor_home, actor_tile)) {
6639 return ACTPROB_CERTAIN;
6640 } else {
6641 return ACTPROB_IMPOSSIBLE;
6642 }
6643 } else {
6644 return action_prob_self_full(nmap, actor, actor_home, actor_tile,
6645 act_id);
6646 }
6647}
6648
6649/**********************************************************************/
6653{
6654 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MIN };
6655
6656 return out;
6657}
6658
6659/**********************************************************************/
6663{
6664 struct act_prob out = { ACTPROB_VAL_MAX, ACTPROB_VAL_MAX };
6665
6666 return out;
6667}
6668
6669/**********************************************************************/
6673{
6674 struct act_prob out = { ACTPROB_VAL_NA, ACTPROB_VAL_MIN};
6675
6676 return out;
6677}
6678
6679/**********************************************************************/
6683{
6685
6686 return out;
6687}
6688
6689/**********************************************************************/
6693{
6694 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MAX };
6695
6696 return out;
6697}
6698
6699/**********************************************************************/
6703bool action_prob_possible(const struct act_prob probability)
6704{
6705 return (ACTPROB_VAL_MIN < probability.max
6706 || action_prob_not_impl(probability));
6707}
6708
6709/**********************************************************************/
6713bool action_prob_certain(const struct act_prob probability)
6714{
6715 return (ACTPROB_VAL_MAX == probability.min
6716 && ACTPROB_VAL_MAX == probability.max);
6717}
6718
6719/**********************************************************************/
6723static inline bool
6724action_prob_not_relevant(const struct act_prob probability)
6725{
6726 return probability.min == ACTPROB_VAL_NA
6727 && probability.max == ACTPROB_VAL_MIN;
6728}
6729
6730/**********************************************************************/
6734static inline bool
6735action_prob_not_impl(const struct act_prob probability)
6736{
6737 return probability.min == ACTPROB_VAL_NOT_IMPL
6738 && probability.max == ACTPROB_VAL_MIN;
6739}
6740
6741/**********************************************************************/
6745static inline bool
6746action_prob_is_signal(const struct act_prob probability)
6747{
6748 return probability.max < probability.min;
6749}
6750
6751/**********************************************************************/
6755 const struct act_prob *ap2)
6756{
6757 return ap1->min == ap2->min && ap1->max == ap2->max;
6758}
6759
6760/**********************************************************************/
6764 const struct act_prob ap2)
6765{
6766 struct act_prob my_ap1;
6767 struct act_prob my_ap2;
6768
6769 /* The action probabilities are real. */
6772
6773 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6774 if (action_prob_is_signal(ap1)) {
6775 /* Assert that it is OK to convert the signal. */
6777
6778 my_ap1 = ACTPROB_NOT_KNOWN;
6779 } else {
6780 my_ap1 = ap1;
6781 }
6782
6783 if (action_prob_is_signal(ap2)) {
6784 /* Assert that it is OK to convert the signal. */
6786
6787 my_ap2 = ACTPROB_NOT_KNOWN;
6788 } else {
6789 my_ap2 = ap2;
6790 }
6791
6792 /* The action probabilities now have a comparison friendly form. */
6795
6796 /* Do the comparison. Start with min. Continue with max. */
6797 if (my_ap1.min < my_ap2.min) {
6798 return -1;
6799 } else if (my_ap1.min > my_ap2.min) {
6800 return 1;
6801 } else if (my_ap1.max < my_ap2.max) {
6802 return -1;
6803 } else if (my_ap1.max > my_ap2.max) {
6804 return 1;
6805 } else {
6806 return 0;
6807 }
6808}
6809
6810/**********************************************************************/
6815{
6816 struct act_prob my_ap;
6817
6818 /* The action probability is real. */
6820
6821 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6822 if (action_prob_is_signal(ap)) {
6823 /* Assert that it is OK to convert the signal. */
6825
6826 my_ap = ACTPROB_NOT_KNOWN;
6827 } else {
6828 my_ap = ap;
6829 }
6830
6831 /* The action probability now has a math friendly form. */
6833
6834 return (double)my_ap.min / (double) ACTPROB_VAL_MAX;
6835}
6836
6837/**********************************************************************/
6841struct act_prob action_prob_and(const struct act_prob *ap1,
6842 const struct act_prob *ap2)
6843{
6844 struct act_prob my_ap1;
6845 struct act_prob my_ap2;
6846 struct act_prob out;
6847
6848 /* The action probabilities are real. */
6849 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
6850 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
6851
6852 if (action_prob_is_signal(*ap1)
6853 && are_action_probabilitys_equal(ap1, ap2)) {
6854 /* Keep the information rather than converting the signal to
6855 * ACTPROB_NOT_KNOWN. */
6856
6857 /* Assert that it is OK to convert the signal. */
6859
6860 out.min = ap1->min;
6861 out.max = ap2->max;
6862
6863 return out;
6864 }
6865
6866 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6867 if (action_prob_is_signal(*ap1)) {
6868 /* Assert that it is OK to convert the signal. */
6870
6871 my_ap1.min = ACTPROB_VAL_MIN;
6872 my_ap1.max = ACTPROB_VAL_MAX;
6873 } else {
6874 my_ap1.min = ap1->min;
6875 my_ap1.max = ap1->max;
6876 }
6877
6878 if (action_prob_is_signal(*ap2)) {
6879 /* Assert that it is OK to convert the signal. */
6881
6882 my_ap2.min = ACTPROB_VAL_MIN;
6883 my_ap2.max = ACTPROB_VAL_MAX;
6884 } else {
6885 my_ap2.min = ap2->min;
6886 my_ap2.max = ap2->max;
6887 }
6888
6889 /* The action probabilities now have a math friendly form. */
6892
6893 /* Do the math. */
6894 out.min = (my_ap1.min * my_ap2.min) / ACTPROB_VAL_MAX;
6895 out.max = (my_ap1.max * my_ap2.max) / ACTPROB_VAL_MAX;
6896
6897 /* Cap at 100%. */
6898 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6899 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6900
6901 return out;
6902}
6903
6904/**********************************************************************/
6911struct act_prob action_prob_fall_back(const struct act_prob *ap1,
6912 const struct act_prob *ap2)
6913{
6914 struct act_prob my_ap1;
6915 struct act_prob my_ap2;
6916 struct act_prob out;
6917
6918 /* The action probabilities are real. */
6919 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
6920 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
6921
6922 if (action_prob_is_signal(*ap1)
6923 && are_action_probabilitys_equal(ap1, ap2)) {
6924 /* Keep the information rather than converting the signal to
6925 * ACTPROB_NOT_KNOWN. */
6926
6927 /* Assert that it is OK to convert the signal. */
6929
6930 out.min = ap1->min;
6931 out.max = ap2->max;
6932
6933 return out;
6934 }
6935
6936 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6937 if (action_prob_is_signal(*ap1)) {
6938 /* Assert that it is OK to convert the signal. */
6940
6941 my_ap1.min = ACTPROB_VAL_MIN;
6942 my_ap1.max = ACTPROB_VAL_MAX;
6943 } else {
6944 my_ap1.min = ap1->min;
6945 my_ap1.max = ap1->max;
6946 }
6947
6948 if (action_prob_is_signal(*ap2)) {
6949 /* Assert that it is OK to convert the signal. */
6951
6952 my_ap2.min = ACTPROB_VAL_MIN;
6953 my_ap2.max = ACTPROB_VAL_MAX;
6954 } else {
6955 my_ap2.min = ap2->min;
6956 my_ap2.max = ap2->max;
6957 }
6958
6959 /* The action probabilities now have a math friendly form. */
6962
6963 /* Do the math. */
6964 out.min = my_ap1.min + (((ACTPROB_VAL_MAX - my_ap1.min) * my_ap2.min)
6965 / ACTPROB_VAL_MAX);
6966 out.max = my_ap1.max + (((ACTPROB_VAL_MAX - my_ap1.max) * my_ap2.max)
6967 / ACTPROB_VAL_MAX);
6968
6969 /* Cap at 100%. */
6970 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6971 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6972
6973 return out;
6974}
6975
6976/**********************************************************************/
6979int action_dice_roll_initial_odds(const struct action *paction)
6980{
6981 switch (paction->result) {
6982 case ACTRES_STRIKE_BUILDING:
6983 case ACTRES_STRIKE_PRODUCTION:
6984 case ACTRES_SPY_SPREAD_PLAGUE:
6985 case ACTRES_SPY_STEAL_TECH:
6986 case ACTRES_SPY_TARGETED_STEAL_TECH:
6987 case ACTRES_SPY_INCITE_CITY:
6988 case ACTRES_SPY_SABOTAGE_CITY:
6989 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
6990 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
6991 case ACTRES_SPY_STEAL_GOLD:
6992 case ACTRES_STEAL_MAPS:
6993 case ACTRES_SPY_NUKE:
6994 case ACTRES_SPY_POISON:
6995 if (BV_ISSET(game.info.diplchance_initial_odds, paction->id)) {
6996 /* Take the initial odds from the diplchance setting. */
6998 server_setting_by_name("diplchance"));
6999 } else {
7000 /* No initial odds. */
7001 return 100;
7002 }
7003 case ACTRES_ESTABLISH_EMBASSY:
7004 case ACTRES_SPY_INVESTIGATE_CITY:
7005 case ACTRES_TRADE_ROUTE:
7006 case ACTRES_MARKETPLACE:
7007 case ACTRES_HELP_WONDER:
7008 case ACTRES_SPY_BRIBE_UNIT:
7009 case ACTRES_SPY_SABOTAGE_UNIT:
7010 case ACTRES_CAPTURE_UNITS:
7011 case ACTRES_FOUND_CITY:
7012 case ACTRES_JOIN_CITY:
7013 case ACTRES_BOMBARD:
7014 case ACTRES_NUKE:
7015 case ACTRES_NUKE_UNITS:
7016 case ACTRES_DESTROY_CITY:
7017 case ACTRES_EXPEL_UNIT:
7018 case ACTRES_DISBAND_UNIT_RECOVER:
7019 case ACTRES_DISBAND_UNIT:
7020 case ACTRES_HOME_CITY:
7021 case ACTRES_HOMELESS:
7022 case ACTRES_UPGRADE_UNIT:
7023 case ACTRES_PARADROP:
7024 case ACTRES_PARADROP_CONQUER:
7025 case ACTRES_AIRLIFT:
7026 case ACTRES_ATTACK:
7027 case ACTRES_CONQUER_CITY:
7028 case ACTRES_CONQUER_EXTRAS:
7029 case ACTRES_HEAL_UNIT:
7030 case ACTRES_TRANSFORM_TERRAIN:
7031 case ACTRES_CULTIVATE:
7032 case ACTRES_PLANT:
7033 case ACTRES_PILLAGE:
7034 case ACTRES_CLEAN_POLLUTION:
7035 case ACTRES_CLEAN_FALLOUT:
7036 case ACTRES_FORTIFY:
7037 case ACTRES_ROAD:
7038 case ACTRES_CONVERT:
7039 case ACTRES_BASE:
7040 case ACTRES_MINE:
7041 case ACTRES_IRRIGATE:
7042 case ACTRES_TRANSPORT_ALIGHT:
7043 case ACTRES_TRANSPORT_UNLOAD:
7044 case ACTRES_TRANSPORT_DISEMBARK:
7045 case ACTRES_TRANSPORT_BOARD:
7046 case ACTRES_TRANSPORT_EMBARK:
7047 case ACTRES_SPY_ATTACK:
7048 case ACTRES_HUT_ENTER:
7049 case ACTRES_HUT_FRIGHTEN:
7050 case ACTRES_UNIT_MOVE:
7051 case ACTRES_NONE:
7052 /* No additional dice roll. */
7053 break;
7054 }
7055
7056 /* The odds of the action not being stopped by its dice roll when the dice
7057 * isn't thrown is 100%. ACTION_ODDS_PCT_DICE_ROLL_NA is above 100% */
7059}
7060
7061/**********************************************************************/
7064int action_dice_roll_odds(const struct player *act_player,
7065 const struct unit *act_unit,
7066 const struct city *tgt_city,
7067 const struct player *tgt_player,
7068 const struct action *paction)
7069{
7070 int odds = action_dice_roll_initial_odds(paction);
7071
7072 fc_assert_action_msg(odds >= 0 && odds <= 100,
7073 odds = 100,
7074 "Bad initial odds for action number %d."
7075 " Does it roll the dice at all?",
7076 paction->id);
7077
7078 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
7079 * it this way instead of rolling twice is that Action_Odds_Pct can
7080 * increase the odds. */
7081 odds += ((odds * get_target_bonus_effects(
7082 NULL,
7083 &(const struct req_context) {
7084 .player = act_player,
7085 .city = tgt_city,
7086 .unit = act_unit,
7087 .unittype = unit_type_get(act_unit),
7088 .action = paction,
7089 },
7090 tgt_player,
7091 EFT_ACTION_ODDS_PCT))
7092 / 100);
7093
7094 /* Odds are between 0% and 100%. */
7095 return CLIP(0, odds, 100);
7096}
7097
7098/**********************************************************************/
7102{
7103 struct action *paction = action_by_number(act);
7104
7105 /* Always immune since its not enabled. Doesn't count. */
7106 if (!action_is_in_use(paction)) {
7107 return FALSE;
7108 }
7109
7111 if (requirement_fulfilled_by_government(gov, &(enabler->target_reqs))) {
7112 return FALSE;
7113 }
7115
7116 return TRUE;
7117}
7118
7119/**********************************************************************/
7124static bool is_target_possible(const action_id wanted_action,
7125 const struct player *actor_player,
7126 const struct req_context *target)
7127{
7129 enabler) {
7130 if (are_reqs_active(target, actor_player,
7131 &enabler->target_reqs, RPT_POSSIBLE)) {
7132 return TRUE;
7133 }
7135
7136 return FALSE;
7137}
7138
7139/**********************************************************************/
7143 const struct player *actor_player,
7144 const struct city* target_city)
7145{
7147 FALSE, "Action %s is against %s not cities",
7148 action_id_rule_name(act_id),
7149 action_target_kind_name(
7150 action_id_get_target_kind(act_id)));
7151
7152 return is_target_possible(act_id, actor_player,
7153 &(const struct req_context) {
7154 .player = city_owner(target_city),
7155 .city = target_city,
7157 });
7158}
7159
7160/**********************************************************************/
7166 const action_id act_id,
7167 const struct unit *actor_unit)
7168{
7169 const struct player *actor_player = unit_owner(actor_unit);
7170 const struct req_context actor_ctxt = {
7171 .player = actor_player,
7172 .city = tile_city(unit_tile(actor_unit)),
7174 .unit = actor_unit,
7175 .unittype = unit_type_get(actor_unit),
7176 };
7177 const struct action *paction = action_by_number(act_id);
7178
7179 enum fc_tristate result;
7180
7182
7183 if (!utype_can_do_action(actor_unit->utype, act_id)) {
7184 /* The unit type can't perform the action. */
7185 return FALSE;
7186 }
7187
7188 result = action_hard_reqs_actor(nmap, paction, &actor_ctxt, FALSE,
7190
7191 if (result == TRI_NO) {
7192 /* The hard requirements aren't fulfilled. */
7193 return FALSE;
7194 }
7195
7197 enabler) {
7198 const enum fc_tristate current
7199 = mke_eval_reqs(actor_player, &actor_ctxt, NULL,
7200 &enabler->actor_reqs,
7201 /* Needed since no player to evaluate DiplRel
7202 * requirements against. */
7203 RPT_POSSIBLE);
7204
7205 if (current == TRI_YES
7206 || current == TRI_MAYBE) {
7207 /* The ruleset requirements may be fulfilled. */
7208 return TRUE;
7209 }
7211
7212 /* No action enabler allows this action. */
7213 return FALSE;
7214}
7215
7216/**********************************************************************/
7221 const action_id act_id)
7222{
7223 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
7224
7225 /* Check if full movement points may enable the specified action. */
7227 act_id,
7230 act_id,
7232}
7233
7234/**********************************************************************/
7244 const struct unit_type *act_utype)
7245{
7246 const struct action *paction = action_by_number(ae->action);
7247 struct universal actor_univ = { .kind = VUT_UTYPE,
7248 .value.utype = act_utype };
7249
7250 fc_assert_ret_val(paction != NULL, FALSE);
7251 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
7252 fc_assert_ret_val(act_utype != NULL, FALSE);
7253
7254 return (action_actor_utype_hard_reqs_ok(paction, act_utype)
7257 &actor_univ));
7258}
7259
7260/**********************************************************************/
7271{
7272 const struct action *paction = action_by_number(ae->action);
7273
7274 switch (action_get_actor_kind(paction)) {
7275 case AAK_UNIT:
7276 unit_type_iterate(putype) {
7277 if (action_enabler_utype_possible_actor(ae, putype)) {
7278 /* A possible actor unit type has been found. */
7279 return TRUE;
7280 }
7282
7283 /* No actor detected. */
7284 return FALSE;
7285 case AAK_COUNT:
7286 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
7287 break;
7288 }
7289
7290 /* No actor detected. */
7291 return FALSE;
7292}
7293
7294/**********************************************************************/
7302{
7303 switch (action_get_actor_kind(paction)) {
7304 case AAK_UNIT:
7305 unit_type_iterate(putype) {
7306 if (action_actor_utype_hard_reqs_ok(paction, putype)) {
7307 return TRUE;
7308 }
7310 break;
7311 case AAK_COUNT:
7312 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
7313 break;
7314 }
7315
7316 /* No actor detected. */
7317 return FALSE;
7318}
7319
7320/**********************************************************************/
7326bool action_is_in_use(struct action *paction)
7327{
7328 struct action_enabler_list *enablers;
7329
7331 /* Hard requirements not fulfilled. */
7332 return FALSE;
7333 }
7334
7336
7338 /* If this iteration finds any entries, action is enabled. */
7339 return TRUE;
7341
7342 /* No non deleted action enabler. */
7343 return FALSE;
7344}
7345
7346/**********************************************************************/
7350{
7351 fc_assert_ret_val(num >= 0, NULL);
7353
7354 return &auto_perfs[num];
7355}
7356
7357/**********************************************************************/
7366{
7367 return action_auto_perf_slot_number(num);
7368}
7369
7370/**********************************************************************/
7373bool action_univs_not_blocking(const struct action *paction,
7374 struct universal *actor_uni,
7375 struct universal *target_uni)
7376{
7378 enab) {
7379 if ((actor_uni == NULL
7380 || universal_fulfills_requirements(FALSE, &(enab->actor_reqs),
7381 actor_uni))
7382 && (target_uni == NULL
7383 || universal_fulfills_requirements(FALSE, &(enab->target_reqs),
7384 target_uni))) {
7385 return TRUE;
7386 }
7388
7389 return FALSE;
7390}
7391
7392/**********************************************************************/
7397void action_list_end(action_id *act_list, int size)
7398{
7400
7401 if (size < MAX_NUM_ACTIONS) {
7402 /* An action list is terminated by ACTION_NONE */
7403 act_list[size] = ACTION_NONE;
7404 }
7405}
7406
7407/**********************************************************************/
7415 int *position,
7416 enum action_result result)
7417{
7418 action_iterate(act) {
7419 struct action *paction = action_by_number(act);
7420 if (paction->result == result) {
7421 /* Assume one result for each action. */
7422 fc_assert_ret(*position < MAX_NUM_ACTIONS);
7423
7424 act_list[(*position)++] = paction->id;
7425 }
7427}
7428
7429/**********************************************************************/
7435{
7436 switch ((enum gen_action)act) {
7437 case ACTION_SPY_POISON:
7438 return "ui_name_poison_city";
7439 case ACTION_SPY_POISON_ESC:
7440 return "ui_name_poison_city_escape";
7441 case ACTION_SPY_SABOTAGE_UNIT:
7442 return "ui_name_sabotage_unit";
7443 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7444 return "ui_name_sabotage_unit_escape";
7445 case ACTION_SPY_BRIBE_UNIT:
7446 return "ui_name_bribe_unit";
7447 case ACTION_SPY_SABOTAGE_CITY:
7448 return "ui_name_sabotage_city";
7449 case ACTION_SPY_SABOTAGE_CITY_ESC:
7450 return "ui_name_sabotage_city_escape";
7451 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7452 return "ui_name_targeted_sabotage_city";
7453 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7454 return "ui_name_sabotage_city_production";
7455 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7456 return "ui_name_targeted_sabotage_city_escape";
7457 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7458 return "ui_name_sabotage_city_production_escape";
7459 case ACTION_SPY_INCITE_CITY:
7460 return "ui_name_incite_city";
7461 case ACTION_SPY_INCITE_CITY_ESC:
7462 return "ui_name_incite_city_escape";
7463 case ACTION_ESTABLISH_EMBASSY:
7464 return "ui_name_establish_embassy";
7465 case ACTION_ESTABLISH_EMBASSY_STAY:
7466 return "ui_name_establish_embassy_stay";
7467 case ACTION_SPY_STEAL_TECH:
7468 return "ui_name_steal_tech";
7469 case ACTION_SPY_STEAL_TECH_ESC:
7470 return "ui_name_steal_tech_escape";
7471 case ACTION_SPY_TARGETED_STEAL_TECH:
7472 return "ui_name_targeted_steal_tech";
7473 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7474 return "ui_name_targeted_steal_tech_escape";
7475 case ACTION_SPY_INVESTIGATE_CITY:
7476 return "ui_name_investigate_city";
7477 case ACTION_INV_CITY_SPEND:
7478 return "ui_name_investigate_city_spend_unit";
7479 case ACTION_SPY_STEAL_GOLD:
7480 return "ui_name_steal_gold";
7481 case ACTION_SPY_STEAL_GOLD_ESC:
7482 return "ui_name_steal_gold_escape";
7483 case ACTION_SPY_SPREAD_PLAGUE:
7484 return "ui_name_spread_plague";
7485 case ACTION_STEAL_MAPS:
7486 return "ui_name_steal_maps";
7487 case ACTION_STEAL_MAPS_ESC:
7488 return "ui_name_steal_maps_escape";
7489 case ACTION_TRADE_ROUTE:
7490 return "ui_name_establish_trade_route";
7491 case ACTION_MARKETPLACE:
7492 return "ui_name_enter_marketplace";
7493 case ACTION_HELP_WONDER:
7494 return "ui_name_help_wonder";
7495 case ACTION_CAPTURE_UNITS:
7496 return "ui_name_capture_units";
7497 case ACTION_EXPEL_UNIT:
7498 return "ui_name_expel_unit";
7499 case ACTION_FOUND_CITY:
7500 return "ui_name_found_city";
7501 case ACTION_JOIN_CITY:
7502 return "ui_name_join_city";
7503 case ACTION_BOMBARD:
7504 return "ui_name_bombard";
7505 case ACTION_BOMBARD2:
7506 return "ui_name_bombard_2";
7507 case ACTION_BOMBARD3:
7508 return "ui_name_bombard_3";
7509 case ACTION_SPY_NUKE:
7510 return "ui_name_suitcase_nuke";
7511 case ACTION_SPY_NUKE_ESC:
7512 return "ui_name_suitcase_nuke_escape";
7513 case ACTION_NUKE:
7514 return "ui_name_explode_nuclear";
7515 case ACTION_NUKE_CITY:
7516 return "ui_name_nuke_city";
7517 case ACTION_NUKE_UNITS:
7518 return "ui_name_nuke_units";
7519 case ACTION_DESTROY_CITY:
7520 return "ui_name_destroy_city";
7521 case ACTION_DISBAND_UNIT_RECOVER:
7522 return "ui_name_disband_unit_recover";
7523 case ACTION_DISBAND_UNIT:
7524 return "ui_name_disband_unit";
7525 case ACTION_HOME_CITY:
7526 return "ui_name_home_city";
7527 case ACTION_HOMELESS:
7528 return "ui_name_homeless";
7529 case ACTION_UPGRADE_UNIT:
7530 return "ui_name_upgrade_unit";
7531 case ACTION_PARADROP:
7532 return "ui_name_paradrop_unit";
7533 case ACTION_PARADROP_CONQUER:
7534 return "ui_name_paradrop_unit_conquer";
7535 case ACTION_PARADROP_FRIGHTEN:
7536 return "ui_name_paradrop_unit_frighten";
7537 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7538 return "ui_name_paradrop_unit_frighten_conquer";
7539 case ACTION_PARADROP_ENTER:
7540 return "ui_name_paradrop_unit_enter";
7541 case ACTION_PARADROP_ENTER_CONQUER:
7542 return "ui_name_paradrop_unit_enter_conquer";
7543 case ACTION_AIRLIFT:
7544 return "ui_name_airlift_unit";
7545 case ACTION_ATTACK:
7546 return "ui_name_attack";
7547 case ACTION_SUICIDE_ATTACK:
7548 return "ui_name_suicide_attack";
7549 case ACTION_STRIKE_BUILDING:
7550 return "ui_name_surgical_strike_building";
7551 case ACTION_STRIKE_PRODUCTION:
7552 return "ui_name_surgical_strike_production";
7553 case ACTION_CONQUER_CITY:
7554 return "ui_name_conquer_city";
7555 case ACTION_CONQUER_CITY2:
7556 return "ui_name_conquer_city_2";
7557 case ACTION_CONQUER_CITY3:
7558 return "ui_name_conquer_city_3";
7559 case ACTION_CONQUER_CITY4:
7560 return "ui_name_conquer_city_4";
7561 case ACTION_CONQUER_EXTRAS:
7562 return "ui_name_conquer_extras";
7563 case ACTION_CONQUER_EXTRAS2:
7564 return "ui_name_conquer_extras_2";
7565 case ACTION_CONQUER_EXTRAS3:
7566 return "ui_name_conquer_extras_3";
7567 case ACTION_CONQUER_EXTRAS4:
7568 return "ui_name_conquer_extras_4";
7569 case ACTION_HEAL_UNIT:
7570 return "ui_name_heal_unit";
7571 case ACTION_HEAL_UNIT2:
7572 return "ui_name_heal_unit_2";
7573 case ACTION_TRANSFORM_TERRAIN:
7574 return "ui_name_transform_terrain";
7575 case ACTION_CULTIVATE:
7576 return "ui_name_cultivate";
7577 case ACTION_PLANT:
7578 return "ui_name_plant";
7579 case ACTION_PILLAGE:
7580 return "ui_name_pillage";
7581 case ACTION_CLEAN_POLLUTION:
7582 return "ui_name_clean_pollution";
7583 case ACTION_CLEAN_FALLOUT:
7584 return "ui_name_clean_fallout";
7585 case ACTION_FORTIFY:
7586 return "ui_name_fortify";
7587 case ACTION_ROAD:
7588 return "ui_name_road";
7589 case ACTION_CONVERT:
7590 return "ui_name_convert_unit";
7591 case ACTION_BASE:
7592 return "ui_name_build_base";
7593 case ACTION_MINE:
7594 return "ui_name_build_mine";
7595 case ACTION_IRRIGATE:
7596 return "ui_name_irrigate";
7597 case ACTION_TRANSPORT_ALIGHT:
7598 return "ui_name_transport_alight";
7599 case ACTION_TRANSPORT_BOARD:
7600 return "ui_name_transport_board";
7601 case ACTION_TRANSPORT_EMBARK:
7602 return "ui_name_transport_embark";
7603 case ACTION_TRANSPORT_EMBARK2:
7604 return "ui_name_transport_embark_2";
7605 case ACTION_TRANSPORT_EMBARK3:
7606 return "ui_name_transport_embark_3";
7607 case ACTION_TRANSPORT_UNLOAD:
7608 return "ui_name_transport_unload";
7609 case ACTION_TRANSPORT_DISEMBARK1:
7610 return "ui_name_transport_disembark";
7611 case ACTION_TRANSPORT_DISEMBARK2:
7612 return "ui_name_transport_disembark_2";
7613 case ACTION_TRANSPORT_DISEMBARK3:
7614 return "ui_name_transport_disembark_3";
7615 case ACTION_TRANSPORT_DISEMBARK4:
7616 return "ui_name_transport_disembark_4";
7617 case ACTION_HUT_ENTER:
7618 return "ui_name_enter_hut";
7619 case ACTION_HUT_ENTER2:
7620 return "ui_name_enter_hut_2";
7621 case ACTION_HUT_ENTER3:
7622 return "ui_name_enter_hut_3";
7623 case ACTION_HUT_ENTER4:
7624 return "ui_name_enter_hut_4";
7625 case ACTION_HUT_FRIGHTEN:
7626 return "ui_name_frighten_hut";
7627 case ACTION_HUT_FRIGHTEN2:
7628 return "ui_name_frighten_hut_2";
7629 case ACTION_HUT_FRIGHTEN3:
7630 return "ui_name_frighten_hut_3";
7631 case ACTION_HUT_FRIGHTEN4:
7632 return "ui_name_frighten_hut_4";
7633 case ACTION_SPY_ATTACK:
7634 return "ui_name_spy_attack";
7635 case ACTION_UNIT_MOVE:
7636 return "ui_name_unit_move";
7637 case ACTION_UNIT_MOVE2:
7638 return "ui_name_unit_move_2";
7639 case ACTION_UNIT_MOVE3:
7640 return "ui_name_unit_move_3";
7641 case ACTION_USER_ACTION1:
7642 return "ui_name_user_action_1";
7643 case ACTION_USER_ACTION2:
7644 return "ui_name_user_action_2";
7645 case ACTION_USER_ACTION3:
7646 return "ui_name_user_action_3";
7647 case ACTION_USER_ACTION4:
7648 return "ui_name_user_action_4";
7649 case ACTION_COUNT:
7650 break;
7651 }
7652
7653 fc_assert(act >= 0 && act < ACTION_COUNT);
7654 return NULL;
7655}
7656
7657/**********************************************************************/
7660const char *action_ui_name_default(int act)
7661{
7662 switch ((enum gen_action)act) {
7663 case ACTION_SPY_POISON:
7664 /* TRANS: _Poison City (3% chance of success). */
7665 return N_("%sPoison City%s");
7666 case ACTION_SPY_POISON_ESC:
7667 /* TRANS: _Poison City and Escape (3% chance of success). */
7668 return N_("%sPoison City and Escape%s");
7669 case ACTION_SPY_SABOTAGE_UNIT:
7670 /* TRANS: S_abotage Enemy Unit (3% chance of success). */
7671 return N_("S%sabotage Enemy Unit%s");
7672 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7673 /* TRANS: S_abotage Enemy Unit and Escape (3% chance of success). */
7674 return N_("S%sabotage Enemy Unit and Escape%s");
7675 case ACTION_SPY_BRIBE_UNIT:
7676 /* TRANS: Bribe Enemy _Unit (3% chance of success). */
7677 return N_("Bribe Enemy %sUnit%s");
7678 case ACTION_SPY_SABOTAGE_CITY:
7679 /* TRANS: _Sabotage City (3% chance of success). */
7680 return N_("%sSabotage City%s");
7681 case ACTION_SPY_SABOTAGE_CITY_ESC:
7682 /* TRANS: _Sabotage City and Escape (3% chance of success). */
7683 return N_("%sSabotage City and Escape%s");
7684 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7685 /* TRANS: Industria_l Sabotage (3% chance of success). */
7686 return N_("Industria%sl Sabotage%s");
7687 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7688 /* TRANS: Industria_l Sabotage Production (3% chance of success). */
7689 return N_("Industria%sl Sabotage Production%s");
7690 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7691 /* TRANS: Industria_l Sabotage and Escape (3% chance of success). */
7692 return N_("Industria%sl Sabotage and Escape%s");
7693 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7694 /* TRANS: Industria_l Sabotage Production and Escape (3% chance of success). */
7695 return N_("Industria%sl Sabotage Production and Escape%s");
7696 case ACTION_SPY_INCITE_CITY:
7697 /* TRANS: Incite a Re_volt (3% chance of success). */
7698 return N_("Incite a Re%svolt%s");
7699 case ACTION_SPY_INCITE_CITY_ESC:
7700 /* TRANS: Incite a Re_volt and Escape (3% chance of success). */
7701 return N_("Incite a Re%svolt and Escape%s");
7702 case ACTION_ESTABLISH_EMBASSY:
7703 /* TRANS: Establish _Embassy (100% chance of success). */
7704 return N_("Establish %sEmbassy%s");
7705 case ACTION_ESTABLISH_EMBASSY_STAY:
7706 /* TRANS: Becom_e Ambassador (100% chance of success). */
7707 return N_("Becom%se Ambassador%s");
7708 case ACTION_SPY_STEAL_TECH:
7709 /* TRANS: Steal _Technology (3% chance of success). */
7710 return N_("Steal %sTechnology%s");
7711 case ACTION_SPY_STEAL_TECH_ESC:
7712 /* TRANS: Steal _Technology and Escape (3% chance of success). */
7713 return N_("Steal %sTechnology and Escape%s");
7714 case ACTION_SPY_TARGETED_STEAL_TECH:
7715 /* TRANS: In_dustrial Espionage (3% chance of success). */
7716 return N_("In%sdustrial Espionage%s");
7717 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7718 /* TRANS: In_dustrial Espionage and Escape (3% chance of success). */
7719 return N_("In%sdustrial Espionage and Escape%s");
7720 case ACTION_SPY_INVESTIGATE_CITY:
7721 /* TRANS: _Investigate City (100% chance of success). */
7722 return N_("%sInvestigate City%s");
7723 case ACTION_INV_CITY_SPEND:
7724 /* TRANS: _Investigate City (spends the unit) (100% chance of
7725 * success). */
7726 return N_("%sInvestigate City (spends the unit)%s");
7727 case ACTION_SPY_STEAL_GOLD:
7728 /* TRANS: Steal _Gold (100% chance of success). */
7729 return N_("Steal %sGold%s");
7730 case ACTION_SPY_STEAL_GOLD_ESC:
7731 /* TRANS: Steal _Gold and Escape (100% chance of success). */
7732 return N_("Steal %sGold and Escape%s");
7733 case ACTION_SPY_SPREAD_PLAGUE:
7734 /* TRANS: Spread _Plague (100% chance of success). */
7735 return N_("Spread %sPlague%s");
7736 case ACTION_STEAL_MAPS:
7737 /* TRANS: Steal _Maps (100% chance of success). */
7738 return N_("Steal %sMaps%s");
7739 case ACTION_STEAL_MAPS_ESC:
7740 /* TRANS: Steal _Maps and Escape (100% chance of success). */
7741 return N_("Steal %sMaps and Escape%s");
7742 case ACTION_TRADE_ROUTE:
7743 /* TRANS: Establish Trade _Route (100% chance of success). */
7744 return N_("Establish Trade %sRoute%s");
7745 case ACTION_MARKETPLACE:
7746 /* TRANS: Enter _Marketplace (100% chance of success). */
7747 return N_("Enter %sMarketplace%s");
7748 case ACTION_HELP_WONDER:
7749 /* TRANS: Help _build Wonder (100% chance of success). */
7750 return N_("Help %sbuild Wonder%s");
7751 case ACTION_CAPTURE_UNITS:
7752 /* TRANS: _Capture Units (100% chance of success). */
7753 return N_("%sCapture Units%s");
7754 case ACTION_EXPEL_UNIT:
7755 /* TRANS: _Expel Unit (100% chance of success). */
7756 return N_("%sExpel Unit%s");
7757 case ACTION_FOUND_CITY:
7758 /* TRANS: _Found City (100% chance of success). */
7759 return N_("%sFound City%s");
7760 case ACTION_JOIN_CITY:
7761 /* TRANS: _Join City (100% chance of success). */
7762 return N_("%sJoin City%s");
7763 case ACTION_BOMBARD:
7764 /* TRANS: B_ombard (100% chance of success). */
7765 return N_("B%sombard%s");
7766 case ACTION_BOMBARD2:
7767 /* TRANS: B_ombard 2 (100% chance of success). */
7768 return N_("B%sombard 2%s");
7769 case ACTION_BOMBARD3:
7770 /* TRANS: B_ombard 3 (100% chance of success). */
7771 return N_("B%sombard 3%s");
7772 case ACTION_SPY_NUKE:
7773 /* TRANS: Suitcase _Nuke (100% chance of success). */
7774 return N_("Suitcase %sNuke%s");
7775 case ACTION_SPY_NUKE_ESC:
7776 /* TRANS: Suitcase _Nuke and Escape (100% chance of success). */
7777 return N_("Suitcase %sNuke and Escape%s");
7778 case ACTION_NUKE:
7779 /* TRANS: Explode _Nuclear (100% chance of success). */
7780 return N_("Explode %sNuclear%s");
7781 case ACTION_NUKE_CITY:
7782 /* TRANS: _Nuke City (100% chance of success). */
7783 return N_("%sNuke City%s");
7784 case ACTION_NUKE_UNITS:
7785 /* TRANS: _Nuke Units (100% chance of success). */
7786 return N_("%sNuke Units%s");
7787 case ACTION_DESTROY_CITY:
7788 /* TRANS: Destroy _City (100% chance of success). */
7789 return N_("Destroy %sCity%s");
7790 case ACTION_DISBAND_UNIT_RECOVER:
7791 /* TRANS: Dis_band recovering production (100% chance of success). */
7792 return N_("Dis%sband recovering production%s");
7793 case ACTION_DISBAND_UNIT:
7794 /* TRANS: Dis_band without recovering production (100% chance of success). */
7795 return N_("Dis%sband without recovering production%s");
7796 case ACTION_HOME_CITY:
7797 /* TRANS: Set _Home City (100% chance of success). */
7798 return N_("Set %sHome City%s");
7799 case ACTION_HOMELESS:
7800 /* TRANS: Make _Homeless (100% chance of success). */
7801 return N_("Make %sHomeless%s");
7802 case ACTION_UPGRADE_UNIT:
7803 /* TRANS: _Upgrade Unit (100% chance of success). */
7804 return N_("%sUpgrade Unit%s");
7805 case ACTION_PARADROP:
7806 /* TRANS: Drop _Paratrooper (100% chance of success). */
7807 return N_("Drop %sParatrooper%s");
7808 case ACTION_PARADROP_CONQUER:
7809 /* TRANS: Drop _Paratrooper (100% chance of success). */
7810 return N_("Drop %sParatrooper%s");
7811 case ACTION_PARADROP_FRIGHTEN:
7812 /* TRANS: Drop _Paratrooper (100% chance of success). */
7813 return N_("Drop %sParatrooper%s");
7814 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7815 /* TRANS: Drop _Paratrooper (100% chance of success). */
7816 return N_("Drop %sParatrooper%s");
7817 case ACTION_PARADROP_ENTER:
7818 /* TRANS: Drop _Paratrooper (100% chance of success). */
7819 return N_("Drop %sParatrooper%s");
7820 case ACTION_PARADROP_ENTER_CONQUER:
7821 /* TRANS: Drop _Paratrooper (100% chance of success). */
7822 return N_("Drop %sParatrooper%s");
7823 case ACTION_AIRLIFT:
7824 /* TRANS: _Airlift to City (100% chance of success). */
7825 return N_("%sAirlift to City%s");
7826 case ACTION_ATTACK:
7827 /* TRANS: _Attack (100% chance of success). */
7828 return N_("%sAttack%s");
7829 case ACTION_SUICIDE_ATTACK:
7830 /* TRANS: _Suicide Attack (100% chance of success). */
7831 return N_("%sSuicide Attack%s");
7832 case ACTION_STRIKE_BUILDING:
7833 /* TRANS: Surgical Str_ike Building (100% chance of success). */
7834 return N_("Surgical Str%sike Building%s");
7835 case ACTION_STRIKE_PRODUCTION:
7836 /* TRANS: Surgical Str_ike Production (100% chance of success). */
7837 return N_("Surgical Str%sike Production%s");
7838 case ACTION_CONQUER_CITY:
7839 case ACTION_CONQUER_CITY3:
7840 case ACTION_CONQUER_CITY4:
7841 /* TRANS: _Conquer City (100% chance of success). */
7842 return N_("%sConquer City%s");
7843 case ACTION_CONQUER_CITY2:
7844 /* TRANS: _Conquer City 2 (100% chance of success). */
7845 return N_("%sConquer City 2%s");
7846 case ACTION_CONQUER_EXTRAS:
7847 case ACTION_CONQUER_EXTRAS3:
7848 case ACTION_CONQUER_EXTRAS4:
7849 /* TRANS: _Conquer Extras (100% chance of success). */
7850 return N_("%sConquer Extras%s");
7851 case ACTION_CONQUER_EXTRAS2:
7852 /* TRANS: _Conquer Extras 2 (100% chance of success). */
7853 return N_("%sConquer Extras 2%s");
7854 case ACTION_HEAL_UNIT:
7855 case ACTION_HEAL_UNIT2:
7856 /* TRANS: Heal _Unit (3% chance of success). */
7857 return N_("Heal %sUnit%s");
7858 case ACTION_TRANSFORM_TERRAIN:
7859 /* TRANS: _Transform Terrain (3% chance of success). */
7860 return N_("%sTransform Terrain%s");
7861 case ACTION_CULTIVATE:
7862 /* TRANS: Transform by _Cultivating (3% chance of success). */
7863 return N_("Transform by %sCultivating%s");
7864 case ACTION_PLANT:
7865 /* TRANS: Transform by _Planting (3% chance of success). */
7866 return N_("Transform by %sPlanting%s");
7867 case ACTION_PILLAGE:
7868 /* TRANS: Pilla_ge (100% chance of success). */
7869 return N_("Pilla%sge%s");
7870 case ACTION_CLEAN_POLLUTION:
7871 /* TRANS: Clean _Pollution (100% chance of success). */
7872 return N_("Clean %sPollution%s");
7873 case ACTION_CLEAN_FALLOUT:
7874 /* TRANS: Clean _Fallout (100% chance of success). */
7875 return N_("Clean %sFallout%s");
7876 case ACTION_FORTIFY:
7877 /* TRANS: _Fortify (100% chance of success). */
7878 return N_("%sFortify%s");
7879 case ACTION_ROAD:
7880 /* TRANS: Build _Road (100% chance of success). */
7881 return N_("Build %sRoad%s");
7882 case ACTION_CONVERT:
7883 /* TRANS: _Convert Unit (100% chance of success). */
7884 return N_("%sConvert Unit%s");
7885 case ACTION_BASE:
7886 /* TRANS: _Build Base (100% chance of success). */
7887 return N_("%sBuild Base%s");
7888 case ACTION_MINE:
7889 /* TRANS: Build _Mine (100% chance of success). */
7890 return N_("Build %sMine%s");
7891 case ACTION_IRRIGATE:
7892 /* TRANS: Build _Irrigation (100% chance of success). */
7893 return N_("Build %sIrrigation%s");
7894 case ACTION_TRANSPORT_ALIGHT:
7895 /* TRANS: _Deboard (100% chance of success). */
7896 return N_("%sDeboard%s");
7897 case ACTION_TRANSPORT_BOARD:
7898 /* TRANS: _Board (100% chance of success). */
7899 return N_("%sBoard%s");
7900 case ACTION_TRANSPORT_EMBARK:
7901 case ACTION_TRANSPORT_EMBARK2:
7902 case ACTION_TRANSPORT_EMBARK3:
7903 /* TRANS: _Embark (100% chance of success). */
7904 return N_("%sEmbark%s");
7905 case ACTION_TRANSPORT_UNLOAD:
7906 /* TRANS: _Unload (100% chance of success). */
7907 return N_("%sUnload%s");
7908 case ACTION_TRANSPORT_DISEMBARK1:
7909 case ACTION_TRANSPORT_DISEMBARK3:
7910 case ACTION_TRANSPORT_DISEMBARK4:
7911 /* TRANS: _Disembark (100% chance of success). */
7912 return N_("%sDisembark%s");
7913 case ACTION_TRANSPORT_DISEMBARK2:
7914 /* TRANS: _Disembark 2 (100% chance of success). */
7915 return N_("%sDisembark 2%s");
7916 case ACTION_SPY_ATTACK:
7917 /* TRANS: _Eliminate Diplomat (100% chance of success). */
7918 return N_("%sEliminate Diplomat%s");
7919 case ACTION_HUT_ENTER:
7920 case ACTION_HUT_ENTER2:
7921 case ACTION_HUT_ENTER3:
7922 case ACTION_HUT_ENTER4:
7923 /* TRANS: Enter _Hut (100% chance of success). */
7924 return N_("Enter %sHut%s");
7925 case ACTION_HUT_FRIGHTEN:
7926 case ACTION_HUT_FRIGHTEN2:
7927 case ACTION_HUT_FRIGHTEN3:
7928 case ACTION_HUT_FRIGHTEN4:
7929 /* TRANS: Frighten _Hut (100% chance of success). */
7930 return N_("Frighten %sHut%s");
7931 case ACTION_UNIT_MOVE:
7932 case ACTION_UNIT_MOVE2:
7933 case ACTION_UNIT_MOVE3:
7934 /* TRANS: Regular _Move (100% chance of success). */
7935 return N_("Regular %sMove%s");
7936 case ACTION_USER_ACTION1:
7937 /* TRANS: _User Action 1 (100% chance of success). */
7938 return N_("%sUser Action 1%s");
7939 case ACTION_USER_ACTION2:
7940 /* TRANS: _User Action 2 (100% chance of success). */
7941 return N_("%sUser Action 2%s");
7942 case ACTION_USER_ACTION3:
7943 /* TRANS: _User Action 3 (100% chance of success). */
7944 return N_("%sUser Action 3%s");
7945 case ACTION_USER_ACTION4:
7946 /* TRANS: _User Action 4 (100% chance of success). */
7947 return N_("%sUser Action 4%s");
7948 case ACTION_COUNT:
7949 fc_assert(act != ACTION_COUNT);
7950 break;
7951 }
7952
7953 return NULL;
7954}
7955
7956/**********************************************************************/
7963{
7964 switch ((enum gen_action)act) {
7965 case ACTION_SPY_POISON:
7966 case ACTION_SPY_POISON_ESC:
7967 case ACTION_SPY_SABOTAGE_UNIT:
7968 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7969 case ACTION_SPY_BRIBE_UNIT:
7970 case ACTION_SPY_SABOTAGE_CITY:
7971 case ACTION_SPY_SABOTAGE_CITY_ESC:
7972 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7973 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7974 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7975 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7976 case ACTION_SPY_INCITE_CITY:
7977 case ACTION_SPY_INCITE_CITY_ESC:
7978 case ACTION_ESTABLISH_EMBASSY:
7979 case ACTION_ESTABLISH_EMBASSY_STAY:
7980 case ACTION_SPY_STEAL_TECH:
7981 case ACTION_SPY_STEAL_TECH_ESC:
7982 case ACTION_SPY_TARGETED_STEAL_TECH:
7983 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7984 case ACTION_SPY_INVESTIGATE_CITY:
7985 case ACTION_INV_CITY_SPEND:
7986 case ACTION_SPY_STEAL_GOLD:
7987 case ACTION_SPY_STEAL_GOLD_ESC:
7988 case ACTION_SPY_SPREAD_PLAGUE:
7989 case ACTION_STEAL_MAPS:
7990 case ACTION_STEAL_MAPS_ESC:
7991 case ACTION_TRADE_ROUTE:
7992 case ACTION_MARKETPLACE:
7993 case ACTION_HELP_WONDER:
7994 case ACTION_CAPTURE_UNITS:
7995 case ACTION_EXPEL_UNIT:
7996 case ACTION_FOUND_CITY:
7997 case ACTION_JOIN_CITY:
7998 case ACTION_SPY_NUKE:
7999 case ACTION_SPY_NUKE_ESC:
8000 case ACTION_DESTROY_CITY:
8001 case ACTION_DISBAND_UNIT_RECOVER:
8002 case ACTION_DISBAND_UNIT:
8003 case ACTION_HOME_CITY:
8004 case ACTION_HOMELESS:
8005 case ACTION_UPGRADE_UNIT:
8006 case ACTION_PARADROP:
8007 case ACTION_PARADROP_CONQUER:
8008 case ACTION_PARADROP_FRIGHTEN:
8009 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8010 case ACTION_PARADROP_ENTER:
8011 case ACTION_PARADROP_ENTER_CONQUER:
8012 case ACTION_AIRLIFT:
8013 case ACTION_ATTACK:
8014 case ACTION_SUICIDE_ATTACK:
8015 case ACTION_STRIKE_BUILDING:
8016 case ACTION_STRIKE_PRODUCTION:
8017 case ACTION_CONQUER_CITY:
8018 case ACTION_CONQUER_CITY2:
8019 case ACTION_CONQUER_CITY3:
8020 case ACTION_CONQUER_CITY4:
8021 case ACTION_HEAL_UNIT:
8022 case ACTION_HEAL_UNIT2:
8023 case ACTION_TRANSFORM_TERRAIN:
8024 case ACTION_CULTIVATE:
8025 case ACTION_PLANT:
8026 case ACTION_PILLAGE:
8027 case ACTION_CLEAN_POLLUTION:
8028 case ACTION_CLEAN_FALLOUT:
8029 case ACTION_FORTIFY:
8030 case ACTION_ROAD:
8031 case ACTION_CONVERT:
8032 case ACTION_BASE:
8033 case ACTION_MINE:
8034 case ACTION_IRRIGATE:
8035 case ACTION_TRANSPORT_ALIGHT:
8036 case ACTION_TRANSPORT_BOARD:
8037 case ACTION_TRANSPORT_EMBARK:
8038 case ACTION_TRANSPORT_EMBARK2:
8039 case ACTION_TRANSPORT_EMBARK3:
8040 case ACTION_TRANSPORT_UNLOAD:
8041 case ACTION_TRANSPORT_DISEMBARK1:
8042 case ACTION_TRANSPORT_DISEMBARK2:
8043 case ACTION_TRANSPORT_DISEMBARK3:
8044 case ACTION_TRANSPORT_DISEMBARK4:
8045 case ACTION_BOMBARD:
8046 case ACTION_BOMBARD2:
8047 case ACTION_BOMBARD3:
8048 case ACTION_SPY_ATTACK:
8049 case ACTION_CONQUER_EXTRAS:
8050 case ACTION_CONQUER_EXTRAS2:
8051 case ACTION_CONQUER_EXTRAS3:
8052 case ACTION_CONQUER_EXTRAS4:
8053 case ACTION_HUT_ENTER:
8054 case ACTION_HUT_ENTER2:
8055 case ACTION_HUT_ENTER3:
8056 case ACTION_HUT_ENTER4:
8057 case ACTION_HUT_FRIGHTEN:
8058 case ACTION_HUT_FRIGHTEN2:
8059 case ACTION_HUT_FRIGHTEN4:
8060 case ACTION_HUT_FRIGHTEN3:
8061 case ACTION_UNIT_MOVE:
8062 case ACTION_UNIT_MOVE2:
8063 case ACTION_UNIT_MOVE3:
8064 /* Min range is not ruleset changeable */
8065 return NULL;
8066 case ACTION_NUKE:
8067 return "explode_nuclear_min_range";
8068 case ACTION_NUKE_CITY:
8069 return "nuke_city_min_range";
8070 case ACTION_NUKE_UNITS:
8071 return "nuke_units_min_range";
8072 case ACTION_USER_ACTION1:
8073 return "user_action_1_min_range";
8074 case ACTION_USER_ACTION2:
8075 return "user_action_2_min_range";
8076 case ACTION_USER_ACTION3:
8077 return "user_action_3_min_range";
8078 case ACTION_USER_ACTION4:
8079 return "user_action_4_min_range";
8080 case ACTION_COUNT:
8081 break;
8082 }
8083
8084 fc_assert(act >= 0 && act < ACTION_COUNT);
8085 return NULL;
8086}
8087
8088/**********************************************************************/
8091int action_min_range_default(enum action_result result)
8092{
8093 switch (result) {
8094 case ACTRES_ESTABLISH_EMBASSY:
8095 case ACTRES_SPY_INVESTIGATE_CITY:
8096 case ACTRES_SPY_POISON:
8097 case ACTRES_SPY_STEAL_GOLD:
8098 case ACTRES_SPY_SABOTAGE_CITY:
8099 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8100 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8101 case ACTRES_SPY_STEAL_TECH:
8102 case ACTRES_SPY_TARGETED_STEAL_TECH:
8103 case ACTRES_SPY_INCITE_CITY:
8104 case ACTRES_TRADE_ROUTE:
8105 case ACTRES_MARKETPLACE:
8106 case ACTRES_HELP_WONDER:
8107 case ACTRES_SPY_BRIBE_UNIT:
8108 case ACTRES_SPY_SABOTAGE_UNIT:
8109 case ACTRES_CAPTURE_UNITS:
8110 case ACTRES_FOUND_CITY:
8111 case ACTRES_JOIN_CITY:
8112 case ACTRES_STEAL_MAPS:
8113 case ACTRES_BOMBARD:
8114 case ACTRES_SPY_NUKE:
8115 case ACTRES_DESTROY_CITY:
8116 case ACTRES_EXPEL_UNIT:
8117 case ACTRES_DISBAND_UNIT_RECOVER:
8118 case ACTRES_DISBAND_UNIT:
8119 case ACTRES_HOME_CITY:
8120 case ACTRES_HOMELESS:
8121 case ACTRES_UPGRADE_UNIT:
8122 case ACTRES_PARADROP:
8123 case ACTRES_PARADROP_CONQUER:
8124 case ACTRES_AIRLIFT:
8125 case ACTRES_STRIKE_BUILDING:
8126 case ACTRES_STRIKE_PRODUCTION:
8127 case ACTRES_ATTACK:
8128 case ACTRES_CONQUER_CITY:
8129 case ACTRES_HEAL_UNIT:
8130 case ACTRES_TRANSFORM_TERRAIN:
8131 case ACTRES_CULTIVATE:
8132 case ACTRES_PLANT:
8133 case ACTRES_PILLAGE:
8134 case ACTRES_CLEAN_POLLUTION:
8135 case ACTRES_CLEAN_FALLOUT:
8136 case ACTRES_FORTIFY:
8137 case ACTRES_ROAD:
8138 case ACTRES_CONVERT:
8139 case ACTRES_BASE:
8140 case ACTRES_MINE:
8141 case ACTRES_IRRIGATE:
8142 case ACTRES_TRANSPORT_ALIGHT:
8143 case ACTRES_TRANSPORT_UNLOAD:
8144 case ACTRES_TRANSPORT_DISEMBARK:
8145 case ACTRES_TRANSPORT_BOARD:
8146 case ACTRES_TRANSPORT_EMBARK:
8147 case ACTRES_SPY_ATTACK:
8148 case ACTRES_SPY_SPREAD_PLAGUE:
8149 case ACTRES_CONQUER_EXTRAS:
8150 case ACTRES_HUT_ENTER:
8151 case ACTRES_HUT_FRIGHTEN:
8152 case ACTRES_UNIT_MOVE:
8153 /* Non ruleset defined action min range not supported here */
8154 fc_assert_msg(FALSE, "Probably wrong value.");
8156 case ACTRES_NUKE:
8157 case ACTRES_NUKE_UNITS:
8159 case ACTRES_NONE:
8161 }
8162
8163 fc_assert(action_result_is_valid(result) || result == ACTRES_NONE);
8164 return 0;
8165}
8166
8167/**********************************************************************/
8174{
8175 switch ((enum gen_action)act) {
8176 case ACTION_SPY_POISON:
8177 case ACTION_SPY_POISON_ESC:
8178 case ACTION_SPY_SABOTAGE_UNIT:
8179 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8180 case ACTION_SPY_BRIBE_UNIT:
8181 case ACTION_SPY_SABOTAGE_CITY:
8182 case ACTION_SPY_SABOTAGE_CITY_ESC:
8183 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8184 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8185 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8186 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8187 case ACTION_SPY_INCITE_CITY:
8188 case ACTION_SPY_INCITE_CITY_ESC:
8189 case ACTION_ESTABLISH_EMBASSY:
8190 case ACTION_ESTABLISH_EMBASSY_STAY:
8191 case ACTION_SPY_STEAL_TECH:
8192 case ACTION_SPY_STEAL_TECH_ESC:
8193 case ACTION_SPY_TARGETED_STEAL_TECH:
8194 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8195 case ACTION_SPY_INVESTIGATE_CITY:
8196 case ACTION_INV_CITY_SPEND:
8197 case ACTION_SPY_STEAL_GOLD:
8198 case ACTION_SPY_STEAL_GOLD_ESC:
8199 case ACTION_SPY_SPREAD_PLAGUE:
8200 case ACTION_STEAL_MAPS:
8201 case ACTION_STEAL_MAPS_ESC:
8202 case ACTION_TRADE_ROUTE:
8203 case ACTION_MARKETPLACE:
8204 case ACTION_CAPTURE_UNITS:
8205 case ACTION_EXPEL_UNIT:
8206 case ACTION_FOUND_CITY:
8207 case ACTION_JOIN_CITY:
8208 case ACTION_SPY_NUKE:
8209 case ACTION_SPY_NUKE_ESC:
8210 case ACTION_DESTROY_CITY:
8211 case ACTION_DISBAND_UNIT:
8212 case ACTION_HOME_CITY:
8213 case ACTION_HOMELESS:
8214 case ACTION_UPGRADE_UNIT:
8215 case ACTION_PARADROP:
8216 case ACTION_PARADROP_CONQUER:
8217 case ACTION_PARADROP_FRIGHTEN:
8218 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8219 case ACTION_PARADROP_ENTER:
8220 case ACTION_PARADROP_ENTER_CONQUER:
8221 case ACTION_ATTACK:
8222 case ACTION_SUICIDE_ATTACK:
8223 case ACTION_STRIKE_BUILDING:
8224 case ACTION_STRIKE_PRODUCTION:
8225 case ACTION_CONQUER_CITY:
8226 case ACTION_CONQUER_CITY2:
8227 case ACTION_CONQUER_CITY3:
8228 case ACTION_CONQUER_CITY4:
8229 case ACTION_HEAL_UNIT:
8230 case ACTION_HEAL_UNIT2:
8231 case ACTION_TRANSFORM_TERRAIN:
8232 case ACTION_CULTIVATE:
8233 case ACTION_PLANT:
8234 case ACTION_PILLAGE:
8235 case ACTION_CLEAN_POLLUTION:
8236 case ACTION_CLEAN_FALLOUT:
8237 case ACTION_FORTIFY:
8238 case ACTION_ROAD:
8239 case ACTION_CONVERT:
8240 case ACTION_BASE:
8241 case ACTION_MINE:
8242 case ACTION_IRRIGATE:
8243 case ACTION_TRANSPORT_ALIGHT:
8244 case ACTION_TRANSPORT_BOARD:
8245 case ACTION_TRANSPORT_EMBARK:
8246 case ACTION_TRANSPORT_EMBARK2:
8247 case ACTION_TRANSPORT_EMBARK3:
8248 case ACTION_TRANSPORT_UNLOAD:
8249 case ACTION_TRANSPORT_DISEMBARK1:
8250 case ACTION_TRANSPORT_DISEMBARK2:
8251 case ACTION_TRANSPORT_DISEMBARK3:
8252 case ACTION_TRANSPORT_DISEMBARK4:
8253 case ACTION_SPY_ATTACK:
8254 case ACTION_CONQUER_EXTRAS:
8255 case ACTION_CONQUER_EXTRAS2:
8256 case ACTION_CONQUER_EXTRAS3:
8257 case ACTION_CONQUER_EXTRAS4:
8258 case ACTION_HUT_ENTER:
8259 case ACTION_HUT_ENTER2:
8260 case ACTION_HUT_ENTER3:
8261 case ACTION_HUT_ENTER4:
8262 case ACTION_HUT_FRIGHTEN:
8263 case ACTION_HUT_FRIGHTEN2:
8264 case ACTION_HUT_FRIGHTEN3:
8265 case ACTION_HUT_FRIGHTEN4:
8266 case ACTION_UNIT_MOVE:
8267 case ACTION_UNIT_MOVE2:
8268 case ACTION_UNIT_MOVE3:
8269 /* Max range is not ruleset changeable */
8270 return NULL;
8271 case ACTION_HELP_WONDER:
8272 return "help_wonder_max_range";
8273 case ACTION_DISBAND_UNIT_RECOVER:
8274 return "disband_unit_recover_max_range";
8275 case ACTION_BOMBARD:
8276 return "bombard_max_range";
8277 case ACTION_BOMBARD2:
8278 return "bombard_2_max_range";
8279 case ACTION_BOMBARD3:
8280 return "bombard_3_max_range";
8281 case ACTION_NUKE:
8282 return "explode_nuclear_max_range";
8283 case ACTION_NUKE_CITY:
8284 return "nuke_city_max_range";
8285 case ACTION_NUKE_UNITS:
8286 return "nuke_units_max_range";
8287 case ACTION_AIRLIFT:
8288 return "airlift_max_range";
8289 case ACTION_USER_ACTION1:
8290 return "user_action_1_max_range";
8291 case ACTION_USER_ACTION2:
8292 return "user_action_2_max_range";
8293 case ACTION_USER_ACTION3:
8294 return "user_action_3_max_range";
8295 case ACTION_USER_ACTION4:
8296 return "user_action_4_max_range";
8297 case ACTION_COUNT:
8298 break;
8299 }
8300
8301 fc_assert(act >= 0 && act < ACTION_COUNT);
8302 return NULL;
8303}
8304
8305/**********************************************************************/
8308int action_max_range_default(enum action_result result)
8309{
8310 switch (result) {
8311 case ACTRES_ESTABLISH_EMBASSY:
8312 case ACTRES_SPY_INVESTIGATE_CITY:
8313 case ACTRES_SPY_POISON:
8314 case ACTRES_SPY_STEAL_GOLD:
8315 case ACTRES_SPY_SABOTAGE_CITY:
8316 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8317 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8318 case ACTRES_SPY_STEAL_TECH:
8319 case ACTRES_SPY_TARGETED_STEAL_TECH:
8320 case ACTRES_SPY_INCITE_CITY:
8321 case ACTRES_TRADE_ROUTE:
8322 case ACTRES_MARKETPLACE:
8323 case ACTRES_SPY_BRIBE_UNIT:
8324 case ACTRES_SPY_SABOTAGE_UNIT:
8325 case ACTRES_CAPTURE_UNITS:
8326 case ACTRES_FOUND_CITY:
8327 case ACTRES_JOIN_CITY:
8328 case ACTRES_STEAL_MAPS:
8329 case ACTRES_SPY_NUKE:
8330 case ACTRES_DESTROY_CITY:
8331 case ACTRES_EXPEL_UNIT:
8332 case ACTRES_DISBAND_UNIT:
8333 case ACTRES_HOME_CITY:
8334 case ACTRES_HOMELESS:
8335 case ACTRES_UPGRADE_UNIT:
8336 case ACTRES_PARADROP:
8337 case ACTRES_PARADROP_CONQUER:
8338 case ACTRES_STRIKE_BUILDING:
8339 case ACTRES_STRIKE_PRODUCTION:
8340 case ACTRES_ATTACK:
8341 case ACTRES_CONQUER_CITY:
8342 case ACTRES_HEAL_UNIT:
8343 case ACTRES_TRANSFORM_TERRAIN:
8344 case ACTRES_CULTIVATE:
8345 case ACTRES_PLANT:
8346 case ACTRES_PILLAGE:
8347 case ACTRES_CLEAN_POLLUTION:
8348 case ACTRES_CLEAN_FALLOUT:
8349 case ACTRES_FORTIFY:
8350 case ACTRES_ROAD:
8351 case ACTRES_CONVERT:
8352 case ACTRES_BASE:
8353 case ACTRES_MINE:
8354 case ACTRES_IRRIGATE:
8355 case ACTRES_TRANSPORT_ALIGHT:
8356 case ACTRES_TRANSPORT_UNLOAD:
8357 case ACTRES_TRANSPORT_DISEMBARK:
8358 case ACTRES_TRANSPORT_BOARD:
8359 case ACTRES_TRANSPORT_EMBARK:
8360 case ACTRES_SPY_ATTACK:
8361 case ACTRES_SPY_SPREAD_PLAGUE:
8362 case ACTRES_CONQUER_EXTRAS:
8363 case ACTRES_HUT_ENTER:
8364 case ACTRES_HUT_FRIGHTEN:
8365 case ACTRES_UNIT_MOVE:
8366 /* Non ruleset defined action max range not supported here */
8367 fc_assert_msg(FALSE, "Probably wrong value.");
8369 case ACTRES_HELP_WONDER:
8370 case ACTRES_DISBAND_UNIT_RECOVER:
8372 case ACTRES_BOMBARD:
8374 case ACTRES_NUKE:
8376 case ACTRES_NUKE_UNITS:
8378 case ACTRES_AIRLIFT:
8380 case ACTRES_NONE:
8382 }
8383
8384 fc_assert(action_result_is_valid(result) || result == ACTRES_NONE);
8385 return 0;
8386}
8387
8388/**********************************************************************/
8395{
8396 switch ((enum gen_action)act) {
8397 case ACTION_SPY_POISON:
8398 case ACTION_SPY_POISON_ESC:
8399 case ACTION_SPY_SABOTAGE_UNIT:
8400 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8401 case ACTION_SPY_BRIBE_UNIT:
8402 case ACTION_SPY_SABOTAGE_CITY:
8403 case ACTION_SPY_SABOTAGE_CITY_ESC:
8404 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8405 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8406 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8407 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8408 case ACTION_SPY_INCITE_CITY:
8409 case ACTION_SPY_INCITE_CITY_ESC:
8410 case ACTION_ESTABLISH_EMBASSY:
8411 case ACTION_ESTABLISH_EMBASSY_STAY:
8412 case ACTION_SPY_STEAL_TECH:
8413 case ACTION_SPY_STEAL_TECH_ESC:
8414 case ACTION_SPY_TARGETED_STEAL_TECH:
8415 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8416 case ACTION_SPY_INVESTIGATE_CITY:
8417 case ACTION_INV_CITY_SPEND:
8418 case ACTION_SPY_STEAL_GOLD:
8419 case ACTION_SPY_STEAL_GOLD_ESC:
8420 case ACTION_SPY_SPREAD_PLAGUE:
8421 case ACTION_STEAL_MAPS:
8422 case ACTION_STEAL_MAPS_ESC:
8423 case ACTION_TRADE_ROUTE:
8424 case ACTION_MARKETPLACE:
8425 case ACTION_HELP_WONDER:
8426 case ACTION_CAPTURE_UNITS:
8427 case ACTION_EXPEL_UNIT:
8428 case ACTION_FOUND_CITY:
8429 case ACTION_JOIN_CITY:
8430 case ACTION_SPY_NUKE:
8431 case ACTION_SPY_NUKE_ESC:
8432 case ACTION_NUKE_UNITS:
8433 case ACTION_DESTROY_CITY:
8434 case ACTION_DISBAND_UNIT_RECOVER:
8435 case ACTION_DISBAND_UNIT:
8436 case ACTION_HOME_CITY:
8437 case ACTION_HOMELESS:
8438 case ACTION_UPGRADE_UNIT:
8439 case ACTION_PARADROP:
8440 case ACTION_PARADROP_CONQUER:
8441 case ACTION_PARADROP_FRIGHTEN:
8442 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8443 case ACTION_PARADROP_ENTER:
8444 case ACTION_PARADROP_ENTER_CONQUER:
8445 case ACTION_AIRLIFT:
8446 case ACTION_ATTACK:
8447 case ACTION_SUICIDE_ATTACK:
8448 case ACTION_STRIKE_BUILDING:
8449 case ACTION_STRIKE_PRODUCTION:
8450 case ACTION_CONQUER_CITY:
8451 case ACTION_CONQUER_CITY2:
8452 case ACTION_CONQUER_CITY3:
8453 case ACTION_CONQUER_CITY4:
8454 case ACTION_HEAL_UNIT:
8455 case ACTION_HEAL_UNIT2:
8456 case ACTION_TRANSFORM_TERRAIN:
8457 case ACTION_CULTIVATE:
8458 case ACTION_PLANT:
8459 case ACTION_CLEAN_POLLUTION:
8460 case ACTION_CLEAN_FALLOUT:
8461 case ACTION_FORTIFY:
8462 case ACTION_ROAD:
8463 case ACTION_CONVERT:
8464 case ACTION_BASE:
8465 case ACTION_MINE:
8466 case ACTION_IRRIGATE:
8467 case ACTION_TRANSPORT_ALIGHT:
8468 case ACTION_TRANSPORT_BOARD:
8469 case ACTION_TRANSPORT_EMBARK:
8470 case ACTION_TRANSPORT_EMBARK2:
8471 case ACTION_TRANSPORT_EMBARK3:
8472 case ACTION_TRANSPORT_UNLOAD:
8473 case ACTION_TRANSPORT_DISEMBARK1:
8474 case ACTION_TRANSPORT_DISEMBARK2:
8475 case ACTION_TRANSPORT_DISEMBARK3:
8476 case ACTION_TRANSPORT_DISEMBARK4:
8477 case ACTION_BOMBARD:
8478 case ACTION_BOMBARD2:
8479 case ACTION_BOMBARD3:
8480 case ACTION_SPY_ATTACK:
8481 case ACTION_CONQUER_EXTRAS:
8482 case ACTION_CONQUER_EXTRAS2:
8483 case ACTION_CONQUER_EXTRAS3:
8484 case ACTION_CONQUER_EXTRAS4:
8485 case ACTION_HUT_ENTER:
8486 case ACTION_HUT_ENTER2:
8487 case ACTION_HUT_ENTER3:
8488 case ACTION_HUT_ENTER4:
8489 case ACTION_HUT_FRIGHTEN:
8490 case ACTION_HUT_FRIGHTEN2:
8491 case ACTION_HUT_FRIGHTEN3:
8492 case ACTION_HUT_FRIGHTEN4:
8493 case ACTION_UNIT_MOVE:
8494 case ACTION_UNIT_MOVE2:
8495 case ACTION_UNIT_MOVE3:
8496 /* Target kind is not ruleset changeable */
8497 return NULL;
8498 case ACTION_NUKE:
8499 return "explode_nuclear_target_kind";
8500 case ACTION_NUKE_CITY:
8501 return "nuke_city_target_kind";
8502 case ACTION_PILLAGE:
8503 return "pillage_target_kind";
8504 case ACTION_USER_ACTION1:
8505 return "user_action_1_target_kind";
8506 case ACTION_USER_ACTION2:
8507 return "user_action_2_target_kind";
8508 case ACTION_USER_ACTION3:
8509 return "user_action_3_target_kind";
8510 case ACTION_USER_ACTION4:
8511 return "user_action_4_target_kind";
8512 case ACTION_COUNT:
8513 break;
8514 }
8515
8516 fc_assert(act >= 0 && act < ACTION_COUNT);
8517 return NULL;
8518}
8519
8520/**********************************************************************/
8523enum action_target_kind
8525{
8526 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8528
8529 switch (result) {
8530 case ACTRES_ESTABLISH_EMBASSY:
8531 case ACTRES_SPY_INVESTIGATE_CITY:
8532 case ACTRES_SPY_POISON:
8533 case ACTRES_SPY_STEAL_GOLD:
8534 case ACTRES_SPY_SABOTAGE_CITY:
8535 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8536 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8537 case ACTRES_SPY_STEAL_TECH:
8538 case ACTRES_SPY_TARGETED_STEAL_TECH:
8539 case ACTRES_SPY_INCITE_CITY:
8540 case ACTRES_TRADE_ROUTE:
8541 case ACTRES_MARKETPLACE:
8542 case ACTRES_HELP_WONDER:
8543 case ACTRES_JOIN_CITY:
8544 case ACTRES_STEAL_MAPS:
8545 case ACTRES_SPY_NUKE:
8546 case ACTRES_DESTROY_CITY:
8547 case ACTRES_DISBAND_UNIT_RECOVER:
8548 case ACTRES_HOME_CITY:
8549 case ACTRES_UPGRADE_UNIT:
8550 case ACTRES_AIRLIFT:
8551 case ACTRES_STRIKE_BUILDING:
8552 case ACTRES_STRIKE_PRODUCTION:
8553 case ACTRES_CONQUER_CITY:
8554 case ACTRES_SPY_SPREAD_PLAGUE:
8555 return ATK_CITY;
8556 case ACTRES_SPY_BRIBE_UNIT:
8557 case ACTRES_SPY_SABOTAGE_UNIT:
8558 case ACTRES_EXPEL_UNIT:
8559 case ACTRES_HEAL_UNIT:
8560 case ACTRES_TRANSPORT_ALIGHT:
8561 case ACTRES_TRANSPORT_UNLOAD:
8562 case ACTRES_TRANSPORT_BOARD:
8563 case ACTRES_TRANSPORT_EMBARK:
8564 return ATK_UNIT;
8565 case ACTRES_BOMBARD:
8566 case ACTRES_ATTACK:
8567 case ACTRES_CAPTURE_UNITS:
8568 case ACTRES_NUKE_UNITS:
8569 case ACTRES_SPY_ATTACK:
8570 return ATK_UNITS;
8571 case ACTRES_FOUND_CITY:
8572 case ACTRES_NUKE:
8573 case ACTRES_PARADROP:
8574 case ACTRES_PARADROP_CONQUER:
8575 case ACTRES_TRANSFORM_TERRAIN:
8576 case ACTRES_CULTIVATE:
8577 case ACTRES_PLANT:
8578 case ACTRES_PILLAGE:
8579 case ACTRES_CLEAN_POLLUTION:
8580 case ACTRES_CLEAN_FALLOUT:
8581 case ACTRES_ROAD:
8582 case ACTRES_BASE:
8583 case ACTRES_MINE:
8584 case ACTRES_IRRIGATE:
8585 case ACTRES_TRANSPORT_DISEMBARK:
8586 case ACTRES_HUT_ENTER:
8587 case ACTRES_HUT_FRIGHTEN:
8588 case ACTRES_UNIT_MOVE:
8589 return ATK_TILE;
8590 case ACTRES_CONQUER_EXTRAS:
8591 return ATK_EXTRAS;
8592 case ACTRES_DISBAND_UNIT:
8593 case ACTRES_CONVERT:
8594 case ACTRES_FORTIFY:
8595 case ACTRES_HOMELESS:
8596 return ATK_SELF;
8597 case ACTRES_NONE:
8599 }
8600
8601 /* Should never be reached. */
8603}
8604
8605/**********************************************************************/
8610 enum action_target_kind tgt_kind)
8611{
8612 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8613 FALSE);
8614 fc_assert_ret_val(action_target_kind_is_valid(tgt_kind),
8615 FALSE);
8616
8617 switch (result) {
8618 case ACTRES_ESTABLISH_EMBASSY:
8619 case ACTRES_SPY_INVESTIGATE_CITY:
8620 case ACTRES_SPY_POISON:
8621 case ACTRES_SPY_STEAL_GOLD:
8622 case ACTRES_SPY_SABOTAGE_CITY:
8623 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8624 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8625 case ACTRES_SPY_STEAL_TECH:
8626 case ACTRES_SPY_TARGETED_STEAL_TECH:
8627 case ACTRES_SPY_INCITE_CITY:
8628 case ACTRES_TRADE_ROUTE:
8629 case ACTRES_MARKETPLACE:
8630 case ACTRES_HELP_WONDER:
8631 case ACTRES_JOIN_CITY:
8632 case ACTRES_STEAL_MAPS:
8633 case ACTRES_SPY_NUKE:
8634 case ACTRES_DESTROY_CITY:
8635 case ACTRES_DISBAND_UNIT_RECOVER:
8636 case ACTRES_HOME_CITY:
8637 case ACTRES_UPGRADE_UNIT:
8638 case ACTRES_AIRLIFT:
8639 case ACTRES_STRIKE_BUILDING:
8640 case ACTRES_STRIKE_PRODUCTION:
8641 case ACTRES_CONQUER_CITY:
8642 case ACTRES_SPY_SPREAD_PLAGUE:
8643 return tgt_kind == ATK_CITY;
8644 case ACTRES_SPY_BRIBE_UNIT:
8645 case ACTRES_SPY_SABOTAGE_UNIT:
8646 case ACTRES_EXPEL_UNIT:
8647 case ACTRES_HEAL_UNIT:
8648 case ACTRES_TRANSPORT_ALIGHT:
8649 case ACTRES_TRANSPORT_UNLOAD:
8650 case ACTRES_TRANSPORT_BOARD:
8651 case ACTRES_TRANSPORT_EMBARK:
8652 return tgt_kind == ATK_UNIT;
8653 case ACTRES_CAPTURE_UNITS:
8654 case ACTRES_BOMBARD:
8655 case ACTRES_NUKE_UNITS:
8656 case ACTRES_ATTACK:
8657 case ACTRES_SPY_ATTACK:
8658 return tgt_kind == ATK_UNITS;
8659 case ACTRES_FOUND_CITY:
8660 case ACTRES_PARADROP:
8661 case ACTRES_PARADROP_CONQUER:
8662 case ACTRES_TRANSFORM_TERRAIN:
8663 case ACTRES_CULTIVATE:
8664 case ACTRES_PLANT:
8665 case ACTRES_CLEAN_POLLUTION:
8666 case ACTRES_CLEAN_FALLOUT:
8667 case ACTRES_ROAD:
8668 case ACTRES_BASE:
8669 case ACTRES_MINE:
8670 case ACTRES_IRRIGATE:
8671 case ACTRES_TRANSPORT_DISEMBARK:
8672 case ACTRES_HUT_ENTER:
8673 case ACTRES_HUT_FRIGHTEN:
8674 case ACTRES_UNIT_MOVE:
8675 return tgt_kind == ATK_TILE;
8676 case ACTRES_CONQUER_EXTRAS:
8677 return tgt_kind == ATK_EXTRAS;
8678 case ACTRES_DISBAND_UNIT:
8679 case ACTRES_CONVERT:
8680 case ACTRES_FORTIFY:
8681 case ACTRES_HOMELESS:
8682 return tgt_kind == ATK_SELF;
8683 case ACTRES_PILLAGE:
8684 return (tgt_kind == ATK_TILE || tgt_kind == ATK_EXTRAS);
8685 case ACTRES_NUKE:
8686 return (tgt_kind == ATK_TILE || tgt_kind == ATK_CITY);
8687 case ACTRES_NONE:
8688 switch (tgt_kind) {
8689 case ATK_CITY:
8690 case ATK_UNIT:
8691 case ATK_UNITS:
8692 case ATK_TILE:
8693 case ATK_EXTRAS:
8694 case ATK_SELF:
8695 /* Works with all existing target kinds. */
8696 return TRUE;
8697 case ATK_COUNT:
8698 fc_assert_ret_val(tgt_kind != ATK_COUNT, FALSE);
8699 break;
8700 }
8701 break;
8702 }
8703
8704 /* Should never be reached. */
8705 return FALSE;
8706}
8707
8708/**********************************************************************/
8711static enum action_sub_target_kind
8713{
8714 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8715 ASTK_NONE);
8716
8717 switch (result) {
8718 case ACTRES_ESTABLISH_EMBASSY:
8719 case ACTRES_SPY_INVESTIGATE_CITY:
8720 case ACTRES_SPY_POISON:
8721 case ACTRES_SPY_STEAL_GOLD:
8722 case ACTRES_SPY_SABOTAGE_CITY:
8723 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8724 case ACTRES_SPY_STEAL_TECH:
8725 case ACTRES_SPY_INCITE_CITY:
8726 case ACTRES_TRADE_ROUTE:
8727 case ACTRES_MARKETPLACE:
8728 case ACTRES_HELP_WONDER:
8729 case ACTRES_JOIN_CITY:
8730 case ACTRES_STEAL_MAPS:
8731 case ACTRES_SPY_NUKE:
8732 case ACTRES_DESTROY_CITY:
8733 case ACTRES_DISBAND_UNIT_RECOVER:
8734 case ACTRES_HOME_CITY:
8735 case ACTRES_HOMELESS:
8736 case ACTRES_UPGRADE_UNIT:
8737 case ACTRES_AIRLIFT:
8738 case ACTRES_STRIKE_PRODUCTION:
8739 case ACTRES_CONQUER_CITY:
8740 case ACTRES_SPY_SPREAD_PLAGUE:
8741 return ASTK_NONE;
8742 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8743 case ACTRES_STRIKE_BUILDING:
8744 return ASTK_BUILDING;
8745 case ACTRES_SPY_TARGETED_STEAL_TECH:
8746 return ASTK_TECH;
8747 case ACTRES_SPY_BRIBE_UNIT:
8748 case ACTRES_SPY_SABOTAGE_UNIT:
8749 case ACTRES_EXPEL_UNIT:
8750 case ACTRES_HEAL_UNIT:
8751 case ACTRES_TRANSPORT_ALIGHT:
8752 case ACTRES_TRANSPORT_UNLOAD:
8753 case ACTRES_TRANSPORT_BOARD:
8754 case ACTRES_TRANSPORT_EMBARK:
8755 return ASTK_NONE;
8756 case ACTRES_CAPTURE_UNITS:
8757 case ACTRES_BOMBARD:
8758 case ACTRES_NUKE_UNITS:
8759 case ACTRES_ATTACK:
8760 case ACTRES_SPY_ATTACK:
8761 return ASTK_NONE;
8762 case ACTRES_FOUND_CITY:
8763 case ACTRES_NUKE:
8764 case ACTRES_PARADROP:
8765 case ACTRES_PARADROP_CONQUER:
8766 case ACTRES_TRANSFORM_TERRAIN:
8767 case ACTRES_CULTIVATE:
8768 case ACTRES_PLANT:
8769 case ACTRES_TRANSPORT_DISEMBARK:
8770 case ACTRES_HUT_ENTER:
8771 case ACTRES_HUT_FRIGHTEN:
8772 case ACTRES_UNIT_MOVE:
8773 return ASTK_NONE;
8774 case ACTRES_PILLAGE:
8775 case ACTRES_CLEAN_POLLUTION:
8776 case ACTRES_CLEAN_FALLOUT:
8777 return ASTK_EXTRA;
8778 case ACTRES_ROAD:
8779 case ACTRES_BASE:
8780 case ACTRES_MINE:
8781 case ACTRES_IRRIGATE:
8782 return ASTK_EXTRA_NOT_THERE;
8783 case ACTRES_CONQUER_EXTRAS:
8784 return ASTK_NONE;
8785 case ACTRES_DISBAND_UNIT:
8786 case ACTRES_CONVERT:
8787 case ACTRES_FORTIFY:
8788 return ASTK_NONE;
8789 case ACTRES_NONE:
8790 return ASTK_NONE;
8791 }
8792
8793 /* Should never be reached. */
8794 return ASTK_NONE;
8795}
8796
8797/**********************************************************************/
8801static enum act_tgt_compl
8803 enum action_target_kind tgt_kind,
8804 enum action_sub_target_kind sub_tgt_kind)
8805{
8806 fc_assert_ret_val(action_result_is_valid(result) || result == ACTRES_NONE,
8807 ACT_TGT_COMPL_SIMPLE);
8808
8809 switch (result) {
8810 case ACTRES_ESTABLISH_EMBASSY:
8811 case ACTRES_SPY_INVESTIGATE_CITY:
8812 case ACTRES_SPY_POISON:
8813 case ACTRES_SPY_STEAL_GOLD:
8814 case ACTRES_SPY_SABOTAGE_CITY:
8815 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
8816 case ACTRES_SPY_STEAL_TECH:
8817 case ACTRES_SPY_INCITE_CITY:
8818 case ACTRES_TRADE_ROUTE:
8819 case ACTRES_MARKETPLACE:
8820 case ACTRES_HELP_WONDER:
8821 case ACTRES_JOIN_CITY:
8822 case ACTRES_STEAL_MAPS:
8823 case ACTRES_SPY_NUKE:
8824 case ACTRES_DESTROY_CITY:
8825 case ACTRES_DISBAND_UNIT_RECOVER:
8826 case ACTRES_HOME_CITY:
8827 case ACTRES_HOMELESS:
8828 case ACTRES_UPGRADE_UNIT:
8829 case ACTRES_AIRLIFT:
8830 case ACTRES_STRIKE_PRODUCTION:
8831 case ACTRES_CONQUER_CITY:
8832 case ACTRES_SPY_SPREAD_PLAGUE:
8833 return ACT_TGT_COMPL_SIMPLE;
8834 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
8835 case ACTRES_STRIKE_BUILDING:
8836 case ACTRES_SPY_TARGETED_STEAL_TECH:
8837 return ACT_TGT_COMPL_MANDATORY;
8838 case ACTRES_SPY_BRIBE_UNIT:
8839 case ACTRES_SPY_SABOTAGE_UNIT:
8840 case ACTRES_EXPEL_UNIT:
8841 case ACTRES_HEAL_UNIT:
8842 case ACTRES_TRANSPORT_ALIGHT:
8843 case ACTRES_TRANSPORT_UNLOAD:
8844 case ACTRES_TRANSPORT_BOARD:
8845 case ACTRES_TRANSPORT_EMBARK:
8846 return ACT_TGT_COMPL_SIMPLE;
8847 case ACTRES_CAPTURE_UNITS:
8848 case ACTRES_BOMBARD:
8849 case ACTRES_NUKE_UNITS:
8850 case ACTRES_ATTACK:
8851 case ACTRES_SPY_ATTACK:
8852 return ACT_TGT_COMPL_SIMPLE;
8853 case ACTRES_FOUND_CITY:
8854 case ACTRES_NUKE:
8855 case ACTRES_PARADROP:
8856 case ACTRES_PARADROP_CONQUER:
8857 case ACTRES_TRANSFORM_TERRAIN:
8858 case ACTRES_CULTIVATE:
8859 case ACTRES_PLANT:
8860 case ACTRES_TRANSPORT_DISEMBARK:
8861 case ACTRES_HUT_ENTER:
8862 case ACTRES_HUT_FRIGHTEN:
8863 case ACTRES_UNIT_MOVE:
8864 return ACT_TGT_COMPL_SIMPLE;
8865 case ACTRES_PILLAGE:
8866 case ACTRES_CLEAN_POLLUTION:
8867 case ACTRES_CLEAN_FALLOUT:
8868 return ACT_TGT_COMPL_FLEXIBLE;
8869 case ACTRES_ROAD:
8870 case ACTRES_BASE:
8871 case ACTRES_MINE:
8872 case ACTRES_IRRIGATE:
8873 return ACT_TGT_COMPL_MANDATORY;
8874 case ACTRES_CONQUER_EXTRAS:
8875 return ACT_TGT_COMPL_SIMPLE;
8876 case ACTRES_DISBAND_UNIT:
8877 case ACTRES_CONVERT:
8878 case ACTRES_FORTIFY:
8879 return ACT_TGT_COMPL_SIMPLE;
8880 case ACTRES_NONE:
8881 return ACT_TGT_COMPL_SIMPLE;
8882 }
8883
8884 /* Should never be reached. */
8885 return ACT_TGT_COMPL_SIMPLE;
8886}
8887
8888/**********************************************************************/
8896{
8897 switch ((enum gen_action)act) {
8898 case ACTION_SPY_POISON:
8899 case ACTION_SPY_POISON_ESC:
8900 case ACTION_SPY_SABOTAGE_UNIT:
8901 case ACTION_SPY_SABOTAGE_UNIT_ESC:
8902 case ACTION_SPY_BRIBE_UNIT:
8903 case ACTION_SPY_SABOTAGE_CITY:
8904 case ACTION_SPY_SABOTAGE_CITY_ESC:
8905 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
8906 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
8907 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
8908 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
8909 case ACTION_SPY_INCITE_CITY:
8910 case ACTION_SPY_INCITE_CITY_ESC:
8911 case ACTION_ESTABLISH_EMBASSY:
8912 case ACTION_ESTABLISH_EMBASSY_STAY:
8913 case ACTION_SPY_STEAL_TECH:
8914 case ACTION_SPY_STEAL_TECH_ESC:
8915 case ACTION_SPY_TARGETED_STEAL_TECH:
8916 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
8917 case ACTION_SPY_INVESTIGATE_CITY:
8918 case ACTION_INV_CITY_SPEND:
8919 case ACTION_SPY_STEAL_GOLD:
8920 case ACTION_SPY_STEAL_GOLD_ESC:
8921 case ACTION_STEAL_MAPS:
8922 case ACTION_STEAL_MAPS_ESC:
8923 case ACTION_TRADE_ROUTE:
8924 case ACTION_MARKETPLACE:
8925 case ACTION_HELP_WONDER:
8926 case ACTION_CAPTURE_UNITS:
8927 case ACTION_EXPEL_UNIT:
8928 case ACTION_JOIN_CITY:
8929 case ACTION_SPY_NUKE:
8930 case ACTION_SPY_NUKE_ESC:
8931 case ACTION_DESTROY_CITY:
8932 case ACTION_DISBAND_UNIT_RECOVER:
8933 case ACTION_DISBAND_UNIT:
8934 case ACTION_HOME_CITY:
8935 case ACTION_HOMELESS:
8936 case ACTION_UPGRADE_UNIT:
8937 case ACTION_PARADROP:
8938 case ACTION_PARADROP_CONQUER:
8939 case ACTION_PARADROP_FRIGHTEN:
8940 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8941 case ACTION_PARADROP_ENTER:
8942 case ACTION_PARADROP_ENTER_CONQUER:
8943 case ACTION_AIRLIFT:
8944 case ACTION_ATTACK:
8945 case ACTION_SUICIDE_ATTACK:
8946 case ACTION_STRIKE_BUILDING:
8947 case ACTION_STRIKE_PRODUCTION:
8948 case ACTION_CONQUER_CITY:
8949 case ACTION_CONQUER_CITY2:
8950 case ACTION_CONQUER_CITY3:
8951 case ACTION_CONQUER_CITY4:
8952 case ACTION_HEAL_UNIT:
8953 case ACTION_HEAL_UNIT2:
8954 case ACTION_TRANSFORM_TERRAIN:
8955 case ACTION_CULTIVATE:
8956 case ACTION_PLANT:
8957 case ACTION_PILLAGE:
8958 case ACTION_CLEAN_POLLUTION:
8959 case ACTION_CLEAN_FALLOUT:
8960 case ACTION_FORTIFY:
8961 case ACTION_ROAD:
8962 case ACTION_CONVERT:
8963 case ACTION_BASE:
8964 case ACTION_MINE:
8965 case ACTION_IRRIGATE:
8966 case ACTION_TRANSPORT_ALIGHT:
8967 case ACTION_TRANSPORT_BOARD:
8968 case ACTION_TRANSPORT_EMBARK:
8969 case ACTION_TRANSPORT_EMBARK2:
8970 case ACTION_TRANSPORT_EMBARK3:
8971 case ACTION_TRANSPORT_UNLOAD:
8972 case ACTION_TRANSPORT_DISEMBARK1:
8973 case ACTION_TRANSPORT_DISEMBARK2:
8974 case ACTION_TRANSPORT_DISEMBARK3:
8975 case ACTION_TRANSPORT_DISEMBARK4:
8976 case ACTION_BOMBARD:
8977 case ACTION_BOMBARD2:
8978 case ACTION_BOMBARD3:
8979 case ACTION_SPY_ATTACK:
8980 case ACTION_CONQUER_EXTRAS:
8981 case ACTION_CONQUER_EXTRAS2:
8982 case ACTION_CONQUER_EXTRAS3:
8983 case ACTION_CONQUER_EXTRAS4:
8984 case ACTION_HUT_ENTER:
8985 case ACTION_HUT_ENTER2:
8986 case ACTION_HUT_ENTER3:
8987 case ACTION_HUT_ENTER4:
8988 case ACTION_HUT_FRIGHTEN:
8989 case ACTION_HUT_FRIGHTEN2:
8990 case ACTION_HUT_FRIGHTEN3:
8991 case ACTION_HUT_FRIGHTEN4:
8992 case ACTION_UNIT_MOVE:
8993 case ACTION_UNIT_MOVE2:
8994 case ACTION_UNIT_MOVE3:
8995 /* actor consuming always is not ruleset changeable */
8996 return NULL;
8997 case ACTION_FOUND_CITY:
8998 return "found_city_consuming_always";
8999 case ACTION_NUKE:
9000 return "explode_nuclear_consuming_always";
9001 case ACTION_NUKE_CITY:
9002 return "nuke_city_consuming_always";
9003 case ACTION_NUKE_UNITS:
9004 return "nuke_units_consuming_always";
9005 case ACTION_SPY_SPREAD_PLAGUE:
9006 return "spread_plague_actor_consuming_always";
9007 case ACTION_USER_ACTION1:
9008 return "user_action_1_actor_consuming_always";
9009 case ACTION_USER_ACTION2:
9010 return "user_action_2_actor_consuming_always";
9011 case ACTION_USER_ACTION3:
9012 return "user_action_3_actor_consuming_always";
9013 case ACTION_USER_ACTION4:
9014 return "user_action_4_actor_consuming_always";
9015 case ACTION_COUNT:
9016 break;
9017 }
9018
9019 fc_assert(act >= 0 && act < ACTION_COUNT);
9020 return NULL;
9021}
9022
9023/**********************************************************************/
9030const char *action_blocked_by_ruleset_var_name(const struct action *act)
9031{
9032 fc_assert_ret_val(act != NULL, NULL);
9033
9034 switch ((enum gen_action)action_number(act)) {
9035 case ACTION_MARKETPLACE:
9036 return "enter_marketplace_blocked_by";
9037 case ACTION_BOMBARD:
9038 return "bombard_blocked_by";
9039 case ACTION_BOMBARD2:
9040 return "bombard_2_blocked_by";
9041 case ACTION_BOMBARD3:
9042 return "bombard_3_blocked_by";
9043 case ACTION_NUKE:
9044 return "explode_nuclear_blocked_by";
9045 case ACTION_NUKE_CITY:
9046 return "nuke_city_blocked_by";
9047 case ACTION_NUKE_UNITS:
9048 return "nuke_units_blocked_by";
9049 case ACTION_ATTACK:
9050 return "attack_blocked_by";
9051 case ACTION_SUICIDE_ATTACK:
9052 return "suicide_attack_blocked_by";
9053 case ACTION_CONQUER_CITY:
9054 return "conquer_city_blocked_by";
9055 case ACTION_CONQUER_CITY2:
9056 return "conquer_city_2_blocked_by";
9057 case ACTION_CONQUER_CITY3:
9058 return "conquer_city_3_blocked_by";
9059 case ACTION_CONQUER_CITY4:
9060 return "conquer_city_4_blocked_by";
9061 case ACTION_UNIT_MOVE:
9062 return "move_blocked_by";
9063 case ACTION_UNIT_MOVE2:
9064 return "move_2_blocked_by";
9065 case ACTION_UNIT_MOVE3:
9066 return "move_3_blocked_by";
9067 case ACTION_SPY_POISON:
9068 case ACTION_SPY_POISON_ESC:
9069 case ACTION_SPY_SABOTAGE_UNIT:
9070 case ACTION_SPY_SABOTAGE_UNIT_ESC:
9071 case ACTION_SPY_BRIBE_UNIT:
9072 case ACTION_SPY_SABOTAGE_CITY:
9073 case ACTION_SPY_SABOTAGE_CITY_ESC:
9074 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
9075 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
9076 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
9077 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
9078 case ACTION_SPY_INCITE_CITY:
9079 case ACTION_SPY_INCITE_CITY_ESC:
9080 case ACTION_ESTABLISH_EMBASSY:
9081 case ACTION_ESTABLISH_EMBASSY_STAY:
9082 case ACTION_SPY_STEAL_TECH:
9083 case ACTION_SPY_STEAL_TECH_ESC:
9084 case ACTION_SPY_TARGETED_STEAL_TECH:
9085 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
9086 case ACTION_SPY_INVESTIGATE_CITY:
9087 case ACTION_INV_CITY_SPEND:
9088 case ACTION_SPY_STEAL_GOLD:
9089 case ACTION_SPY_STEAL_GOLD_ESC:
9090 case ACTION_STEAL_MAPS:
9091 case ACTION_STEAL_MAPS_ESC:
9092 case ACTION_TRADE_ROUTE:
9093 case ACTION_HELP_WONDER:
9094 case ACTION_CAPTURE_UNITS:
9095 case ACTION_EXPEL_UNIT:
9096 case ACTION_FOUND_CITY:
9097 case ACTION_JOIN_CITY:
9098 case ACTION_SPY_NUKE:
9099 case ACTION_SPY_NUKE_ESC:
9100 case ACTION_DESTROY_CITY:
9101 case ACTION_DISBAND_UNIT_RECOVER:
9102 case ACTION_DISBAND_UNIT:
9103 case ACTION_HOME_CITY:
9104 case ACTION_HOMELESS:
9105 case ACTION_UPGRADE_UNIT:
9106 case ACTION_PARADROP:
9107 case ACTION_PARADROP_CONQUER:
9108 case ACTION_PARADROP_FRIGHTEN:
9109 case ACTION_PARADROP_FRIGHTEN_CONQUER:
9110 case ACTION_PARADROP_ENTER:
9111 case ACTION_PARADROP_ENTER_CONQUER:
9112 case ACTION_AIRLIFT:
9113 case ACTION_STRIKE_BUILDING:
9114 case ACTION_STRIKE_PRODUCTION:
9115 case ACTION_HEAL_UNIT:
9116 case ACTION_HEAL_UNIT2:
9117 case ACTION_TRANSFORM_TERRAIN:
9118 case ACTION_CULTIVATE:
9119 case ACTION_PLANT:
9120 case ACTION_PILLAGE:
9121 case ACTION_CLEAN_POLLUTION:
9122 case ACTION_CLEAN_FALLOUT:
9123 case ACTION_FORTIFY:
9124 case ACTION_ROAD:
9125 case ACTION_CONVERT:
9126 case ACTION_BASE:
9127 case ACTION_MINE:
9128 case ACTION_IRRIGATE:
9129 case ACTION_TRANSPORT_ALIGHT:
9130 case ACTION_TRANSPORT_BOARD:
9131 case ACTION_TRANSPORT_EMBARK:
9132 case ACTION_TRANSPORT_EMBARK2:
9133 case ACTION_TRANSPORT_EMBARK3:
9134 case ACTION_TRANSPORT_UNLOAD:
9135 case ACTION_TRANSPORT_DISEMBARK1:
9136 case ACTION_TRANSPORT_DISEMBARK2:
9137 case ACTION_TRANSPORT_DISEMBARK3:
9138 case ACTION_TRANSPORT_DISEMBARK4:
9139 case ACTION_SPY_SPREAD_PLAGUE:
9140 case ACTION_SPY_ATTACK:
9141 case ACTION_CONQUER_EXTRAS:
9142 case ACTION_CONQUER_EXTRAS2:
9143 case ACTION_CONQUER_EXTRAS3:
9144 case ACTION_CONQUER_EXTRAS4:
9145 case ACTION_HUT_ENTER:
9146 case ACTION_HUT_ENTER2:
9147 case ACTION_HUT_ENTER3:
9148 case ACTION_HUT_ENTER4:
9149 case ACTION_HUT_FRIGHTEN:
9150 case ACTION_HUT_FRIGHTEN2:
9151 case ACTION_HUT_FRIGHTEN3:
9152 case ACTION_HUT_FRIGHTEN4:
9153 case ACTION_USER_ACTION1:
9154 case ACTION_USER_ACTION2:
9155 case ACTION_USER_ACTION3:
9156 case ACTION_USER_ACTION4:
9157 /* blocked_by is not ruleset changeable */
9158 return NULL;
9159 case ACTION_COUNT:
9160 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
9161 break;
9162 }
9163
9164 return NULL;
9165}
9166
9167/**********************************************************************/
9171const char *
9173{
9174 fc_assert_ret_val(act != NULL, NULL);
9175
9176 if (!(action_has_result(act, ACTRES_SPY_BRIBE_UNIT)
9177 ||action_has_result(act, ACTRES_ATTACK))) {
9178 /* No support in the action performer function */
9179 return NULL;
9180 }
9181
9182 switch ((enum gen_action)action_number(act)) {
9183 case ACTION_SPY_BRIBE_UNIT:
9184 return "bribe_unit_post_success_forced_actions";
9185 case ACTION_ATTACK:
9186 return "attack_post_success_forced_actions";
9187 case ACTION_MARKETPLACE:
9188 case ACTION_BOMBARD:
9189 case ACTION_BOMBARD2:
9190 case ACTION_BOMBARD3:
9191 case ACTION_NUKE:
9192 case ACTION_NUKE_CITY:
9193 case ACTION_NUKE_UNITS:
9194 case ACTION_SUICIDE_ATTACK:
9195 case ACTION_CONQUER_CITY:
9196 case ACTION_CONQUER_CITY2:
9197 case ACTION_CONQUER_CITY3:
9198 case ACTION_CONQUER_CITY4:
9199 case ACTION_SPY_POISON:
9200 case ACTION_SPY_POISON_ESC:
9201 case ACTION_SPY_SABOTAGE_UNIT:
9202 case ACTION_SPY_SABOTAGE_UNIT_ESC:
9203 case ACTION_SPY_SABOTAGE_CITY:
9204 case ACTION_SPY_SABOTAGE_CITY_ESC:
9205 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
9206 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
9207 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
9208 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
9209 case ACTION_SPY_INCITE_CITY:
9210 case ACTION_SPY_INCITE_CITY_ESC:
9211 case ACTION_ESTABLISH_EMBASSY:
9212 case ACTION_ESTABLISH_EMBASSY_STAY:
9213 case ACTION_SPY_STEAL_TECH:
9214 case ACTION_SPY_STEAL_TECH_ESC:
9215 case ACTION_SPY_TARGETED_STEAL_TECH:
9216 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
9217 case ACTION_SPY_INVESTIGATE_CITY:
9218 case ACTION_INV_CITY_SPEND:
9219 case ACTION_SPY_STEAL_GOLD:
9220 case ACTION_SPY_STEAL_GOLD_ESC:
9221 case ACTION_STEAL_MAPS:
9222 case ACTION_STEAL_MAPS_ESC:
9223 case ACTION_TRADE_ROUTE:
9224 case ACTION_HELP_WONDER:
9225 case ACTION_CAPTURE_UNITS:
9226 case ACTION_EXPEL_UNIT:
9227 case ACTION_FOUND_CITY:
9228 case ACTION_JOIN_CITY:
9229 case ACTION_SPY_NUKE:
9230 case ACTION_SPY_NUKE_ESC:
9231 case ACTION_DESTROY_CITY:
9232 case ACTION_DISBAND_UNIT_RECOVER:
9233 case ACTION_DISBAND_UNIT:
9234 case ACTION_HOME_CITY:
9235 case ACTION_HOMELESS:
9236 case ACTION_UPGRADE_UNIT:
9237 case ACTION_PARADROP:
9238 case ACTION_PARADROP_CONQUER:
9239 case ACTION_PARADROP_FRIGHTEN:
9240 case ACTION_PARADROP_FRIGHTEN_CONQUER:
9241 case ACTION_PARADROP_ENTER:
9242 case ACTION_PARADROP_ENTER_CONQUER:
9243 case ACTION_AIRLIFT:
9244 case ACTION_STRIKE_BUILDING:
9245 case ACTION_STRIKE_PRODUCTION:
9246 case ACTION_HEAL_UNIT:
9247 case ACTION_HEAL_UNIT2:
9248 case ACTION_TRANSFORM_TERRAIN:
9249 case ACTION_CULTIVATE:
9250 case ACTION_PLANT:
9251 case ACTION_PILLAGE:
9252 case ACTION_CLEAN_POLLUTION:
9253 case ACTION_CLEAN_FALLOUT:
9254 case ACTION_FORTIFY:
9255 case ACTION_ROAD:
9256 case ACTION_CONVERT:
9257 case ACTION_BASE:
9258 case ACTION_MINE:
9259 case ACTION_IRRIGATE:
9260 case ACTION_TRANSPORT_ALIGHT:
9261 case ACTION_TRANSPORT_BOARD:
9262 case ACTION_TRANSPORT_EMBARK:
9263 case ACTION_TRANSPORT_EMBARK2:
9264 case ACTION_TRANSPORT_EMBARK3:
9265 case ACTION_TRANSPORT_UNLOAD:
9266 case ACTION_TRANSPORT_DISEMBARK1:
9267 case ACTION_TRANSPORT_DISEMBARK2:
9268 case ACTION_TRANSPORT_DISEMBARK3:
9269 case ACTION_TRANSPORT_DISEMBARK4:
9270 case ACTION_SPY_SPREAD_PLAGUE:
9271 case ACTION_SPY_ATTACK:
9272 case ACTION_CONQUER_EXTRAS:
9273 case ACTION_CONQUER_EXTRAS2:
9274 case ACTION_CONQUER_EXTRAS3:
9275 case ACTION_CONQUER_EXTRAS4:
9276 case ACTION_HUT_ENTER:
9277 case ACTION_HUT_ENTER2:
9278 case ACTION_HUT_ENTER3:
9279 case ACTION_HUT_ENTER4:
9280 case ACTION_HUT_FRIGHTEN:
9281 case ACTION_HUT_FRIGHTEN2:
9282 case ACTION_HUT_FRIGHTEN3:
9283 case ACTION_HUT_FRIGHTEN4:
9284 case ACTION_UNIT_MOVE:
9285 case ACTION_UNIT_MOVE2:
9286 case ACTION_UNIT_MOVE3:
9287 case ACTION_USER_ACTION1:
9288 case ACTION_USER_ACTION2:
9289 case ACTION_USER_ACTION3:
9290 case ACTION_USER_ACTION4:
9291 /* not ruleset changeable */
9292 return NULL;
9293 case ACTION_COUNT:
9294 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
9295 break;
9296 }
9297
9298 return NULL;
9299}
9300
9301/**********************************************************************/
9306{
9307 return action_enabler_list_size(action_enablers_for_action(action)) > 0;
9308}
9309
9310/**********************************************************************/
9313const char *gen_action_name_update_cb(const char *old_name)
9314{
9315 if (is_ruleset_compat_mode()) {
9316 if (!strcasecmp("Recycle Unit", old_name)) {
9317 return "Disband Unit Recover";
9318 }
9319 }
9320
9321 return old_name;
9322}
9323
9324const char *atk_helpnames[ATK_COUNT] =
9325{
9326 N_("individual cities"), /* ATK_CITY */
9327 N_("individual units"), /* ATK_UNIT */
9328 N_("unit stacks"), /* ATK_UNITS */
9329 N_("tiles"), /* ATK_TILE */
9330 N_("tile extras"), /* ATK_EXTRAS */
9331 N_("itself") /* ATK_SELF */
9332};
9333
9334/**********************************************************************/
9338const char *action_target_kind_help(enum action_target_kind kind)
9339{
9340 fc_assert(kind >= 0 && kind < ATK_COUNT);
9341
9342 return _(atk_helpnames[kind]);
9343}
9344
9345/************************************************************************/
9348struct action_list *action_list_by_result(enum action_result result)
9349{
9350 fc_assert(result < ACTRES_LAST);
9351
9352 return actlist_by_result[result];
9353}
9354
9355/************************************************************************/
9358struct action_list *action_list_by_activity(enum unit_activity activity)
9359{
9360 fc_assert(activity < ACTIVITY_LAST);
9361
9362 return actlist_by_activity[activity];
9363}
bool action_removes_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2312
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:7142
static struct action * actions[MAX_NUM_ACTIONS]
Definition actions.c:96
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
const char * action_name_translation(const struct action *action)
Definition actions.c:1890
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1833
static void oblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:247
struct act_prob action_speculate_unit_on_extras(const struct civ_map *nmap, 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:6591
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
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:208
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:2083
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:7220
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
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
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
bool action_prob_certain(const struct act_prob probability)
Definition actions.c:6713
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:7349
req_vec_num_in_item action_enabler_vector_number(const void *enabler, const struct requirement_vector *vec)
Definition actions.c:2968
bool action_has_complex_target(const struct action *paction)
Definition actions.c:1792
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
static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE]
Definition actions.c:104
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2838
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
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6703
#define ACTPROB_VAL_NOT_IMPL
Definition actions.c:94
struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS]
Definition actions.c:98
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3520
struct act_prob action_prob_new_not_impl(void)
Definition actions.c:6682
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2904
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
void actions_rs_pre_san_gen(void)
Definition actions.c:1520
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:7962
struct act_prob action_speculate_unit_on_self(const struct civ_map *nmap, action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat)
Definition actions.c:6625
void action_list_end(action_id *act_list, int size)
Definition actions.c:7397
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:9030
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
#define ACTPROB_VAL_MAX
Definition actions.c:88
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
struct req_vec_problem * action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
Definition actions.c:2598
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:7064
static struct ae_contra_or * req_contradiction_or(int alternatives,...)
Definition actions.c:160
struct act_prob action_prob_vs_tile(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6224
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
const char * atk_helpnames[ATK_COUNT]
Definition actions.c:9324
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
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
static void hard_code_actions(void)
Definition actions.c:914
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
bool action_is_in_use(struct action *paction)
Definition actions.c:7326
static struct req_vec_problem * enabler_tile_tgt_local_diplrel_implies_claimed(const struct action_enabler *enabler)
Definition actions.c:2693
bool action_ever_possible(action_id action)
Definition actions.c:9305
bool action_result_legal_target_kind(enum action_result result, enum action_target_kind tgt_kind)
Definition actions.c:8609
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:3015
bool are_action_probabilitys_equal(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6754
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:6324
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:9172
struct action * action_by_rule_name(const char *name)
Definition actions.c:1708
static bool action_has_possible_actor_hard_reqs(struct action *paction)
Definition actions.c:7301
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
enum action_battle_kind action_get_battle_kind(const struct action *pact)
Definition actions.c:1762
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1751
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
static bool action_prob_not_relevant(const struct act_prob probability)
Definition actions.c:6724
void actions_free(void)
Definition actions.c:1530
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
void action_enabler_free(struct action_enabler *enabler)
Definition actions.c:2415
static void ae_contra_close(struct ae_contra_or *contra)
Definition actions.c:189
struct act_prob action_speculate_unit_on_units(const struct civ_map *nmap, 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:6524
static enum fc_tristate tech_can_be_stolen(const struct player *actor_player, const struct player *target_player)
Definition actions.c:5239
static struct action_list * actlist_by_result[ACTRES_LAST]
Definition actions.c:146
static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT]
Definition actions.c:105
static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:336
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:9358
int action_number(const struct action *action)
Definition actions.c:1868
struct act_prob action_prob_new_unknown(void)
Definition actions.c:6692
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1856
#define ACTPROB_VAL_NA
Definition actions.c:92
static struct req_vec_problem * enabler_first_clarification(const struct action_enabler *enabler)
Definition actions.c:2886
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
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
static bool action_prob_not_impl(const struct act_prob probability)
Definition actions.c:6735
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
struct act_prob action_prob_and(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6841
static bool actions_initialized
Definition actions.c:99
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:8895
bool action_immune_government(struct government *gov, action_id act)
Definition actions.c:7101
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:294
static bool is_target_possible(const action_id wanted_action, const struct player *actor_player, const struct req_context *target)
Definition actions.c:7124
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
static struct act_prob ap_dipl_battle_win(const struct unit *pattacker, const struct unit *pdefender)
Definition actions.c:5275
struct act_prob action_prob_vs_extras(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6307
enum unit_activity actres_get_activity(enum action_result result)
Definition actions.c:2136
struct act_prob action_prob_new_certain(void)
Definition actions.c:6662
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:8173
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
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:6979
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:6377
struct act_prob action_prob_fall_back(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6911
#define obligatory_req_vector_iterate_end
Definition actions.c:76
static const struct unit_type * tgt_city_local_utype(const struct city *target_city)
Definition actions.c:3077
static struct requirement * req_vec_first_local_diplrel(const struct requirement_vector *vec)
Definition actions.c:2649
enum action_target_kind action_target_kind_default(enum action_result result)
Definition actions.c:8524
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:6158
static bool plr_sees_tile(const struct player *plr, const struct tile *ttile)
Definition actions.c:3042
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
struct act_prob action_prob_vs_units(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:6141
struct action_list * action_list_by_result(enum action_result result)
Definition actions.c:9348
void action_list_add_all_by_result(action_id *act_list, int *position, enum action_result result)
Definition actions.c:7414
bool action_univs_not_blocking(const struct action *paction, struct universal *actor_uni, struct universal *target_uni)
Definition actions.c:7373
struct act_prob action_speculate_unit_on_city(const struct civ_map *nmap, 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:6456
static struct requirement * req_vec_first_contradiction_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition actions.c:2670
bool actions_are_ready(void)
Definition actions.c:1583
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
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:8802
int action_min_range_default(enum action_result result)
Definition actions.c:8091
struct act_prob action_speculate_unit_on_tile(const struct civ_map *nmap, 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:6557
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
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:8394
#define obligatory_req_vector_iterate(obreq_vec, pobreq)
Definition actions.c:74
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
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:7165
struct action * action_is_blocked_by(const struct civ_map *nmap, 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
static bool is_enabler_active(const struct action_enabler *enabler, const struct req_context *actor, const struct req_context *target)
Definition actions.c:4632
static struct action_enabler_list * action_enablers_by_action[MAX_NUM_ACTIONS]
Definition actions.c:101
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2442
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
static void hard_code_oblig_hard_reqs(void)
Definition actions.c:354
const char * action_ui_name_default(int act)
Definition actions.c:7660
#define ACTPROB_VAL_1_PCT
Definition actions.c:90
bool action_enabler_utype_possible_actor(const struct action_enabler *ae, const struct unit_type *act_utype)
Definition actions.c:7243
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
struct action_enabler * action_enabler_new(void)
Definition actions.c:2396
bool action_requires_details(const struct action *paction)
Definition actions.c:1805
struct act_prob action_prob_new_not_relevant(void)
Definition actions.c:6672
const char * action_target_kind_help(enum action_target_kind kind)
Definition actions.c:9338
static struct req_vec_problem * enabler_first_self_contradiction(const struct action_enabler *enabler)
Definition actions.c:2766
int action_get_role(const struct action *paction)
Definition actions.c:2123
struct act_prob action_speculate_unit_on_unit(const struct civ_map *nmap, 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:6491
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
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:7365
struct act_prob action_prob_new_impossible(void)
Definition actions.c:6652
bool action_enabler_possible_actor(const struct action_enabler *ae)
Definition actions.c:7270
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
struct action ** _actions
Definition actions.c:97
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:2459
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
struct act_prob action_prob_unit_vs_tgt(const struct civ_map *nmap, 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:6399
static enum action_sub_target_kind action_sub_target_kind_default(enum action_result result)
Definition actions.c:8712
static bool action_prob_is_signal(const struct act_prob probability)
Definition actions.c:6746
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2427
static bool plr_knows_tile(const struct player *plr, const struct tile *ttile)
Definition actions.c:3033
bool action_creates_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2224
static const char * action_prob_to_text(const struct act_prob prob)
Definition actions.c:1931
int action_prob_cmp_pessimist(const struct act_prob ap1, const struct act_prob ap2)
Definition actions.c:6763
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
bool action_id_is_rare_pop_up(action_id act_id)
Definition actions.c:1820
void actions_init(void)
Definition actions.c:1460
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
static void hard_code_oblig_hard_reqs_ruleset(void)
Definition actions.c:877
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
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
static const struct impr_type * tgt_city_local_building(const struct city *target_city)
Definition actions.c:3054
static struct astring ui_name_str
Definition actions.c:107
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
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
double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
Definition actions.c:6814
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition actions.c:267
const char * gen_action_name_update_cb(const char *old_name)
Definition actions.c:9313
static struct action_list * actlist_by_activity[ACTIVITY_LAST]
Definition actions.c:147
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
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
struct requirement_vector * action_enabler_vector_by_number(const void *enabler, req_vec_num_in_item number)
Definition actions.c:2991
bool action_distance_accepted(const struct action *action, const int distance)
Definition actions.c:1844
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:6241
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:7434
const char * action_get_ui_name_mnemonic(action_id act_id, const char *mnemonic)
Definition actions.c:1918
int action_max_range_default(enum action_result result)
Definition actions.c:8308
#define ACTPROB_VAL_MIN
Definition actions.c:86
#define ACTION_DISTANCE_MAX
Definition actions.h:354
#define ACTPROB_CERTAIN
Definition actions.h:940
#define ACTPROB_NA
Definition actions.h:941
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_enabler_list_re_iterate_end
Definition actions.h:463
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:350
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:459
#define action_has_result(_act_, _res_)
Definition actions.h:448
#define action_enabler_list_iterate_end
Definition actions.h:457
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:352
#define action_iterate_end
Definition actions.h:472
#define MAX_NUM_ACTIONS
Definition actions.h:296
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
#define ACTPROB_NOT_KNOWN
Definition actions.h:943
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:696
#define ACTPROB_IMPOSSIBLE
Definition actions.h:939
#define ACTPROB_NOT_IMPLEMENTED
Definition actions.h:942
#define action_iterate(_act_)
Definition actions.h:467
#define ACTION_ANY
Definition actions.h:290
#define action_id_get_target_kind(act_id)
Definition actions.h:655
#define action_id_has_result_safe(act_id, result)
Definition actions.h:668
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:946
#define ACTION_NONE
Definition actions.h:293
void astr_free(struct astring *astr)
Definition astring.c:153
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
void astr_clear(struct astring *astr)
Definition astring.c:205
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
bool can_build_base(const struct unit *punit, const struct base_type *pbase, const struct tile *ptile)
Definition base.c:53
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:722
int city_unit_slots_available(const struct city *pcity)
Definition city.c:1027
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1438
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:1985
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:748
static bool is_non_attack_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:736
#define city_tile(_pcity_)
Definition city.h:544
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define city_owner(_pcity_)
Definition city.h:543
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:85
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
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile)
Definition combat.c:884
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender)
Definition combat.c:438
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:271
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile)
Definition combat.c:783
@ ATT_OK
Definition combat.h:35
char * enablers
Definition comments.c:48
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:55
struct unit * actor_unit
Definition dialogs_g.h:54
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
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:56
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
struct unit struct city * target_city
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:56
int int id
Definition editgui_g.h:28
struct @21::@22 reqs
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
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:136
#define effect_list_iterate_end
Definition effects.h:375
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
bool unit_can_displace_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:713
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
bool can_remove_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:586
struct extra_type_list * extra_type_list_of_terr_claimers(void)
Definition extras.c:259
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:327
bool can_build_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:507
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:792
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:338
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:159
#define extra_type_iterate_end
Definition extras.h:297
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_index(_e_)
Definition extras.h:177
#define extra_deps_iterate_end
Definition extras.h:346
#define extra_type_list_iterate_end
Definition extras.h:161
#define extra_base_get(_e_)
Definition extras.h:184
#define extra_road_get(_e_)
Definition extras.h:185
const struct functions * fc_funcs
int Tech_type_id
Definition fc_types.h:347
#define ACT_TIME_INSTANTANEOUS
Definition fc_types.h:319
@ RPT_CERTAIN
Definition fc_types.h:586
@ RPT_POSSIBLE
Definition fc_types.h:585
int action_id
Definition fc_types.h:359
#define ACTRES_LAST
Definition fc_types.h:300
#define MAX_NUM_ACTION_AUTO_PERFORMERS
Definition fc_types.h:54
#define _(String)
Definition fcintl.h:67
#define N_(String)
Definition fcintl.h:69
struct civ_game game
Definition game.c:57
static bool is_ruleset_compat_mode(void)
Definition game.h:340
#define RS_DEFAULT_EXPLODE_NUCLEAR_MAX_RANGE
Definition game.h:864
#define RS_DEFAULT_ACTION_MIN_RANGE
Definition game.h:862
#define RS_DEFAULT_USER_ACTION_TARGET_KIND
Definition game.h:861
#define RS_DEFAULT_ACTION_MAX_RANGE
Definition game.h:863
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_msg(condition, message,...)
Definition log.h:205
#define fc_assert_action_msg(condition, action, message,...)
Definition log.h:201
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_error(message,...)
Definition log.h:103
#define FC_STATIC_ASSERT(cond, tag)
Definition log.h:235
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
Definition map.c:101
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:740
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
#define MAP_DISTANCE_MAX
Definition map.h:612
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:385
#define square_iterate_end
Definition map.h:388
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
bool can_see_techs_of_target(const struct player *pow_player, const struct player *target_player)
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)
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:304
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:316
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:869
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
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:826
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:485
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:210
#define nations_iterate_end
Definition nation.h:335
#define nations_iterate(NAME_pnation)
Definition nation.h:332
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1084
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
bool player_can_see_city_externals(const struct player *pow_player, const struct city *target_city)
Definition player.c:1143
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool can_player_see_hypotetic_units_at(const struct player *pplayer, const struct tile *ptile)
Definition player.c:984
struct player_slot * slots
Definition player.c:50
bool can_player_see_city_internals(const struct player *pplayer, const struct city *pcity)
Definition player.c:1129
bool player_can_trust_tile_has_no_units(const struct player *pplayer, const struct tile *ptile)
Definition player.c:958
bool universal_never_there(const struct universal *source)
const struct req_context * req_context_empty(void)
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
struct req_vec_problem * req_vec_suggest_repair(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
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)
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *descr,...)
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
struct req_vec_problem * req_vec_suggest_improvement(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
signed char req_vec_num_in_item
req_vec_num_in_item a requirement vectors number in an item.
#define requirement_vector_iterate_end
#define requirement_fulfilled_by_government(_gov_, _rqs_)
#define requirement_vector_iterate(req_vec, preq)
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
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_id server_setting_by_name(const char *name)
int server_setting_value_int_get(server_setting_id id)
enum fc_tristate fc_tristate_and(enum fc_tristate one, enum fc_tristate two)
Definition shared.c:124
fc_tristate
Definition shared.h:46
@ TRI_YES
Definition shared.h:46
@ TRI_NO
Definition shared.h:46
@ TRI_MAYBE
Definition shared.h:46
#define CLIP(lower, current, upper)
Definition shared.h:57
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
size_t size
Definition specvec.h:72
enum action_auto_perf_cause cause
Definition actions.h:570
action_id alternatives[MAX_NUM_ACTIONS]
Definition actions.h:578
struct requirement req
Definition actions.c:42
bool ruledit_disabled
Definition actions.h:445
action_id action
Definition actions.h:439
struct requirement_vector actor_reqs
Definition actions.h:440
struct requirement_vector target_reqs
Definition actions.h:441
bool unitwaittime_controlled
Definition actions.h:428
action_id id
Definition actions.h:380
bool actor_consuming_always
Definition actions.h:412
bool rare_pop_up
Definition actions.h:425
int max_distance
Definition actions.h:395
bool quiet
Definition actions.h:402
enum action_sub_target_kind sub_target_kind
Definition actions.h:387
enum moves_actor_kind moves_actor
Definition actions.h:432
struct action::@12::@13 is_unit
enum action_result result
Definition actions.h:382
char ui_name[MAX_LEN_NAME]
Definition actions.h:398
bv_action_sub_results sub_results
Definition actions.h:383
enum action_actor_kind actor_kind
Definition actions.h:385
enum act_tgt_compl target_complexity
Definition actions.h:390
bv_actions blocked_by
Definition actions.h:406
union action::@12 actor
enum action_target_kind target_kind
Definition actions.h:386
int min_distance
Definition actions.h:395
struct action_enabler_contradiction * alternative
Definition actions.c:54
int alternatives
Definition actions.c:51
Definition city.h:309
int id
Definition city.h:315
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
bool buildable
Definition extras.h:112
int(* player_tile_city_id_get)(const struct tile *ptile, const struct player *pplayer)
bool(* player_tile_vision_get)(const struct tile *ptile, const struct player *pplayer, enum vision_layer vision)
struct ae_contra_or * contras
Definition actions.c:64
const char * error_msg
Definition actions.c:68
bool tech_steal_allow_holes
enum airlifting_style airlifting_style
bool airlift_from_always_enabled
bv_actions diplchance_initial_odds
struct player_economic economic
Definition player.h:284
const struct tile * tile
const struct player * player
const struct unit_type * unittype
const struct unit * unit
const struct city * city
req_vec_num_in_item vector_number
enum req_vec_change_operation operation
struct requirement req
struct req_vec_change * suggested_solutions
enum req_range range
struct universal source
struct terrain * cultivate_result
Definition terrain.h:203
struct terrain * plant_result
Definition terrain.h:206
int clean_fallout_time
Definition terrain.h:220
int pillage_time
Definition terrain.h:221
int clean_pollution_time
Definition terrain.h:219
struct terrain * transform_result
Definition terrain.h:217
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
struct unit_class::@85 cache
struct extra_type_list * native_bases
Definition unittype.h:157
int transport_capacity
Definition unittype.h:504
int pop_cost
Definition unittype.h:493
int paratroopers_range
Definition unittype.h:522
int convert_time
Definition unittype.h:512
struct veteran_system * veteran
Definition unittype.h:525
const struct unit_type * obsoleted_by
Definition unittype.h:510
int bombard_rate
Definition unittype.h:528
int city_slots
Definition unittype.h:533
const struct unit_type * converted_to
Definition unittype.h:511
int attack_strength
Definition unittype.h:495
Definition unit.h:138
int moves_left
Definition unit.h:150
int hp
Definition unit.h:151
struct tile * tile
Definition unit.h:140
struct extra_type * activity_target
Definition unit.h:164
bool paradropped
Definition unit.h:174
const struct unit_type * utype
Definition unit.h:139
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
#define fc__attribute(x)
Definition support.h:89
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define fc__fallthrough
Definition support.h:109
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define advance_iterate(_start, _p)
Definition tech.h:264
#define A_FIRST
Definition tech.h:44
#define advance_iterate_end
Definition tech.h:270
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:538
#define T_NONE
Definition terrain.h:56
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:209
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:401
int tile_activity_time(enum unit_activity activity, const struct tile *ptile, const struct extra_type *tgt)
Definition tile.c:412
enum known_type tile_get_known(const struct tile *ptile, const struct player *pplayer)
Definition tile.c:386
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
@ TILE_UNKNOWN
Definition tile.h:35
@ TILE_KNOWN_SEEN
Definition tile.h:37
#define ACTIVITY_FACTOR
Definition tile.h:164
#define tile_terrain(_tile)
Definition tile.h:109
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#define tile_owner(_tile)
Definition tile.h:95
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
enum citytile_type citytile
Definition fc_types.h:613
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2504
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
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:719
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:328
bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
Definition unit.c:1157
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1972
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:771
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2019
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
@ UU_OK
Definition unit.h:61
#define unit_home(_pu_)
Definition unit.h:393
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:430
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
@ AR_OK_SRC_UNKNOWN
Definition unit.h:75
@ AR_OK_DST_UNKNOWN
Definition unit.h:76
@ AR_NO_MOVES
Definition unit.h:78
@ AR_BAD_DST_CITY
Definition unit.h:83
@ AR_NOT_IN_CITY
Definition unit.h:81
@ AR_OCCUPIED
Definition unit.h:80
@ AR_OK
Definition unit.h:74
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
@ AR_WRONG_UNITTYPE
Definition unit.h:79
@ AR_BAD_SRC_CITY
Definition unit.h:82
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
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
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2645
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1595
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
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
#define utype_class(_t_)
Definition unittype.h:736
#define L_LAST
Definition unittype.h:420
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848
#define U_NOT_OBSOLETED
Definition unittype.h:509