Freeciv-3.2: /fast/freeciv/nightly/S3_2/common/actions.c Source File

Freeciv-3.2

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 "metaknowledge.h"
32#include "movement.h"
33#include "nation.h"
34#include "research.h"
35#include "server_settings.h"
36#include "unit.h"
37
38/* Custom data types for obligatory hard action requirements. */
39
40/* A contradiction to an obligatory hard requirement. */
41 struct action_enabler_contradiction {
42 /* A requirement that contradicts the obligatory hard requirement. */
43 struct requirement req;
44
45 /* Is the obligatory hard requirement in the action enabler's target
46 * requirement vector? If FALSE it is in its actor requirement vector. */
47 bool is_target;
48};
49
50/* One or more alternative obligatory hard requirement contradictions. */
51 struct ae_contra_or {
52 int alternatives;
53 /* The obligatory hard requirement is fulfilled if a contradiction exists
54 * that doesn't contradict the action enabler. */
55 struct action_enabler_contradiction *alternative;
56
57 /* How many obligatory reqs use this */
58 int users;
59};
60
61/* An obligatory hard action requirement */
62 struct obligatory_req {
63 /* The requirement is fulfilled if the action enabler doesn't contradict
64 * one of the contradictions listed here. */
65 struct ae_contra_or *contras;
66
67 /* The error message to show when the hard obligatory requirement is
68 * missing. Must be there. */
69 const char *error_msg;
70};
71
72#define SPECVEC_TAG obligatory_req
73#define SPECVEC_TYPE struct obligatory_req
74#include "specvec.h"
75#define obligatory_req_vector_iterate(obreq_vec, pobreq) \
76 TYPED_VECTOR_ITERATE(struct obligatory_req, obreq_vec, pobreq)
77#define obligatory_req_vector_iterate_end VECTOR_ITERATE_END
78
79/* Values used to interpret action probabilities.
80 *
81 * Action probabilities are sent over the network. A change in a value here
82 * will therefore change the network protocol.
83 *
84 * A change in a value here should also update the action probability
85 * format documentation in fc_types.h */
86/* The lowest possible probability value (0%) */
87#define ACTPROB_VAL_MIN 0
88/* The highest possible probability value (100%) */
89#define ACTPROB_VAL_MAX 200
90/* A probability increase of 1% corresponds to this increase. */
91#define ACTPROB_VAL_1_PCT (ACTPROB_VAL_MAX / 100)
92/* Action probability doesn't apply when min is this. */
93#define ACTPROB_VAL_NA 253
94/* Action probability unsupported when min is this. */
95#define ACTPROB_VAL_NOT_IMPL 254
96
97 static struct action *actions[MAX_NUM_ACTIONS];
98 struct action **_actions = actions;
99 struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS];
100 static bool actions_initialized = FALSE;
101
102 static struct action_enabler_list *action_enablers_by_action[MAX_NUM_ACTIONS];
103
104/* Hard requirements relates to action result. */
105 static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE];
106 static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT];
107
108 static struct astring ui_name_str = ASTRING_INIT;
109
110static struct action *
111 unit_action_new(action_id id,
112 enum action_result result,
113 bool rare_pop_up,
114 bool unitwaittime_controlled,
115 enum moves_actor_kind moves_actor,
116 const int min_distance,
117 const int max_distance,
118 bool actor_consuming_always);
119
120static bool is_enabler_active(const struct action_enabler *enabler,
121 const struct req_context *actor,
122 const struct req_context *target);
123
124static inline bool
125 action_prob_is_signal(const struct act_prob probability);
126static inline bool
127 action_prob_not_relevant(const struct act_prob probability);
128static inline bool
129 action_prob_not_impl(const struct act_prob probability);
130
131static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
132 const struct unit *pvictim,
133 const struct tile *tgt_tile,
134 const struct action *paction)
135 fc__attribute((nonnull(3)));
136
137/* Make sure that an action distance can target the whole map. */
138 FC_STATIC_ASSERT(MAP_DISTANCE_MAX <= ACTION_DISTANCE_LAST_NON_SIGNAL,
139 action_range_can_not_cover_the_whole_map);
140
141 static struct action_list *actlist_by_result[ACTRES_LAST];
142 static struct action_list *actlist_by_activity[ACTIVITY_LAST];
143
144/**********************************************************************/
155 static struct ae_contra_or *req_contradiction_or(int alternatives, ...)
156{
157 struct ae_contra_or *out;
158 int i;
159 va_list args;
160
161 fc_assert_ret_val(alternatives > 0, NULL);
162 out = fc_malloc(sizeof(*out));
163 out->users = 0;
164 out->alternatives = alternatives;
165 out->alternative = fc_malloc(sizeof(out->alternative[0]) * alternatives);
166
167 va_start(args, alternatives);
168 for (i = 0; i < alternatives; i++) {
169 struct requirement contradiction = va_arg(args, struct requirement);
170 bool is_target = va_arg(args, int);
171
172 out->alternative[i].req = contradiction;
173 out->alternative[i].is_target = is_target;
174 }
175 va_end(args);
176
177 return out;
178}
179
180/**********************************************************************/
184 static void ae_contra_close(struct ae_contra_or *contra)
185{
186 contra->users--;
187
188 if (contra->users < 1) {
189 /* No users left. Delete. */
190 FC_FREE(contra->alternative);
191 FC_FREE(contra);
192 }
193}
194
195/**********************************************************************/
203 static void voblig_hard_req_reg(struct ae_contra_or *contras,
204 const char *error_message,
205 va_list args)
206{
207 struct obligatory_req oreq;
208 enum action_result res;
209 int users = 0;
210
211 /* A non null action message is used to indicate that an obligatory hard
212 * requirement is missing. */
213 fc_assert_ret(error_message);
214
215 /* Pack the obligatory hard requirement. */
216 oreq.contras = contras;
217 oreq.error_msg = error_message;
218
219 /* Add the obligatory hard requirement to each action result it applies
220 * to. */
221 while (ACTRES_NONE != (res = va_arg(args, enum action_result))) {
222 /* Any invalid action result should terminate the loop before this
223 * assertion. */
224 fc_assert_ret_msg(action_result_is_valid(res),
225 "Invalid action result %d", res);
226
227 /* Add to list for action result */
228 obligatory_req_vector_append(&oblig_hard_reqs_r[res], oreq);
229
230 /* Register the new user. */
231 users++;
232 }
233
234 fc_assert(users > 0);
235
236 oreq.contras->users += users;
237}
238
239/**********************************************************************/
247 static void oblig_hard_req_reg(struct ae_contra_or *contras,
248 const char *error_message,
249 ...)
250{
251 va_list args;
252
253 /* Add the obligatory hard requirement to each action result it applies
254 * to. */
255 va_start(args, error_message);
256 voblig_hard_req_reg(contras, error_message, args);
257 va_end(args);
258}
259
260/**********************************************************************/
267 static void oblig_hard_req_register(struct requirement contradiction,
268 bool is_target,
269 const char *error_message,
270 ...)
271{
272 struct ae_contra_or *contra;
273 va_list args;
274
275 /* Pack the obligatory hard requirement. */
276 contra = req_contradiction_or(1, contradiction, is_target);
277
278 /* Add the obligatory hard requirement to each action result it applies
279 * to. */
280 va_start(args, error_message);
281 voblig_hard_req_reg(contra, error_message, args);
282 va_end(args);
283}
284
285/**********************************************************************/
294 static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
295 const char *error_message,
296 va_list args)
297{
298 struct obligatory_req oreq;
299 enum action_sub_result res;
300
301 /* A non null action message is used to indicate that an obligatory hard
302 * requirement is missing. */
303 fc_assert_ret(error_message);
304
305 /* Pack the obligatory hard requirement. */
306 oreq.contras = contras;
307 oreq.error_msg = error_message;
308
309 /* Add the obligatory hard requirement to each action sub result it
310 * applies to. */
311 while (ACT_SUB_RES_COUNT != (res = va_arg(args,
312 enum action_sub_result))) {
313 /* Any invalid action sub result should terminate the loop before this
314 * assertion. */
315 fc_assert_ret_msg(action_sub_result_is_valid(res),
316 "Invalid action result %d", res);
317
318 /* Add to list for action result */
319 obligatory_req_vector_append(&oblig_hard_reqs_sr[res], oreq);
320
321 /* Register the new user. */
322 oreq.contras->users++;
323 }
324}
325
326/**********************************************************************/
336 static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
337 const char *error_message,
338 ...)
339{
340 va_list args;
341
342 /* Add the obligatory hard requirement to each action result it applies
343 * to. */
344 va_start(args, error_message);
345 voblig_hard_req_reg_sub_res(contras, error_message, args);
346 va_end(args);
347}
348
349/**********************************************************************/
354 static void hard_code_oblig_hard_reqs(void)
355{
356 /* Why this is a hard requirement: There is currently no point in
357 * allowing the listed actions against domestic targets.
358 * (Possible counter argument: crazy hack involving the Lua
359 * callback action_started_callback() to use an action to do
360 * something else. */
361 /* TODO: Unhardcode as a part of false flag operation support. */
362 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
363 FALSE, FALSE, TRUE, DRO_FOREIGN),
364 FALSE,
365 N_("All action enablers for %s must require a "
366 "foreign target."),
367 ACTRES_ESTABLISH_EMBASSY,
368 ACTRES_SPY_INVESTIGATE_CITY,
369 ACTRES_SPY_STEAL_GOLD,
370 ACTRES_STEAL_MAPS,
371 ACTRES_SPY_STEAL_TECH,
372 ACTRES_SPY_TARGETED_STEAL_TECH,
373 ACTRES_SPY_INCITE_CITY,
374 ACTRES_SPY_BRIBE_UNIT,
375 ACTRES_CAPTURE_UNITS,
376 ACTRES_CONQUER_CITY,
377 ACTRES_SPY_ESCAPE,
378 ACTRES_NONE);
379 /* The same for tile targeted actions that also can be done to unclaimed
380 * tiles. */
381 oblig_hard_req_reg(req_contradiction_or(
382 2,
383 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
384 FALSE, FALSE, TRUE, DRO_FOREIGN),
385 FALSE,
386 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
387 FALSE, TRUE, TRUE,
388 CITYT_CLAIMED),
389 TRUE),
390 /* TRANS: error message for ruledit */
391 N_("All action enablers for %s must require a "
392 "non domestic target."),
393 ACTRES_PARADROP_CONQUER,
394 ACTRES_NONE);
395 /* The same for tile extras targeted actions that also can be done to
396 * unowned extras. */
397 oblig_hard_req_reg(req_contradiction_or(
398 2,
399 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
400 FALSE, FALSE, TRUE, DRO_FOREIGN),
401 FALSE,
402 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
403 FALSE, TRUE, TRUE,
404 CITYT_EXTRAS_OWNED),
405 TRUE),
406 /* TRANS: error message for ruledit */
407 N_("All action enablers for %s must require a "
408 "non domestic target."),
409 ACTRES_CONQUER_EXTRAS,
410 ACTRES_NONE);
411
412 /* Why this is a hard requirement: There is currently no point in
413 * establishing an embassy when a real embassy already exists.
414 * (Possible exception: crazy hack using the Lua callback
415 * action_started_callback() to make establish embassy do something
416 * else even if the UI still call the action Establish Embassy) */
417 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
418 FALSE, TRUE, TRUE,
419 DRO_HAS_REAL_EMBASSY),
420 FALSE,
421 N_("All action enablers for %s must require the"
422 " absence of a real embassy."),
423 ACTRES_ESTABLISH_EMBASSY,
424 ACTRES_NONE);
425
426 /* Why this is a hard requirement: There is currently no point in
427 * fortifying an already fortified unit. */
428 oblig_hard_req_register(req_from_values(VUT_ACTIVITY, REQ_RANGE_LOCAL,
429 FALSE, TRUE, TRUE,
430 ACTIVITY_FORTIFIED),
431 FALSE,
432 N_("All action enablers for %s must require that"
433 " the actor unit isn't already fortified."),
434 ACTRES_FORTIFY,
435 ACTRES_NONE);
436
437 /* Why this is a hard requirement: there is a hard requirement that
438 * the actor player is at war with the owner of any city on the
439 * target tile.
440 * The Freeciv code assumes that ACTRES_ATTACK has this. */
441 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
442 FALSE, FALSE, TRUE, DS_WAR),
443 FALSE,
444 N_("All action enablers for %s must require"
445 " that the actor is at war with the target."),
446 ACTRES_ATTACK,
447 ACTRES_WIPE_UNITS,
448 ACTRES_NONE);
449
450 /* Why this is a hard requirement: Keep the old rules. Need to work
451 * out corner cases. */
452 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
453 FALSE, TRUE, TRUE, DRO_FOREIGN),
454 FALSE,
455 N_("All action enablers for %s must require"
456 " a domestic target."),
457 ACTRES_UPGRADE_UNIT, ACTRES_NONE);
458
459 /* Why this is a hard requirement: The code expects that only domestic and
460 * allied transports can be boarded. */
461 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
462 FALSE, TRUE, TRUE, DS_ARMISTICE),
463 FALSE,
464 N_("All action enablers for %s must require"
465 " a domestic or allied target."),
466 ACTRES_TRANSPORT_EMBARK,
467 ACTRES_TRANSPORT_BOARD,
468 ACTRES_TRANSPORT_LOAD,
469 ACTRES_NONE);
470 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
471 FALSE, TRUE, TRUE, DS_WAR),
472 FALSE,
473 N_("All action enablers for %s must require"
474 " a domestic or allied target."),
475 ACTRES_TRANSPORT_EMBARK,
476 ACTRES_TRANSPORT_BOARD,
477 ACTRES_TRANSPORT_LOAD,
478 ACTRES_NONE);
479 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
480 FALSE, TRUE, TRUE, DS_CEASEFIRE),
481 FALSE,
482 N_("All action enablers for %s must require"
483 " a domestic or allied target."),
484 ACTRES_TRANSPORT_EMBARK,
485 ACTRES_TRANSPORT_BOARD,
486 ACTRES_TRANSPORT_LOAD,
487 ACTRES_NONE);
488 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
489 FALSE, TRUE, TRUE, DS_PEACE),
490 FALSE,
491 N_("All action enablers for %s must require"
492 " a domestic or allied target."),
493 ACTRES_TRANSPORT_EMBARK,
494 ACTRES_TRANSPORT_BOARD,
495 ACTRES_TRANSPORT_LOAD,
496 ACTRES_NONE);
497 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
498 FALSE, TRUE, TRUE, DS_NO_CONTACT),
499 FALSE,
500 N_("All action enablers for %s must require"
501 " a domestic or allied target."),
502 ACTRES_TRANSPORT_EMBARK,
503 ACTRES_TRANSPORT_BOARD,
504 ACTRES_TRANSPORT_LOAD,
505 ACTRES_NONE);
506
507 /* Why this is a hard requirement: Preserve semantics of the Settlers
508 * unit type flag. */
509 oblig_hard_req_register(req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
510 FALSE, FALSE, TRUE,
511 UTYF_SETTLERS),
512 FALSE,
513 N_("All action enablers for %s must require"
514 " that the actor has"
515 " the Settlers utype flag."),
516 ACTRES_TRANSFORM_TERRAIN,
517 ACTRES_CULTIVATE,
518 ACTRES_PLANT,
519 ACTRES_ROAD,
520 ACTRES_BASE,
521 ACTRES_MINE,
522 ACTRES_IRRIGATE,
523 ACTRES_CLEAN,
524 ACTRES_NONE);
525
526 /* Why this is a hard requirement: Preserve semantics of the rule that a
527 * *_time of 0 disables the action. */
528 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_TILE,
529 FALSE, FALSE, FALSE,
530 TA_CAN_IRRIGATE),
531 TRUE,
532 N_("All action enablers for %s must require"
533 " that the target"
534 " tile's terrain's irrigation_time"
535 " is above 0. (See \"TerrainAlter\"'s"
536 " \"CanIrrigate\")"),
537 ACTRES_IRRIGATE,
538 ACTRES_NONE);
539 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_TILE,
540 FALSE, FALSE, FALSE,
541 TA_CAN_MINE),
542 TRUE,
543 N_("All action enablers for %s must require"
544 " that the target"
545 " tile's terrain's mining_time"
546 " is above 0. (See \"TerrainAlter\"'s"
547 " \"CanMine\")"),
548 ACTRES_MINE,
549 ACTRES_NONE);
550 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_TILE,
551 FALSE, FALSE, FALSE,
552 TA_CAN_ROAD),
553 TRUE,
554 N_("All action enablers for %s must require"
555 " that the target"
556 " tile's terrain's road_time"
557 " is above 0. (See \"TerrainAlter\"'s"
558 " \"CanRoad\")"),
559 ACTRES_ROAD,
560 ACTRES_NONE);
561 oblig_hard_req_register(req_from_values(VUT_TERRAINALTER, REQ_RANGE_TILE,
562 FALSE, FALSE, FALSE,
563 TA_CAN_BASE),
564 TRUE,
565 N_("All action enablers for %s must require"
566 " that the target"
567 " tile's terrain's base_time"
568 " is above 0. (See \"TerrainAlter\"'s"
569 " \"CanBase\")"),
570 ACTRES_BASE,
571 ACTRES_NONE);
572
573 /* Why this is a hard requirement: Preserve semantics of the NoCities
574 * terrain flag. */
575 oblig_hard_req_register(req_from_values(VUT_TERRFLAG, REQ_RANGE_TILE,
576 FALSE, TRUE, TRUE,
577 TER_NO_CITIES),
578 TRUE,
579 N_("All action enablers for %s must require that"
580 " the target doesn't have"
581 " the NoCities terrain flag."),
582 ACTRES_FOUND_CITY,
583 ACTRES_NONE);
584
585 /* It isn't possible to establish a trade route from a non existing
586 * city. The Freeciv code assumes this applies to Enter Marketplace
587 * too. */
588 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
589 FALSE, FALSE, TRUE,
590 USP_HAS_HOME_CITY),
591 FALSE,
592 N_("All action enablers for %s must require"
593 " that the actor has a home city."),
594 ACTRES_TRADE_ROUTE,
595 ACTRES_MARKETPLACE,
596 ACTRES_NONE);
597
598 /* Why this is a hard requirement:
599 * - preserve the semantics of the NonMil unit type flag. */
600 oblig_hard_req_reg(req_contradiction_or(
601 3,
602 req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
603 FALSE, FALSE, TRUE,
604 UTYF_CIVILIAN),
605 FALSE,
606 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
607 FALSE, TRUE, TRUE, DS_PEACE),
608 FALSE,
609 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
610 FALSE, TRUE, TRUE,
611 CITYT_CLAIMED),
612 TRUE),
613 /* TRANS: error message for ruledit */
614 N_("All action enablers for %s must require"
615 " that the actor has the NonMil utype flag"
616 " or that the target tile is unclaimed"
617 " or that the diplomatic relation to"
618 " the target tile owner isn't peace."),
619 ACTRES_PARADROP,
620 ACTRES_PARADROP_CONQUER,
621 ACTRES_NONE);
622
623 /* Why this is a hard requirement: Preserve semantics of NonMil
624 * flag. Need to replace other uses in game engine before this can
625 * be demoted to a regular unit flag. */
626 oblig_hard_req_register(req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
627 FALSE, TRUE, TRUE, UTYF_CIVILIAN),
628 FALSE,
629 N_("All action enablers for %s must require"
630 " that the actor doesn't have"
631 " the NonMil utype flag."),
632 ACTRES_ATTACK,
633 ACTRES_CONQUER_CITY,
634 ACTRES_WIPE_UNITS,
635 ACTRES_NONE);
636 oblig_hard_req_reg(req_contradiction_or(
637 2,
638 req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL,
639 FALSE, TRUE, TRUE, UTYF_CIVILIAN),
640 FALSE,
641 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
642 FALSE, TRUE, TRUE,
643 CITYT_CENTER),
644 TRUE),
645 /* TRANS: error message for ruledit */
646 N_("All action enablers for %s must require"
647 " no city at the target tile or"
648 " that the actor doesn't have"
649 " the NonMil utype flag."),
650 ACTRES_PARADROP_CONQUER,
651 ACTRES_NONE);
652
653 /* Why this is a hard requirement: Preserve semantics of
654 * CanOccupyCity unit class flag. */
655 oblig_hard_req_register(req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
656 FALSE, FALSE, TRUE,
657 UCF_CAN_OCCUPY_CITY),
658 FALSE,
659 N_("All action enablers for %s must require"
660 " that the actor has"
661 " the CanOccupyCity uclass flag."),
662 ACTRES_CONQUER_CITY,
663 ACTRES_NONE);
664 oblig_hard_req_reg(req_contradiction_or(
665 2,
666 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
667 FALSE, FALSE, TRUE,
668 UCF_CAN_OCCUPY_CITY),
669 FALSE,
670 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
671 FALSE, TRUE, TRUE,
672 CITYT_CENTER),
673 TRUE),
674 /* TRANS: error message for ruledit */
675 N_("All action enablers for %s must require"
676 " no city at the target tile or"
677 " that the actor has"
678 " the CanOccupyCity uclass flag."),
679 ACTRES_PARADROP_CONQUER,
680 ACTRES_NONE);
681
682 /* Why this is a hard requirement: Consistency with ACTRES_ATTACK.
683 * Assumed by other locations in the Freeciv code. Examples:
684 * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */
685 oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
686 FALSE, FALSE, TRUE, DS_WAR),
687 FALSE,
688 N_("All action enablers for %s must require"
689 " that the actor is at war with the target."),
690 ACTRES_CONQUER_CITY,
691 ACTRES_NONE);
692 oblig_hard_req_reg(req_contradiction_or(
693 2,
694 req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL,
695 FALSE, FALSE, TRUE, DS_WAR),
696 FALSE,
697 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
698 FALSE, TRUE, TRUE,
699 CITYT_CENTER),
700 TRUE),
701 /* TRANS: error message for ruledit */
702 N_("All action enablers for %s must require"
703 " no city at the target tile or"
704 " that the actor is at war with the target."),
705 ACTRES_PARADROP_CONQUER,
706 ACTRES_NONE);
707
708 /* Why this is a hard requirement: a unit must move into a city to
709 * conquer it, move into a transport to embark, move out of a transport
710 * to disembark from it, move into an extra to conquer it and move into a
711 * hut to enter/frighten it. */
712 oblig_hard_req_register(req_from_values(VUT_MINMOVES, REQ_RANGE_LOCAL,
713 FALSE, FALSE, TRUE, 1),
714 FALSE,
715 N_("All action enablers for %s must require"
716 " that the actor has a movement point left."),
717 ACTRES_CONQUER_CITY,
718 ACTRES_TRANSPORT_DISEMBARK,
719 ACTRES_TRANSPORT_EMBARK,
720 ACTRES_CONQUER_EXTRAS,
721 ACTRES_HUT_ENTER,
722 ACTRES_HUT_FRIGHTEN,
723 ACTRES_UNIT_MOVE,
724 ACTRES_NONE);
725
726 /* Why this is a hard requirement: this eliminates the need to
727 * check if units transported by the actor unit can exist at the
728 * same tile as all the units in the occupied city.
729 *
730 * This makes an implicit rule explicit:
731 * 1. A unit must move into a city to conquer it.
732 * 2. It can't move into the city if the tile contains a non-allied
733 * unit (see unit_move_to_tile_test()).
734 * 3. A city could, at the time this rule was made explicit, only
735 * contain units allied to its owner.
736 * 3. A player could, at the time this rule was made explicit, not
737 * be allied to a player that is at war with another ally.
738 * 4. A player could, at the time this rule was made explicit, only
739 * conquer a city belonging to someone they were at war with.
740 * Conclusion: the conquered city had to be empty.
741 */
742 oblig_hard_req_register(req_from_values(VUT_MAXTILEUNITS, REQ_RANGE_TILE,
743 FALSE, FALSE, TRUE, 0),
744 TRUE,
745 N_("All action enablers for %s must require"
746 " that the target city is empty."),
747 ACTRES_CONQUER_CITY,
748 ACTRES_NONE);
749
750 /* Why this is a hard requirement: Assumed in the code. Corner case
751 * where diplomacy prevents a transported unit to go to the target
752 * tile. The paradrop code doesn't check if transported units can
753 * coexist with the target tile city and units. */
754 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
755 FALSE, TRUE, TRUE,
756 USP_TRANSPORTING),
757 FALSE,
758 N_("All action enablers for %s must require"
759 " that the actor isn't transporting"
760 " another unit."),
761 ACTRES_PARADROP,
762 ACTRES_PARADROP_CONQUER,
763 ACTRES_AIRLIFT,
764 ACTRES_NONE);
765
766 /* Why this is a hard requirement: sanity. */
767 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
768 FALSE, FALSE, FALSE,
769 USP_HAS_HOME_CITY),
770 FALSE,
771 N_("All action enablers for %s must require"
772 " that the actor has a home city."),
773 ACTRES_HOMELESS, ACTRES_NONE);
774
775 /* Why this is a hard requirement: Assumed in the code.
776 * See hrm Bug #772516 - https://www.hostedredmine.com/issues/772516 */
777 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
778 FALSE, TRUE, TRUE,
779 USP_TRANSPORTING),
780 TRUE,
781 N_("All action enablers for %s must require"
782 " that the target isn't transporting another"
783 " unit."),
784 ACTRES_CAPTURE_UNITS, ACTRES_NONE);
785
786 /* Why this is a hard requirement: sanity. */
787 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
788 FALSE, FALSE, TRUE,
789 USP_TRANSPORTING),
790 TRUE,
791 N_("All action enablers for %s must require"
792 " that the target is transporting a unit."),
793 ACTRES_TRANSPORT_DEBOARD, ACTRES_NONE);
794 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
795 FALSE, FALSE, TRUE,
796 USP_TRANSPORTED),
797 FALSE,
798 N_("All action enablers for %s must require"
799 " that the actor is transported."),
800 ACTRES_TRANSPORT_DEBOARD,
801 ACTRES_TRANSPORT_DISEMBARK,
802 ACTRES_NONE);
803 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
804 FALSE, FALSE, TRUE,
805 USP_LIVABLE_TILE),
806 FALSE,
807 N_("All action enablers for %s must require"
808 " that the actor is on a livable tile."),
809 ACTRES_TRANSPORT_DEBOARD, ACTRES_NONE);
810
811 /* Why this is a hard requirement: sanity. */
812 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
813 FALSE, FALSE, TRUE,
814 USP_TRANSPORTING),
815 FALSE,
816 N_("All action enablers for %s must require"
817 " that the actor is transporting a unit."),
818 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
819 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
820 FALSE, FALSE, TRUE,
821 USP_TRANSPORTED),
822 TRUE,
823 N_("All action enablers for %s must require"
824 " that the target is transported."),
825 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
826 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
827 FALSE, FALSE, TRUE,
828 USP_LIVABLE_TILE),
829 TRUE,
830 N_("All action enablers for %s must require"
831 " that the target is on a livable tile."),
832 ACTRES_TRANSPORT_UNLOAD, ACTRES_NONE);
833
834 /* Why this is a hard requirement: Use ACTRES_TRANSPORT_DISEMBARK to
835 * disembark. Assumed by the Freeciv code. */
836 oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL,
837 FALSE, TRUE, TRUE,
838 USP_TRANSPORTED),
839 FALSE,
840 N_("All action enablers for %s must require"
841 " that the actor isn't transported."),
842 ACTRES_UNIT_MOVE,
843 ACTRES_TELEPORT, ACTRES_TELEPORT_CONQUER,
844 ACTRES_NONE);
845
846 /* Why this is a hard requirement: assumed by the Freeciv code. */
847 oblig_hard_req_register(req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
848 FALSE, FALSE, TRUE,
849 CITYT_CENTER),
850 FALSE,
851 N_("All action enablers for %s must require"
852 " that the actor unit is in a city."),
853 ACTRES_AIRLIFT,
854 ACTRES_NONE);
855
856 /* Why this is a hard requirement: Give meaning to the HutFrighten unit
857 * class flag. The point of it is to keep our options open for how both
858 * entering and frightening a hut at the same tile should be handled.
859 * See hrm Feature #920427 */
860 oblig_hard_req_reg_sub_res(req_contradiction_or(
861 1,
862 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
863 FALSE, TRUE, FALSE,
864 UCF_HUT_FRIGHTEN),
865 FALSE),
866 N_("All action enablers for %s must require"
867 " that the actor unit doesn't have the"
868 " HutFrighten unit class flag."),
869 ACT_SUB_RES_HUT_ENTER,
870 ACT_SUB_RES_COUNT);
871 oblig_hard_req_reg_sub_res(req_contradiction_or(
872 1,
873 req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL,
874 FALSE, FALSE, FALSE,
875 UCF_HUT_FRIGHTEN),
876 FALSE),
877 N_("All action enablers for %s must require"
878 " that the actor unit has the HutFrighten"
879 " unit class flag."),
880 ACT_SUB_RES_HUT_FRIGHTEN,
881 ACT_SUB_RES_COUNT);
882}
883
884/**********************************************************************/
888 static void hard_code_oblig_hard_reqs_ruleset(void)
889{
890 /* Why this is a hard requirement: the "animal can't conquer a city"
891 * rule. Assumed in unit_can_take_over(). */
892 nations_iterate(pnation) {
893 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
894 oblig_hard_req_register(req_from_values(VUT_NATION, REQ_RANGE_PLAYER,
895 FALSE, TRUE, TRUE,
896 nation_number(pnation)),
897 FALSE,
898 N_("All action enablers for %s must require"
899 " a non animal player actor."),
900 ACTRES_CONQUER_CITY,
901 ACTRES_NONE);
902 oblig_hard_req_reg(req_contradiction_or(
903 2,
904 req_from_values(VUT_NATION, REQ_RANGE_PLAYER,
905 FALSE, TRUE, TRUE,
906 nation_number(pnation)),
907 FALSE,
908 req_from_values(VUT_CITYTILE, REQ_RANGE_TILE,
909 FALSE, TRUE, TRUE,
910 CITYT_CENTER),
911 TRUE),
912 /* TRANS: error message for ruledit */
913 N_("All action enablers for %s must require"
914 " no city at the target tile or"
915 " a non animal player actor."),
916 ACTRES_PARADROP_CONQUER,
917 ACTRES_NONE);
918 }
919 } nations_iterate_end;
920}
921
922/**********************************************************************/
925 static void hard_code_actions(void)
926{
927 actions[ACTION_SPY_POISON] =
928 unit_action_new(ACTION_SPY_POISON, ACTRES_SPY_POISON,
929 FALSE, TRUE,
930 MAK_ESCAPE, 0, 1, TRUE);
931 actions[ACTION_SPY_POISON_ESC] =
932 unit_action_new(ACTION_SPY_POISON_ESC, ACTRES_SPY_POISON,
933 FALSE, TRUE,
934 MAK_ESCAPE, 0, 1, FALSE);
935 actions[ACTION_SPY_SABOTAGE_UNIT] =
936 unit_action_new(ACTION_SPY_SABOTAGE_UNIT, ACTRES_SPY_SABOTAGE_UNIT,
937 FALSE, TRUE,
938 MAK_ESCAPE, 0, 1, TRUE);
939 actions[ACTION_SPY_SABOTAGE_UNIT_ESC] =
940 unit_action_new(ACTION_SPY_SABOTAGE_UNIT_ESC, ACTRES_SPY_SABOTAGE_UNIT,
941 FALSE, TRUE,
942 MAK_ESCAPE, 0, 1, FALSE);
943 actions[ACTION_SPY_BRIBE_UNIT] =
944 unit_action_new(ACTION_SPY_BRIBE_UNIT, ACTRES_SPY_BRIBE_UNIT,
945 FALSE, TRUE,
946 /* Tries a forced move if the target unit is alone at
947 * its tile and not in a city. Takes all movement if
948 * the forced move fails. */
949 MAK_FORCED,
950 0, 1, FALSE);
951 actions[ACTION_SPY_SABOTAGE_CITY] =
952 unit_action_new(ACTION_SPY_SABOTAGE_CITY, ACTRES_SPY_SABOTAGE_CITY,
953 FALSE, TRUE,
954 MAK_ESCAPE, 0, 1, TRUE);
955 actions[ACTION_SPY_SABOTAGE_CITY_ESC] =
956 unit_action_new(ACTION_SPY_SABOTAGE_CITY_ESC, ACTRES_SPY_SABOTAGE_CITY,
957 FALSE, TRUE,
958 MAK_ESCAPE, 0, 1, FALSE);
959 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY] =
960 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY,
961 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
962 FALSE, TRUE,
963 MAK_ESCAPE, 0, 1, TRUE);
964 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION] =
965 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION,
966 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
967 FALSE, TRUE,
968 MAK_ESCAPE, 0, 1, TRUE);
969 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
970 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC,
971 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
972 FALSE, TRUE,
973 MAK_ESCAPE, 0, 1, FALSE);
974 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC] =
975 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC,
976 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
977 FALSE, TRUE,
978 MAK_ESCAPE, 0, 1, FALSE);
979 actions[ACTION_SPY_INCITE_CITY] =
980 unit_action_new(ACTION_SPY_INCITE_CITY, ACTRES_SPY_INCITE_CITY,
981 FALSE, TRUE,
982 MAK_ESCAPE, 0, 1, TRUE);
983 actions[ACTION_SPY_INCITE_CITY_ESC] =
984 unit_action_new(ACTION_SPY_INCITE_CITY_ESC, ACTRES_SPY_INCITE_CITY,
985 FALSE, TRUE,
986 MAK_ESCAPE, 0, 1, FALSE);
987 actions[ACTION_ESTABLISH_EMBASSY] =
988 unit_action_new(ACTION_ESTABLISH_EMBASSY,
989 ACTRES_ESTABLISH_EMBASSY,
990 FALSE, TRUE,
991 MAK_STAYS, 0, 1, FALSE);
992 actions[ACTION_ESTABLISH_EMBASSY_STAY] =
993 unit_action_new(ACTION_ESTABLISH_EMBASSY_STAY,
994 ACTRES_ESTABLISH_EMBASSY,
995 FALSE, TRUE,
996 MAK_STAYS, 0, 1, TRUE);
997 actions[ACTION_SPY_STEAL_TECH] =
998 unit_action_new(ACTION_SPY_STEAL_TECH,
999 ACTRES_SPY_STEAL_TECH,
1000 FALSE, TRUE,
1001 MAK_ESCAPE, 0, 1, TRUE);
1002 actions[ACTION_SPY_STEAL_TECH_ESC] =
1003 unit_action_new(ACTION_SPY_STEAL_TECH_ESC,
1004 ACTRES_SPY_STEAL_TECH,
1005 FALSE, TRUE,
1006 MAK_ESCAPE, 0, 1, FALSE);
1007 actions[ACTION_SPY_TARGETED_STEAL_TECH] =
1008 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH,
1009 ACTRES_SPY_TARGETED_STEAL_TECH,
1010 FALSE, TRUE,
1011 MAK_ESCAPE, 0, 1, TRUE);
1012 actions[ACTION_SPY_TARGETED_STEAL_TECH_ESC] =
1013 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH_ESC,
1014 ACTRES_SPY_TARGETED_STEAL_TECH,
1015 FALSE, TRUE,
1016 MAK_ESCAPE, 0, 1, FALSE);
1017 actions[ACTION_SPY_INVESTIGATE_CITY] =
1018 unit_action_new(ACTION_SPY_INVESTIGATE_CITY,
1019 ACTRES_SPY_INVESTIGATE_CITY,
1020 FALSE, TRUE,
1021 MAK_STAYS, 0, 1, FALSE);
1022 actions[ACTION_INV_CITY_SPEND] =
1023 unit_action_new(ACTION_INV_CITY_SPEND,
1024 ACTRES_SPY_INVESTIGATE_CITY,
1025 FALSE, TRUE,
1026 MAK_STAYS, 0, 1, TRUE);
1027 actions[ACTION_SPY_STEAL_GOLD] =
1028 unit_action_new(ACTION_SPY_STEAL_GOLD,
1029 ACTRES_SPY_STEAL_GOLD,
1030 FALSE, TRUE,
1031 MAK_ESCAPE, 0, 1, TRUE);
1032 actions[ACTION_SPY_STEAL_GOLD_ESC] =
1033 unit_action_new(ACTION_SPY_STEAL_GOLD_ESC,
1034 ACTRES_SPY_STEAL_GOLD,
1035 FALSE, TRUE,
1036 MAK_ESCAPE, 0, 1, FALSE);
1037 actions[ACTION_SPY_SPREAD_PLAGUE] =
1038 unit_action_new(ACTION_SPY_SPREAD_PLAGUE,
1039 ACTRES_SPY_SPREAD_PLAGUE,
1040 FALSE, TRUE,
1041 MAK_ESCAPE, 0, 1, FALSE);
1042 actions[ACTION_SPY_ESCAPE] =
1043 unit_action_new(ACTION_SPY_ESCAPE,
1044 ACTRES_SPY_ESCAPE,
1045 FALSE, TRUE,
1046 MAK_ESCAPE, 0, 1, FALSE);
1047 actions[ACTION_TRADE_ROUTE] =
1048 unit_action_new(ACTION_TRADE_ROUTE, ACTRES_TRADE_ROUTE,
1049 FALSE, TRUE,
1050 MAK_STAYS, 0, 1, TRUE);
1051 actions[ACTION_MARKETPLACE] =
1052 unit_action_new(ACTION_MARKETPLACE, ACTRES_MARKETPLACE,
1053 FALSE, TRUE,
1054 MAK_STAYS, 0, 1, TRUE);
1055 actions[ACTION_HELP_WONDER] =
1056 unit_action_new(ACTION_HELP_WONDER, ACTRES_HELP_WONDER,
1057 FALSE, TRUE,
1058 MAK_STAYS, 0, 1, TRUE);
1059 actions[ACTION_CAPTURE_UNITS] =
1060 unit_action_new(ACTION_CAPTURE_UNITS, ACTRES_CAPTURE_UNITS,
1061 FALSE, TRUE, MAK_STAYS,
1062 /* A single domestic unit at the target tile will make
1063 * the action illegal. It must therefore be performed
1064 * from another tile. */
1065 1, 1,
1066 FALSE);
1067 actions[ACTION_FOUND_CITY] =
1068 unit_action_new(ACTION_FOUND_CITY, ACTRES_FOUND_CITY,
1069 TRUE, TRUE, MAK_STAYS,
1070 /* Illegal to perform to a target on another tile.
1071 * Reason: The Freeciv code assumes that the city
1072 * founding unit is located at the tile were the new
1073 * city is founded. */
1074 0, 0,
1075 TRUE);
1076 actions[ACTION_JOIN_CITY] =
1077 unit_action_new(ACTION_JOIN_CITY, ACTRES_JOIN_CITY,
1078 TRUE, TRUE,
1079 MAK_STAYS, 0, 1, TRUE);
1080 actions[ACTION_STEAL_MAPS] =
1081 unit_action_new(ACTION_STEAL_MAPS, ACTRES_STEAL_MAPS,
1082 FALSE, TRUE,
1083 MAK_ESCAPE, 0, 1, TRUE);
1084 actions[ACTION_STEAL_MAPS_ESC] =
1085 unit_action_new(ACTION_STEAL_MAPS_ESC, ACTRES_STEAL_MAPS,
1086 FALSE, TRUE,
1087 MAK_ESCAPE, 0, 1, FALSE);
1088 actions[ACTION_BOMBARD] =
1089 unit_action_new(ACTION_BOMBARD, ACTRES_BOMBARD,
1090 FALSE, TRUE, MAK_STAYS,
1091 /* A single domestic unit at the target tile will make
1092 * the action illegal. It must therefore be performed
1093 * from another tile. */
1094 1,
1095 /* Overwritten by the ruleset's bombard_max_range */
1096 1,
1097 FALSE);
1098 actions[ACTION_BOMBARD2] =
1099 unit_action_new(ACTION_BOMBARD2, ACTRES_BOMBARD,
1100 FALSE, TRUE,
1101 MAK_STAYS,
1102 /* A single domestic unit at the target tile will make
1103 * the action illegal. It must therefore be performed
1104 * from another tile. */
1105 1,
1106 /* Overwritten by the ruleset's bombard_2_max_range */
1107 1,
1108 FALSE);
1109 actions[ACTION_BOMBARD3] =
1110 unit_action_new(ACTION_BOMBARD3, ACTRES_BOMBARD,
1111 FALSE, TRUE, MAK_STAYS,
1112 /* A single domestic unit at the target tile will make
1113 * the action illegal. It must therefore be performed
1114 * from another tile. */
1115 1,
1116 /* Overwritten by the ruleset's bombard_3_max_range */
1117 1,
1118 FALSE);
1119 actions[ACTION_BOMBARD_LETHAL] =
1120 unit_action_new(ACTION_BOMBARD_LETHAL, ACTRES_BOMBARD,
1121 FALSE, TRUE, MAK_STAYS,
1122 /* A single domestic unit at the target tile will make
1123 * the action illegal. It must therefore be performed
1124 * from another tile. */
1125 1,
1126 /* Overwritten by the ruleset's bombard_lethal_max_range */
1127 1,
1128 FALSE);
1129 actions[ACTION_BOMBARD_LETHAL2] =
1130 unit_action_new(ACTION_BOMBARD_LETHAL2, ACTRES_BOMBARD,
1131 FALSE, TRUE, MAK_STAYS,
1132 /* A single domestic unit at the target tile will make
1133 * the action illegal. It must therefore be performed
1134 * from another tile. */
1135 1,
1136 /* Overwritten by the ruleset's bombard_lethal_2_max_range */
1137 1,
1138 FALSE);
1139 actions[ACTION_SPY_NUKE] =
1140 unit_action_new(ACTION_SPY_NUKE, ACTRES_SPY_NUKE,
1141 FALSE, TRUE,
1142 MAK_ESCAPE, 0, 1, TRUE);
1143 actions[ACTION_SPY_NUKE_ESC] =
1144 unit_action_new(ACTION_SPY_NUKE_ESC, ACTRES_SPY_NUKE,
1145 FALSE, TRUE,
1146 MAK_ESCAPE, 0, 1, FALSE);
1147 actions[ACTION_NUKE] =
1148 unit_action_new(ACTION_NUKE, ACTRES_NUKE,
1149 TRUE, TRUE,
1150 MAK_STAYS, 0,
1151 /* Overwritten by the ruleset's
1152 * explode_nuclear_max_range */
1153 0,
1154 TRUE);
1155 actions[ACTION_NUKE_CITY] =
1156 unit_action_new(ACTION_NUKE_CITY, ACTRES_NUKE,
1157 TRUE, TRUE,
1158 MAK_STAYS, 1, 1, TRUE);
1159 actions[ACTION_NUKE_UNITS] =
1160 unit_action_new(ACTION_NUKE_UNITS, ACTRES_NUKE_UNITS,
1161 TRUE, TRUE,
1162 MAK_STAYS, 1, 1, TRUE);
1163 actions[ACTION_DESTROY_CITY] =
1164 unit_action_new(ACTION_DESTROY_CITY, ACTRES_DESTROY_CITY,
1165 TRUE, TRUE,
1166 MAK_STAYS, 0, 1, FALSE);
1167 actions[ACTION_EXPEL_UNIT] =
1168 unit_action_new(ACTION_EXPEL_UNIT, ACTRES_EXPEL_UNIT,
1169 FALSE, TRUE,
1170 MAK_STAYS, 0, 1, FALSE);
1171 actions[ACTION_DISBAND_UNIT_RECOVER] =
1172 unit_action_new(ACTION_DISBAND_UNIT_RECOVER, ACTRES_DISBAND_UNIT_RECOVER,
1173 TRUE, TRUE, MAK_STAYS,
1174 /* Illegal to perform to a target on another tile to
1175 * keep the rules exactly as they were for now. */
1176 0, 1,
1177 TRUE);
1178 actions[ACTION_DISBAND_UNIT] =
1179 unit_action_new(ACTION_DISBAND_UNIT,
1180 /* Can't be ACTRES_NONE because
1181 * action_success_actor_consume() sets unit lost
1182 * reason based on action result. */
1183 ACTRES_DISBAND_UNIT,
1184 TRUE, TRUE,
1185 MAK_STAYS, 0, 0, TRUE);
1186 actions[ACTION_HOME_CITY] =
1187 unit_action_new(ACTION_HOME_CITY, ACTRES_HOME_CITY,
1188 TRUE, FALSE,
1189 /* Illegal to perform to a target on another tile to
1190 * keep the rules exactly as they were for now. */
1191 MAK_STAYS, 0, 0, FALSE);
1192 actions[ACTION_HOMELESS] =
1193 unit_action_new(ACTION_HOMELESS, ACTRES_HOMELESS,
1194 TRUE, FALSE,
1195 MAK_STAYS, 0, 0, FALSE);
1196 actions[ACTION_UPGRADE_UNIT] =
1197 unit_action_new(ACTION_UPGRADE_UNIT, ACTRES_UPGRADE_UNIT,
1198 TRUE, TRUE, MAK_STAYS,
1199 /* Illegal to perform to a target on another tile to
1200 * keep the rules exactly as they were for now. */
1201 0, 0,
1202 FALSE);
1203 actions[ACTION_PARADROP] =
1204 unit_action_new(ACTION_PARADROP, ACTRES_PARADROP,
1205 TRUE, TRUE,
1206 MAK_TELEPORT,
1207 1,
1208 /* Still limited by each unit type's
1209 * paratroopers_range field. */
1210 ACTION_DISTANCE_MAX,
1211 FALSE);
1212 actions[ACTION_PARADROP_CONQUER] =
1213 unit_action_new(ACTION_PARADROP_CONQUER, ACTRES_PARADROP_CONQUER,
1214 TRUE, TRUE,
1215 MAK_TELEPORT,
1216 1,
1217 /* Still limited by each unit type's
1218 * paratroopers_range field. */
1219 ACTION_DISTANCE_MAX,
1220 FALSE);
1221 actions[ACTION_PARADROP_FRIGHTEN] =
1222 unit_action_new(ACTION_PARADROP_FRIGHTEN, ACTRES_PARADROP,
1223 TRUE, TRUE,
1224 MAK_TELEPORT,
1225 1,
1226 /* Still limited by each unit type's
1227 * paratroopers_range field. */
1228 ACTION_DISTANCE_MAX,
1229 FALSE);
1230 actions[ACTION_PARADROP_FRIGHTEN_CONQUER] =
1231 unit_action_new(ACTION_PARADROP_FRIGHTEN_CONQUER,
1232 ACTRES_PARADROP_CONQUER,
1233 TRUE, TRUE,
1234 MAK_TELEPORT,
1235 1,
1236 /* Still limited by each unit type's
1237 * paratroopers_range field. */
1238 ACTION_DISTANCE_MAX,
1239 FALSE);
1240 actions[ACTION_PARADROP_ENTER] =
1241 unit_action_new(ACTION_PARADROP_ENTER, ACTRES_PARADROP,
1242 TRUE, TRUE,
1243 MAK_TELEPORT,
1244 1,
1245 /* Still limited by each unit type's
1246 * paratroopers_range field. */
1247 ACTION_DISTANCE_MAX,
1248 FALSE);
1249 actions[ACTION_PARADROP_ENTER_CONQUER] =
1250 unit_action_new(ACTION_PARADROP_ENTER_CONQUER,
1251 ACTRES_PARADROP_CONQUER,
1252 TRUE, TRUE,
1253 MAK_TELEPORT,
1254 1,
1255 /* Still limited by each unit type's
1256 * paratroopers_range field. */
1257 ACTION_DISTANCE_MAX,
1258 FALSE);
1259 actions[ACTION_AIRLIFT] =
1260 unit_action_new(ACTION_AIRLIFT, ACTRES_AIRLIFT,
1261 TRUE, TRUE,
1262 MAK_TELEPORT,
1263 1,
1264 /* Overwritten by the ruleset's airlift_max_range. */
1265 ACTION_DISTANCE_UNLIMITED,
1266 FALSE);
1267 actions[ACTION_ATTACK] =
1268 unit_action_new(ACTION_ATTACK, ACTRES_ATTACK,
1269 FALSE, TRUE,
1270 /* Tries a forced move if the target unit's tile has
1271 * no non-allied units and the occupychance dice roll
1272 * tells it to move. */
1273 MAK_FORCED,
1274 1, 1, FALSE);
1275 actions[ACTION_ATTACK2] =
1276 unit_action_new(ACTION_ATTACK2, ACTRES_ATTACK,
1277 FALSE, TRUE,
1278 /* Tries a forced move if the target unit's tile has
1279 * no non-allied units and the occupychance dice roll
1280 * tells it to move. */
1281 MAK_FORCED,
1282 1, 1, FALSE);
1283 actions[ACTION_SUICIDE_ATTACK] =
1284 unit_action_new(ACTION_SUICIDE_ATTACK, ACTRES_ATTACK,
1285 FALSE, TRUE,
1286 MAK_FORCED, 1, 1, TRUE);
1287 actions[ACTION_SUICIDE_ATTACK2] =
1288 unit_action_new(ACTION_SUICIDE_ATTACK2, ACTRES_ATTACK,
1289 FALSE, TRUE,
1290 MAK_FORCED, 1, 1, TRUE);
1291 actions[ACTION_WIPE_UNITS] =
1292 unit_action_new(ACTION_WIPE_UNITS, ACTRES_WIPE_UNITS,
1293 FALSE, TRUE,
1294 MAK_FORCED,
1295 1, 1, FALSE);
1296 actions[ACTION_STRIKE_BUILDING] =
1297 unit_action_new(ACTION_STRIKE_BUILDING, ACTRES_STRIKE_BUILDING,
1298 FALSE, FALSE,
1299 MAK_STAYS, 1, 1, FALSE);
1300 actions[ACTION_STRIKE_PRODUCTION] =
1301 unit_action_new(ACTION_STRIKE_PRODUCTION, ACTRES_STRIKE_PRODUCTION,
1302 FALSE, FALSE,
1303 MAK_STAYS, 1, 1, FALSE);
1304 actions[ACTION_CONQUER_CITY] =
1305 unit_action_new(ACTION_CONQUER_CITY, ACTRES_CONQUER_CITY,
1306 FALSE, TRUE,
1307 MAK_REGULAR, 1, 1, FALSE);
1308 actions[ACTION_CONQUER_CITY2] =
1309 unit_action_new(ACTION_CONQUER_CITY2, ACTRES_CONQUER_CITY,
1310 FALSE, TRUE,
1311 MAK_REGULAR, 1, 1, FALSE);
1312 actions[ACTION_CONQUER_CITY3] =
1313 unit_action_new(ACTION_CONQUER_CITY3, ACTRES_CONQUER_CITY,
1314 FALSE, TRUE,
1315 MAK_REGULAR, 1, 1, FALSE);
1316 actions[ACTION_CONQUER_CITY4] =
1317 unit_action_new(ACTION_CONQUER_CITY4, ACTRES_CONQUER_CITY,
1318 FALSE, TRUE,
1319 MAK_REGULAR, 1, 1, FALSE);
1320 actions[ACTION_CONQUER_EXTRAS] =
1321 unit_action_new(ACTION_CONQUER_EXTRAS, ACTRES_CONQUER_EXTRAS,
1322 FALSE, TRUE,
1323 MAK_REGULAR, 1, 1, FALSE);
1324 actions[ACTION_CONQUER_EXTRAS2] =
1325 unit_action_new(ACTION_CONQUER_EXTRAS2, ACTRES_CONQUER_EXTRAS,
1326 FALSE, TRUE,
1327 MAK_REGULAR, 1, 1, FALSE);
1328 actions[ACTION_CONQUER_EXTRAS3] =
1329 unit_action_new(ACTION_CONQUER_EXTRAS3, ACTRES_CONQUER_EXTRAS,
1330 FALSE, TRUE,
1331 MAK_REGULAR, 1, 1, FALSE);
1332 actions[ACTION_CONQUER_EXTRAS4] =
1333 unit_action_new(ACTION_CONQUER_EXTRAS4, ACTRES_CONQUER_EXTRAS,
1334 FALSE, TRUE,
1335 MAK_REGULAR, 1, 1, FALSE);
1336 actions[ACTION_HEAL_UNIT] =
1337 unit_action_new(ACTION_HEAL_UNIT, ACTRES_HEAL_UNIT,
1338 FALSE, TRUE,
1339 MAK_STAYS, 0, 1, FALSE);
1340 actions[ACTION_HEAL_UNIT2] =
1341 unit_action_new(ACTION_HEAL_UNIT2, ACTRES_HEAL_UNIT,
1342 FALSE, TRUE,
1343 MAK_STAYS, 0, 1, FALSE);
1344 actions[ACTION_TRANSFORM_TERRAIN] =
1345 unit_action_new(ACTION_TRANSFORM_TERRAIN, ACTRES_TRANSFORM_TERRAIN,
1346 TRUE, FALSE,
1347 MAK_STAYS, 0, 0, FALSE);
1348 actions[ACTION_CULTIVATE] =
1349 unit_action_new(ACTION_CULTIVATE, ACTRES_CULTIVATE,
1350 TRUE, FALSE,
1351 MAK_STAYS, 0, 0, FALSE);
1352 actions[ACTION_PLANT] =
1353 unit_action_new(ACTION_PLANT, ACTRES_PLANT,
1354 TRUE, FALSE,
1355 MAK_STAYS, 0, 0, FALSE);
1356 actions[ACTION_PILLAGE] =
1357 unit_action_new(ACTION_PILLAGE, ACTRES_PILLAGE,
1358 TRUE, FALSE,
1359 MAK_STAYS, 0, 0, FALSE);
1360 actions[ACTION_CLEAN] =
1361 unit_action_new(ACTION_CLEAN, ACTRES_CLEAN,
1362 TRUE, FALSE,
1363 MAK_STAYS, 0, 0, FALSE);
1364 actions[ACTION_FORTIFY] =
1365 unit_action_new(ACTION_FORTIFY, ACTRES_FORTIFY,
1366 TRUE, FALSE,
1367 MAK_STAYS, 0, 0, FALSE);
1368 actions[ACTION_ROAD] =
1369 unit_action_new(ACTION_ROAD, ACTRES_ROAD,
1370 TRUE, FALSE,
1371 MAK_STAYS, 0, 0, FALSE);
1372 actions[ACTION_CONVERT] =
1373 unit_action_new(ACTION_CONVERT, ACTRES_CONVERT,
1374 TRUE, FALSE,
1375 MAK_STAYS, 0, 0, FALSE);
1376 actions[ACTION_BASE] =
1377 unit_action_new(ACTION_BASE, ACTRES_BASE,
1378 TRUE, FALSE,
1379 MAK_STAYS, 0, 0, FALSE);
1380 actions[ACTION_MINE] =
1381 unit_action_new(ACTION_MINE, ACTRES_MINE,
1382 TRUE, FALSE,
1383 MAK_STAYS, 0, 0, FALSE);
1384 actions[ACTION_IRRIGATE] =
1385 unit_action_new(ACTION_IRRIGATE, ACTRES_IRRIGATE,
1386 TRUE, FALSE,
1387 MAK_STAYS, 0, 0, FALSE);
1388 actions[ACTION_TRANSPORT_DEBOARD] =
1389 unit_action_new(ACTION_TRANSPORT_DEBOARD, ACTRES_TRANSPORT_DEBOARD,
1390 TRUE, FALSE,
1391 MAK_STAYS, 0, 0, FALSE);
1392 actions[ACTION_TRANSPORT_BOARD] =
1393 unit_action_new(ACTION_TRANSPORT_BOARD, ACTRES_TRANSPORT_BOARD,
1394 TRUE, FALSE,
1395 MAK_STAYS, 0, 0, FALSE);
1396 actions[ACTION_TRANSPORT_BOARD2] =
1397 unit_action_new(ACTION_TRANSPORT_BOARD2, ACTRES_TRANSPORT_BOARD,
1398 TRUE, FALSE,
1399 MAK_STAYS, 0, 0, FALSE);
1400 actions[ACTION_TRANSPORT_BOARD3] =
1401 unit_action_new(ACTION_TRANSPORT_BOARD3, ACTRES_TRANSPORT_BOARD,
1402 TRUE, FALSE,
1403 MAK_STAYS, 0, 0, FALSE);
1404 actions[ACTION_TRANSPORT_UNLOAD] =
1405 unit_action_new(ACTION_TRANSPORT_UNLOAD, ACTRES_TRANSPORT_UNLOAD,
1406 TRUE, FALSE,
1407 MAK_STAYS, 0, 0, FALSE);
1408 actions[ACTION_TRANSPORT_LOAD] =
1409 unit_action_new(ACTION_TRANSPORT_LOAD, ACTRES_TRANSPORT_LOAD,
1410 TRUE, FALSE,
1411 MAK_STAYS, 0, 0, FALSE);
1412 actions[ACTION_TRANSPORT_LOAD2] =
1413 unit_action_new(ACTION_TRANSPORT_LOAD2, ACTRES_TRANSPORT_LOAD,
1414 TRUE, FALSE,
1415 MAK_STAYS, 0, 0, FALSE);
1416 actions[ACTION_TRANSPORT_LOAD3] =
1417 unit_action_new(ACTION_TRANSPORT_LOAD3, ACTRES_TRANSPORT_LOAD,
1418 TRUE, FALSE,
1419 MAK_STAYS, 0, 0, FALSE);
1420 actions[ACTION_TRANSPORT_DISEMBARK1] =
1421 unit_action_new(ACTION_TRANSPORT_DISEMBARK1,
1422 ACTRES_TRANSPORT_DISEMBARK,
1423 FALSE, TRUE,
1424 MAK_REGULAR, 1, 1, FALSE);
1425 actions[ACTION_TRANSPORT_DISEMBARK2] =
1426 unit_action_new(ACTION_TRANSPORT_DISEMBARK2,
1427 ACTRES_TRANSPORT_DISEMBARK,
1428 FALSE, TRUE,
1429 MAK_REGULAR, 1, 1, FALSE);
1430 actions[ACTION_TRANSPORT_DISEMBARK3] =
1431 unit_action_new(ACTION_TRANSPORT_DISEMBARK3,
1432 ACTRES_TRANSPORT_DISEMBARK,
1433 FALSE, TRUE,
1434 MAK_REGULAR, 1, 1, FALSE);
1435 actions[ACTION_TRANSPORT_DISEMBARK4] =
1436 unit_action_new(ACTION_TRANSPORT_DISEMBARK4,
1437 ACTRES_TRANSPORT_DISEMBARK,
1438 FALSE, TRUE,
1439 MAK_REGULAR, 1, 1, FALSE);
1440 actions[ACTION_TRANSPORT_EMBARK] =
1441 unit_action_new(ACTION_TRANSPORT_EMBARK, ACTRES_TRANSPORT_EMBARK,
1442 TRUE, TRUE,
1443 MAK_REGULAR, 1, 1, FALSE);
1444 actions[ACTION_TRANSPORT_EMBARK2] =
1445 unit_action_new(ACTION_TRANSPORT_EMBARK2, ACTRES_TRANSPORT_EMBARK,
1446 TRUE, TRUE,
1447 MAK_REGULAR, 1, 1, FALSE);
1448 actions[ACTION_TRANSPORT_EMBARK3] =
1449 unit_action_new(ACTION_TRANSPORT_EMBARK3, ACTRES_TRANSPORT_EMBARK,
1450 TRUE, TRUE,
1451 MAK_REGULAR, 1, 1, FALSE);
1452 actions[ACTION_TRANSPORT_EMBARK4] =
1453 unit_action_new(ACTION_TRANSPORT_EMBARK4, ACTRES_TRANSPORT_EMBARK,
1454 TRUE, TRUE,
1455 MAK_REGULAR, 1, 1, FALSE);
1456 actions[ACTION_SPY_ATTACK] =
1457 unit_action_new(ACTION_SPY_ATTACK, ACTRES_SPY_ATTACK,
1458 FALSE, TRUE,
1459 MAK_STAYS, 1, 1, FALSE);
1460 actions[ACTION_HUT_ENTER] =
1461 unit_action_new(ACTION_HUT_ENTER, ACTRES_HUT_ENTER,
1462 FALSE, TRUE,
1463 MAK_REGULAR, 1, 1, FALSE);
1464 actions[ACTION_HUT_ENTER2] =
1465 unit_action_new(ACTION_HUT_ENTER2, ACTRES_HUT_ENTER,
1466 FALSE, TRUE,
1467 MAK_REGULAR, 1, 1, FALSE);
1468 actions[ACTION_HUT_ENTER3] =
1469 unit_action_new(ACTION_HUT_ENTER3, ACTRES_HUT_ENTER,
1470 FALSE, TRUE,
1471 MAK_REGULAR, 1, 1, FALSE);
1472 actions[ACTION_HUT_ENTER4] =
1473 unit_action_new(ACTION_HUT_ENTER4, ACTRES_HUT_ENTER,
1474 FALSE, TRUE,
1475 MAK_REGULAR, 1, 1, FALSE);
1476 actions[ACTION_HUT_FRIGHTEN] =
1477 unit_action_new(ACTION_HUT_FRIGHTEN, ACTRES_HUT_FRIGHTEN,
1478 FALSE, TRUE,
1479 MAK_REGULAR, 1, 1, FALSE);
1480 actions[ACTION_HUT_FRIGHTEN2] =
1481 unit_action_new(ACTION_HUT_FRIGHTEN2, ACTRES_HUT_FRIGHTEN,
1482 FALSE, TRUE,
1483 MAK_REGULAR, 1, 1, FALSE);
1484 actions[ACTION_HUT_FRIGHTEN3] =
1485 unit_action_new(ACTION_HUT_FRIGHTEN3, ACTRES_HUT_FRIGHTEN,
1486 FALSE, TRUE,
1487 MAK_REGULAR, 1, 1, FALSE);
1488 actions[ACTION_HUT_FRIGHTEN4] =
1489 unit_action_new(ACTION_HUT_FRIGHTEN4, ACTRES_HUT_FRIGHTEN,
1490 FALSE, TRUE,
1491 MAK_REGULAR, 1, 1, FALSE);
1492 actions[ACTION_UNIT_MOVE] =
1493 unit_action_new(ACTION_UNIT_MOVE, ACTRES_UNIT_MOVE,
1494 TRUE, TRUE,
1495 MAK_REGULAR, 1, 1, FALSE);
1496 actions[ACTION_UNIT_MOVE2] =
1497 unit_action_new(ACTION_UNIT_MOVE2, ACTRES_UNIT_MOVE,
1498 TRUE, TRUE,
1499 MAK_REGULAR, 1, 1, FALSE);
1500 actions[ACTION_UNIT_MOVE3] =
1501 unit_action_new(ACTION_UNIT_MOVE3, ACTRES_UNIT_MOVE,
1502 TRUE, TRUE,
1503 MAK_REGULAR, 1, 1, FALSE);
1504 actions[ACTION_TELEPORT] =
1505 unit_action_new(ACTION_TELEPORT, ACTRES_TELEPORT,
1506 TRUE, TRUE,
1507 MAK_TELEPORT, 1, 1, FALSE);
1508 actions[ACTION_TELEPORT_CONQUER] =
1509 unit_action_new(ACTION_TELEPORT_CONQUER, ACTRES_TELEPORT_CONQUER,
1510 TRUE, TRUE,
1511 MAK_TELEPORT, 1,
1512 ACTION_DISTANCE_MAX, FALSE);
1513 actions[ACTION_TELEPORT_FRIGHTEN] =
1514 unit_action_new(ACTION_TELEPORT_FRIGHTEN,
1515 ACTRES_TELEPORT,
1516 TRUE, TRUE,
1517 MAK_TELEPORT, 1,
1518 ACTION_DISTANCE_MAX, FALSE);
1519 actions[ACTION_TELEPORT_FRIGHTEN_CONQUER] =
1520 unit_action_new(ACTION_TELEPORT_FRIGHTEN_CONQUER,
1521 ACTRES_TELEPORT_CONQUER,
1522 TRUE, TRUE,
1523 MAK_TELEPORT, 1,
1524 ACTION_DISTANCE_MAX, FALSE);
1525 actions[ACTION_TELEPORT_ENTER] =
1526 unit_action_new(ACTION_TELEPORT_ENTER,
1527 ACTRES_TELEPORT,
1528 TRUE, TRUE,
1529 MAK_TELEPORT, 1,
1530 ACTION_DISTANCE_MAX, FALSE);
1531 actions[ACTION_TELEPORT_ENTER_CONQUER] =
1532 unit_action_new(ACTION_TELEPORT_ENTER_CONQUER,
1533 ACTRES_TELEPORT_CONQUER,
1534 TRUE, TRUE,
1535 MAK_TELEPORT, 1,
1536 ACTION_DISTANCE_MAX, FALSE);
1537 actions[ACTION_USER_ACTION1] =
1538 unit_action_new(ACTION_USER_ACTION1, ACTRES_NONE,
1539 FALSE, TRUE,
1540 MAK_UNREPRESENTABLE,
1541 /* Overwritten by the ruleset */
1542 0, 1, FALSE);
1543 actions[ACTION_USER_ACTION2] =
1544 unit_action_new(ACTION_USER_ACTION2, ACTRES_NONE,
1545 FALSE, TRUE,
1546 MAK_UNREPRESENTABLE,
1547 /* Overwritten by the ruleset */
1548 0, 1, FALSE);
1549 actions[ACTION_USER_ACTION3] =
1550 unit_action_new(ACTION_USER_ACTION3, ACTRES_NONE,
1551 FALSE, TRUE,
1552 MAK_UNREPRESENTABLE,
1553 /* Overwritten by the ruleset */
1554 0, 1, FALSE);
1555 actions[ACTION_USER_ACTION4] =
1556 unit_action_new(ACTION_USER_ACTION4, ACTRES_NONE,
1557 FALSE, TRUE,
1558 MAK_UNREPRESENTABLE,
1559 /* Overwritten by the ruleset */
1560 0, 1, FALSE);
1561 actions[ACTION_COLLECT_RANSOM] =
1562 unit_action_new(ACTION_COLLECT_RANSOM, ACTRES_COLLECT_RANSOM,
1563 FALSE, TRUE,
1564 /* Tries a forced move if the target unit's tile has
1565 * no non-allied units and the occupychance dice roll
1566 * tells it to move. */
1567 MAK_FORCED,
1568 1, 1, FALSE);
1569
1570 /* The structure even for these need to be created, for
1571 * the action_id_rule_name() to work on iterations. */
1572
1573 /*
1574 actions[ACTION_UNUSED_1]
1575 = unit_action_new(ACTION_UNUSED_1, ACTRES_NONE,
1576 FALSE, FALSE,
1577 MAK_UNREPRESENTABLE,
1578 0, 0, FALSE);
1579 */
1580}
1581
1582/**********************************************************************/
1585 void actions_init(void)
1586{
1587 int i, j;
1588
1589 for (i = 0; i < ACTRES_LAST; i++) {
1590 actlist_by_result[i] = action_list_new();
1591 }
1592 for (i = 0; i < ACTIVITY_LAST; i++) {
1593 actlist_by_activity[i] = action_list_new();
1594 }
1595
1596 /* Hard code the actions */
1597 hard_code_actions();
1598
1599 /* Initialize the action enabler list */
1600 action_iterate_all(act) {
1601 action_enablers_by_action[act] = action_enabler_list_new();
1602 } action_iterate_all_end;
1603
1604 /* Initialize action obligatory hard requirements. */
1605
1606 /* Obligatory hard requirements sorted by action result in memory. */
1607 for (i = 0; i < ACTRES_NONE; i++) {
1608 /* Prepare each action result's storage area. */
1609 obligatory_req_vector_init(&oblig_hard_reqs_r[i]);
1610 }
1611
1612 /* Obligatory hard requirements sorted by action sub result in memory. */
1613 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
1614 /* Prepare each action sub result's storage area. */
1615 obligatory_req_vector_init(&oblig_hard_reqs_sr[i]);
1616 }
1617
1618 /* Obligatory hard requirements are sorted by requirement in the source
1619 * code. This makes it easy to read, modify and explain it. */
1620 hard_code_oblig_hard_reqs();
1621
1622 /* Initialize the action auto performers. */
1623 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
1624 /* Nothing here. Nothing after this point. */
1625 auto_perfs[i].cause = AAPC_COUNT;
1626
1627 /* The criteria to pick *this* auto performer for its cause. */
1628 requirement_vector_init(&auto_perfs[i].reqs);
1629
1630 for (j = 0; j < MAX_NUM_ACTIONS; j++) {
1631 /* Nothing here. Nothing after this point. */
1632 auto_perfs[i].alternatives[j] = ACTION_NONE;
1633 }
1634 }
1635
1636 /* The actions them self are now initialized. */
1637 actions_initialized = TRUE;
1638}
1639
1640/**********************************************************************/
1645 void actions_rs_pre_san_gen(void)
1646{
1647 /* Some obligatory hard requirements needs access to the rest of the
1648 * ruleset. */
1649 hard_code_oblig_hard_reqs_ruleset();
1650}
1651
1652/**********************************************************************/
1655 void actions_free(void)
1656{
1657 int i;
1658
1659 /* Don't consider the actions to be initialized any longer. */
1660 actions_initialized = FALSE;
1661
1662 action_iterate_all(act) {
1663 action_enabler_list_iterate(action_enablers_by_action[act], enabler) {
1664 action_enabler_free(enabler);
1665 } action_enabler_list_iterate_end;
1666
1667 action_enabler_list_destroy(action_enablers_by_action[act]);
1668
1669 FC_FREE(actions[act]);
1670 } action_iterate_all_end;
1671
1672 /* Free the obligatory hard action requirements. */
1673 for (i = 0; i < ACTRES_NONE; i++) {
1674 obligatory_req_vector_iterate(&oblig_hard_reqs_r[i], oreq) {
1675 ae_contra_close(oreq->contras);
1676 } obligatory_req_vector_iterate_end;
1677 obligatory_req_vector_free(&oblig_hard_reqs_r[i]);
1678 }
1679 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
1680 obligatory_req_vector_iterate(&oblig_hard_reqs_sr[i], oreq) {
1681 ae_contra_close(oreq->contras);
1682 } obligatory_req_vector_iterate_end;
1683 obligatory_req_vector_free(&oblig_hard_reqs_sr[i]);
1684 }
1685
1686 /* Free the action auto performers. */
1687 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
1688 requirement_vector_free(&auto_perfs[i].reqs);
1689 }
1690
1691 astr_free(&ui_name_str);
1692
1693 for (i = 0; i < ACTRES_LAST; i++) {
1694 action_list_destroy(actlist_by_result[i]);
1695 actlist_by_result[i] = NULL;
1696 }
1697 for (i = 0; i < ACTIVITY_LAST; i++) {
1698 action_list_destroy(actlist_by_activity[i]);
1699 actlist_by_activity[i] = NULL;
1700 }
1701}
1702
1703/**********************************************************************/
1708 bool actions_are_ready(void)
1709{
1710 if (!actions_initialized) {
1711 /* The actions them self aren't initialized yet. */
1712 return FALSE;
1713 }
1714
1715 action_iterate(act) {
1716 if (actions[act]->ui_name[0] == '\0') {
1717 /* An action without a UI name exists means that the ruleset haven't
1718 * loaded yet. The ruleset loading will assign a default name to
1719 * any actions not named by the ruleset. The client will get this
1720 * name from the server. */
1721 return FALSE;
1722 }
1723 } action_iterate_end;
1724
1725 /* The actions should be ready for use. */
1726 return TRUE;
1727}
1728
1729/**********************************************************************/
1732 static struct action *action_new(action_id id,
1733 enum action_result result,
1734 const int min_distance,
1735 const int max_distance,
1736 bool actor_consuming_always)
1737{
1738 struct action *action;
1739
1740 action = fc_malloc(sizeof(*action));
1741
1742 action->id = id;
1743
1744 action->result = result;
1745
1746 if (result != ACTRES_LAST) {
1747 enum unit_activity act = actres_activity_result(result);
1748
1749 action_list_append(actlist_by_result[result], action);
1750
1751 if (act != ACTIVITY_LAST) {
1752 action_list_append(actlist_by_activity[act], action);
1753 }
1754 }
1755
1756 /* Not set here */
1757 BV_CLR_ALL(action->sub_results);
1758
1759 action->actor_kind = AAK_UNIT;
1760 action->target_kind = actres_target_kind_default(result);
1761 action->sub_target_kind = actres_sub_target_kind_default(result);
1762 action->target_complexity = actres_target_compl_calc(result);
1763
1764 /* ASTK_NONE implies ACT_TGT_COMPL_SIMPLE and
1765 * !ASTK_NONE implies !ACT_TGT_COMPL_SIMPLE */
1766 fc_assert_msg(((action->sub_target_kind == ASTK_NONE
1767 && action->target_complexity == ACT_TGT_COMPL_SIMPLE)
1768 || (action->sub_target_kind != ASTK_NONE
1769 && action->target_complexity != ACT_TGT_COMPL_SIMPLE)),
1770 "%s contradicts itself regarding sub targets.",
1771 action_rule_name(action));
1772
1773 /* The distance between the actor and itself is always 0. */
1774 fc_assert(action->target_kind != ATK_SELF
1775 || (min_distance == 0 && max_distance == 0));
1776
1777 action->min_distance = min_distance;
1778 action->max_distance = max_distance;
1779
1780 action->actor_consuming_always = actor_consuming_always;
1781
1782 /* Loaded from the ruleset. Until generalized actions are ready it has to
1783 * be defined separately from other action data. */
1784 action->ui_name[0] = '\0';
1785 action->quiet = FALSE;
1786 BV_CLR_ALL(action->blocked_by);
1787
1788 return action;
1789}
1790
1791/**********************************************************************/
1794static struct action *
1795unit_action_new(action_id id,
1796 enum action_result result,
1797 bool rare_pop_up,
1798 bool unitwaittime_controlled,
1799 enum moves_actor_kind moves_actor,
1800 const int min_distance,
1801 const int max_distance,
1802 bool actor_consuming_always)
1803{
1804 struct action *act = action_new(id, result,
1805 min_distance, max_distance,
1806 actor_consuming_always);
1807
1808 act->actor.is_unit.rare_pop_up = rare_pop_up;
1809
1810 act->actor.is_unit.unitwaittime_controlled = unitwaittime_controlled;
1811
1812 act->actor.is_unit.moves_actor = moves_actor;
1813
1814 return act;
1815}
1816
1817/**********************************************************************/
1820 bool action_id_exists(const action_id act_id)
1821{
1822 /* Actions are still hard coded. */
1823 return gen_action_is_valid(act_id) && actions[act_id];
1824}
1825
1826/**********************************************************************/
1831 struct action *action_by_rule_name(const char *name)
1832{
1833 /* Actions are still hard coded in the gen_action enum. */
1834 action_id act_id = gen_action_by_name(name, fc_strcasecmp);
1835
1836 if (!action_id_exists(act_id)) {
1837 /* Nothing to return. */
1838
1839 log_verbose("Asked for non existing action named %s", name);
1840
1841 return NULL;
1842 }
1843
1844 return action_by_number(act_id);
1845}
1846
1847/**********************************************************************/
1850 enum action_actor_kind action_get_actor_kind(const struct action *paction)
1851{
1852 fc_assert_ret_val_msg(paction, AAK_COUNT, "Action doesn't exist.");
1853
1854 return paction->actor_kind;
1855}
1856
1857/**********************************************************************/
1860 enum action_target_kind action_get_target_kind(
1861 const struct action *paction)
1862{
1863 fc_assert_ret_val_msg(paction, ATK_COUNT, "Action doesn't exist.");
1864
1865 return paction->target_kind;
1866}
1867
1868/**********************************************************************/
1871 enum action_sub_target_kind action_get_sub_target_kind(
1872 const struct action *paction)
1873{
1874 fc_assert_ret_val_msg(paction, ASTK_COUNT, "Action doesn't exist.");
1875
1876 return paction->sub_target_kind;
1877}
1878
1879/**********************************************************************/
1884 bool action_has_complex_target(const struct action *paction)
1885{
1886 fc_assert_ret_val(paction != NULL, FALSE);
1887
1888 return paction->target_complexity >= ACT_TGT_COMPL_FLEXIBLE;
1889}
1890
1891/**********************************************************************/
1897 bool action_requires_details(const struct action *paction)
1898{
1899 fc_assert_ret_val(paction != NULL, FALSE);
1900
1901 return paction->target_complexity >= ACT_TGT_COMPL_MANDATORY;
1902}
1903
1904/**********************************************************************/
1912 bool action_id_is_rare_pop_up(action_id act_id)
1913{
1914 fc_assert_ret_val_msg((action_id_exists(act_id)),
1915 FALSE, "Action %d don't exist.", act_id);
1916 fc_assert_ret_val(action_id_get_actor_kind(act_id) == AAK_UNIT, FALSE);
1917
1918 return actions[act_id]->actor.is_unit.rare_pop_up;
1919}
1920
1921/**********************************************************************/
1925 bool action_distance_inside_max(const struct action *action,
1926 const int distance)
1927{
1928 return (distance <= action-> max_distance
1929 || action->max_distance == ACTION_DISTANCE_UNLIMITED);
1930}
1931
1932/**********************************************************************/
1936 bool action_distance_accepted(const struct action *action,
1937 const int distance)
1938{
1939 fc_assert_ret_val(action, FALSE);
1940
1941 return (distance >= action->min_distance
1942 && action_distance_inside_max(action, distance));
1943}
1944
1945/**********************************************************************/
1948 bool action_would_be_blocked_by(const struct action *blocked,
1949 const struct action *blocker)
1950{
1951 fc_assert_ret_val(blocked, FALSE);
1952 fc_assert_ret_val(blocker, FALSE);
1953
1954 return BV_ISSET(blocked->blocked_by, action_number(blocker));
1955}
1956
1957/**********************************************************************/
1960 int action_number(const struct action *action)
1961{
1962 return action->id;
1963}
1964
1965/**********************************************************************/
1968 const char *action_rule_name(const struct action *action)
1969{
1970 /* Rule name is still hard coded. */
1971 return action_id_rule_name(action->id);
1972}
1973
1974/**********************************************************************/
1982 const char *action_name_translation(const struct action *action)
1983{
1984 /* Use action_id_name_translation() to format the UI name. */
1985 return action_id_name_translation(action->id);
1986}
1987
1988/**********************************************************************/
1991 const char *action_id_rule_name(action_id act_id)
1992{
1993 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
1994
1995 return gen_action_name(act_id);
1996}
1997
1998/**********************************************************************/
2002 const char *action_id_name_translation(action_id act_id)
2003{
2004 return action_prepare_ui_name(act_id, "", ACTPROB_NA, NULL);
2005}
2006
2007/**********************************************************************/
2010 const char *action_get_ui_name_mnemonic(action_id act_id,
2011 const char *mnemonic)
2012{
2013 return action_prepare_ui_name(act_id, mnemonic, ACTPROB_NA, NULL);
2014}
2015
2016/**********************************************************************/
2023 static const char *action_prob_to_text(const struct act_prob prob)
2024{
2025 static struct astring chance = ASTRING_INIT;
2026
2027 /* How to interpret action probabilities like prob is documented in
2028 * fc_types.h */
2029 if (action_prob_is_signal(prob)) {
2030 fc_assert(action_prob_not_impl(prob)
2031 || action_prob_not_relevant(prob));
2032
2033 /* Unknown because of missing server support or should not exits. */
2034 return NULL;
2035 }
2036
2037 if (prob.min == prob.max) {
2038 /* Only one probability in range. */
2039
2040 /* TRANS: the probability that an action will succeed. Given in
2041 * percentage. Resolution is 0.5%. */
2042 astr_set(&chance, _("%.1f%%"), (double)prob.max / ACTPROB_VAL_1_PCT);
2043 } else {
2044 /* TRANS: the interval (end points included) where the probability of
2045 * the action's success is. Given in percentage. Resolution is 0.5%. */
2046 astr_set(&chance, _("[%.1f%%, %.1f%%]"),
2047 (double)prob.min / ACTPROB_VAL_1_PCT,
2048 (double)prob.max / ACTPROB_VAL_1_PCT);
2049 }
2050
2051 return astr_str(&chance);
2052}
2053
2054/**********************************************************************/
2064 const char *action_prepare_ui_name(action_id act_id, const char *mnemonic,
2065 const struct act_prob prob,
2066 const char *custom)
2067{
2068 struct astring chance = ASTRING_INIT;
2069
2070 /* Text representation of the probability. */
2071 const char *probtxt;
2072
2073 if (!actions_are_ready()) {
2074 /* Could be a client who haven't gotten the ruleset yet */
2075
2076 /* so there shouldn't be any action probability to show */
2077 fc_assert(action_prob_not_relevant(prob));
2078
2079 /* but the action should be valid */
2080 fc_assert_ret_val_msg(action_id_exists(act_id),
2081 "Invalid action",
2082 "Invalid action %d", act_id);
2083
2084 /* and no custom text will be inserted */
2085 fc_assert(custom == NULL || custom[0] == '\0');
2086
2087 /* Make the best of what is known */
2088 astr_set(&ui_name_str, _("%s%s (name may be wrong)"),
2089 mnemonic, action_id_rule_name(act_id));
2090
2091 /* Return the guess. */
2092 return astr_str(&ui_name_str);
2093 }
2094
2095 probtxt = action_prob_to_text(prob);
2096
2097 /* Format the info part of the action's UI name. */
2098 if (probtxt != NULL && custom != NULL) {
2099 /* TRANS: action UI name's info part with custom info and probability.
2100 * Hint: you can move the paren handling from this sting to the action
2101 * names if you need to add extra information (like a mnemonic letter
2102 * that doesn't appear in the action UI name) to it. In that case you
2103 * must do so for all strings with this comment and for every action
2104 * name. To avoid a `()` when no UI name info part is added you have
2105 * to add the extra information to every action name or remove the
2106 * surrounding parens. */
2107 astr_set(&chance, _(" (%s; %s)"), custom, probtxt);
2108 } else if (probtxt != NULL) {
2109 /* TRANS: action UI name's info part with probability.
2110 * Hint: you can move the paren handling from this sting to the action
2111 * names if you need to add extra information (like a mnemonic letter
2112 * that doesn't appear in the action UI name) to it. In that case you
2113 * must do so for all strings with this comment and for every action
2114 * name. To avoid a `()` when no UI name info part is added you have
2115 * to add the extra information to every action name or remove the
2116 * surrounding parens. */
2117 astr_set(&chance, _(" (%s)"), probtxt);
2118 } else if (custom != NULL) {
2119 /* TRANS: action UI name's info part with custom info.
2120 * Hint: you can move the paren handling from this sting to the action
2121 * names if you need to add extra information (like a mnemonic letter
2122 * that doesn't appear in the action UI name) to it. In that case you
2123 * must do so for all strings with this comment and for every action
2124 * name. To avoid a `()` when no UI name info part is added you have
2125 * to add the extra information to every action name or remove the
2126 * surrounding parens. */
2127 astr_set(&chance, _(" (%s)"), custom);
2128 } else {
2129 /* No info part to display. */
2130 astr_clear(&chance);
2131 }
2132
2133 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
2134
2135 /* Escape any instances of the mnemonic in the action's UI format string.
2136 * (Assumes any mnemonic can be escaped by doubling, and that they are
2137 * unlikely to appear in a format specifier. True for clients seen so
2138 * far: Gtk's _ and Qt's &) */
2139 {
2140 struct astring fmtstr = ASTRING_INIT;
2141 const char *ui_name = _(actions[act_id]->ui_name);
2142
2143 if (mnemonic[0] != '\0') {
2144 const char *hit;
2145
2146 fc_assert(!strchr(mnemonic, '%'));
2147 while ((hit = strstr(ui_name, mnemonic))) {
2148 astr_add(&fmtstr, "%.*s%s%s", (int)(hit - ui_name), ui_name,
2149 mnemonic, mnemonic);
2150 ui_name = hit + strlen(mnemonic);
2151 }
2152 }
2153 astr_add(&fmtstr, "%s", ui_name);
2154
2155 /* Use the modified format string */
2156 astr_set(&ui_name_str, astr_str(&fmtstr), mnemonic,
2157 astr_str(&chance));
2158
2159 astr_free(&fmtstr);
2160 }
2161
2162 astr_free(&chance);
2163
2164 return astr_str(&ui_name_str);
2165}
2166
2167/**********************************************************************/
2175 const char *action_prob_explain(const struct act_prob prob)
2176{
2177 static struct astring tool_tip = ASTRING_INIT;
2178
2179 if (action_prob_is_signal(prob)) {
2180 fc_assert(action_prob_not_impl(prob));
2181
2182 /* Missing server support. No in game action will change this. */
2183 astr_clear(&tool_tip);
2184 } else if (prob.min == prob.max) {
2185 /* TRANS: action probability of success. Given in percentage.
2186 * Resolution is 0.5%. */
2187 astr_set(&tool_tip, _("The probability of success is %.1f%%."),
2188 (double)prob.max / ACTPROB_VAL_1_PCT);
2189 } else {
2190 astr_set(&tool_tip,
2191 /* TRANS: action probability interval (min to max). Given in
2192 * percentage. Resolution is 0.5%. The string at the end is
2193 * shown when the interval is wide enough to not be caused by
2194 * rounding. It explains that the interval is imprecise because
2195 * the player doesn't have enough information. */
2196 _("The probability of success is %.1f%%, %.1f%% or somewhere"
2197 " in between.%s"),
2198 (double)prob.min / ACTPROB_VAL_1_PCT,
2199 (double)prob.max / ACTPROB_VAL_1_PCT,
2200 prob.max - prob.min > 1 ?
2201 /* TRANS: explanation used in the action probability tooltip
2202 * above. Preserve leading space. */
2203 _(" (This is the most precise interval I can calculate "
2204 "given the information our nation has access to.)") :
2205 "");
2206 }
2207
2208 return astr_str(&tool_tip);
2209}
2210
2211/**********************************************************************/
2215 int action_get_role(const struct action *paction)
2216{
2217 fc_assert_msg(AAK_UNIT == action_get_actor_kind(paction),
2218 "Action %s isn't performed by a unit",
2219 action_rule_name(paction));
2220
2221 return paction->id + L_LAST;
2222}
2223
2224/**********************************************************************/
2227 struct action_enabler *action_enabler_new(void)
2228{
2229 struct action_enabler *enabler;
2230
2231 enabler = fc_malloc(sizeof(*enabler));
2232 enabler->ruledit_disabled = FALSE;
2233 requirement_vector_init(&enabler->actor_reqs);
2234 requirement_vector_init(&enabler->target_reqs);
2235
2236 /* Make sure that action doesn't end up as a random value that happens to
2237 * be a valid action id. */
2238 enabler->action = ACTION_NONE;
2239
2240 return enabler;
2241}
2242
2243/**********************************************************************/
2246 void action_enabler_free(struct action_enabler *enabler)
2247{
2248 requirement_vector_free(&enabler->actor_reqs);
2249 requirement_vector_free(&enabler->target_reqs);
2250
2251 free(enabler);
2252}
2253
2254/**********************************************************************/
2257struct action_enabler *
2258action_enabler_copy(const struct action_enabler *original)
2259{
2260 struct action_enabler *enabler = action_enabler_new();
2261
2262 enabler->action = original->action;
2263
2264 requirement_vector_copy(&enabler->actor_reqs, &original->actor_reqs);
2265 requirement_vector_copy(&enabler->target_reqs, &original->target_reqs);
2266
2267 return enabler;
2268}
2269
2270/**********************************************************************/
2273 void action_enabler_add(struct action_enabler *enabler)
2274{
2275 /* Sanity check: a non existing action enabler can't be added. */
2276 fc_assert_ret(enabler);
2277 /* Sanity check: a non existing action doesn't have enablers. */
2278 fc_assert_ret(action_id_exists(enabler_get_action_id(enabler)));
2279
2280 action_enabler_list_append(
2281 action_enablers_for_action(enabler_get_action_id(enabler)),
2282 enabler);
2283}
2284
2285/**********************************************************************/
2290 bool action_enabler_remove(struct action_enabler *enabler)
2291{
2292 /* Sanity check: a non existing action enabler can't be removed. */
2293 fc_assert_ret_val(enabler, FALSE);
2294 /* Sanity check: a non existing action doesn't have enablers. */
2295 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), FALSE);
2296
2297 return action_enabler_list_remove(
2298 action_enablers_for_action(enabler_get_action_id(enabler)),
2299 enabler);
2300}
2301
2302/**********************************************************************/
2305struct action_enabler_list *
2306action_enablers_for_action(action_id action)
2307{
2308 /* Sanity check: a non existing action doesn't have enablers. */
2309 fc_assert_ret_val(action_id_exists(action), NULL);
2310
2311 return action_enablers_by_action[action];
2312}
2313
2314/**********************************************************************/
2325static struct req_vec_problem *
2326ae_suggest_repair_if_no_oblig(const struct action_enabler *enabler,
2327 const struct obligatory_req_vector *oblig)
2328{
2329 struct action *paction;
2330
2331 /* Sanity check: a non existing action enabler is missing but it doesn't
2332 * miss any obligatory hard requirements. */
2333 fc_assert_ret_val(enabler, NULL);
2334
2335 /* Sanity check: a non existing action doesn't have any obligatory hard
2336 * requirements. */
2337 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), NULL);
2338 paction = enabler_get_action(enabler);
2339
2340 /* No obligatory hard requirements. */
2341 fc_assert_ret_val(oblig, NULL);
2342
2343 obligatory_req_vector_iterate(oblig, obreq) {
2344 struct req_vec_problem *out;
2345 int i;
2346 bool fulfilled = FALSE;
2347
2348 /* Check each alternative. */
2349 for (i = 0; i < obreq->contras->alternatives; i++) {
2350 const struct requirement_vector *ae_vec;
2351
2352 /* Select action enabler requirement vector. */
2353 ae_vec = (obreq->contras->alternative[i].is_target
2354 ? &enabler->target_reqs
2355 : &enabler->actor_reqs);
2356
2357 if (does_req_contradicts_reqs(&obreq->contras->alternative[i].req,
2358 ae_vec)
2359 /* Consider the hard requirement fulfilled since a universal that
2360 * never is there always will be absent in this ruleset. */
2361 || (obreq->contras->alternative[i].req.present
2362 && universal_never_there(
2363 &obreq->contras->alternative[i].req.source))) {
2364 /* It is enough that one alternative accepts the enabler. */
2365 fulfilled = TRUE;
2366 break;
2367 }
2368
2369 /* Fall back to the next alternative */
2370 }
2371
2372 if (fulfilled) {
2373 /* This obligatory hard requirement isn't a problem. */
2374 continue;
2375 }
2376
2377 /* Missing hard obligatory requirement detected */
2378
2379 out = req_vec_problem_new(obreq->contras->alternatives,
2380 obreq->error_msg,
2381 action_rule_name(paction));
2382
2383 for (i = 0; i < obreq->contras->alternatives; i++) {
2384 const struct requirement_vector *ae_vec;
2385
2386 /* Select action enabler requirement vector. */
2387 ae_vec = (obreq->contras->alternative[i].is_target
2388 ? &enabler->target_reqs
2389 : &enabler->actor_reqs);
2390
2391 /* The suggested fix is to append a requirement that makes the enabler
2392 * contradict the missing hard obligatory requirement detector. */
2393 out->suggested_solutions[i].operation = RVCO_APPEND;
2394 out->suggested_solutions[i].vector_number
2395 = action_enabler_vector_number(enabler, ae_vec);
2396
2397 /* Change the requirement from what should conflict to what is
2398 * wanted. */
2399 out->suggested_solutions[i].req.present
2400 = !obreq->contras->alternative[i].req.present;
2401 out->suggested_solutions[i].req.source
2402 = obreq->contras->alternative[i].req.source;
2403 out->suggested_solutions[i].req.range
2404 = obreq->contras->alternative[i].req.range;
2405 out->suggested_solutions[i].req.survives
2406 = obreq->contras->alternative[i].req.survives;
2407 out->suggested_solutions[i].req.quiet
2408 = obreq->contras->alternative[i].req.quiet;
2409 }
2410
2411 /* Return the first problem found. The next problem will be detected
2412 * during the next call. */
2413 return out;
2414 } obligatory_req_vector_iterate_end;
2415
2416 /* No obligatory req problems found. */
2417 return NULL;
2418}
2419
2420/**********************************************************************/
2429struct req_vec_problem *
2430action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
2431{
2432 struct action *paction;
2433 enum action_sub_result sub_res;
2434 struct req_vec_problem *out;
2435
2436 /* Sanity check: a non existing action enabler is missing but it doesn't
2437 * miss any obligatory hard requirements. */
2438 fc_assert_ret_val(enabler, NULL);
2439
2440 /* Sanity check: a non existing action doesn't have any obligatory hard
2441 * requirements. */
2442 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), NULL);
2443 paction = enabler_get_action(enabler);
2444
2445 if (paction->result != ACTRES_NONE) {
2446 /* A hard coded action result may mean obligatory requirements. */
2447 out = ae_suggest_repair_if_no_oblig(enabler,
2448 &oblig_hard_reqs_r[paction->result]);
2449 if (out != NULL) {
2450 return out;
2451 }
2452 }
2453
2454 for (sub_res = action_sub_result_begin();
2455 sub_res != action_sub_result_end();
2456 sub_res = action_sub_result_next(sub_res)) {
2457 if (!BV_ISSET(paction->sub_results, sub_res)) {
2458 /* Not relevant */
2459 continue;
2460 }
2461
2462 /* The action has this sub result. Check its hard requirements. */
2463 out = ae_suggest_repair_if_no_oblig(enabler,
2464 &oblig_hard_reqs_sr[sub_res]);
2465 if (out != NULL) {
2466 return out;
2467 }
2468 }
2469
2470 /* No obligatory req problems found. */
2471 return NULL;
2472}
2473
2474/**********************************************************************/
2480static struct requirement *
2481req_vec_first_local_diplrel(const struct requirement_vector *vec)
2482{
2483 requirement_vector_iterate(vec, preq) {
2484 if (preq->source.kind == VUT_DIPLREL
2485 && preq->range == REQ_RANGE_LOCAL) {
2486 return preq;
2487 }
2488 } requirement_vector_iterate_end;
2489
2490 return NULL;
2491}
2492
2493/**********************************************************************/
2501static struct requirement *
2502req_vec_first_contradiction_in_vec(const struct requirement *req,
2503 const struct requirement_vector *vec)
2504{
2505 /* If the requirement is contradicted by any requirement in the vector it
2506 * contradicts the entire requirement vector. */
2507 requirement_vector_iterate(vec, preq) {
2508 if (are_requirements_contradictions(req, preq)) {
2509 return preq;
2510 }
2511 } requirement_vector_iterate_end;
2512
2513 /* Not a singe requirement in the requirement vector is contradicted be
2514 * the specified requirement. */
2515 return NULL;
2516}
2517
2518/**********************************************************************/
2524static struct req_vec_problem *
2525enabler_tile_tgt_local_diplrel_implies_claimed(
2526 const struct action_enabler *enabler)
2527{
2528 struct req_vec_problem *out;
2529 struct requirement *local_diplrel;
2530 struct requirement *claimed_req;
2531 struct requirement tile_is_claimed;
2532 struct requirement tile_is_unclaimed;
2533 struct action *paction = enabler_get_action(enabler);
2534 struct astring astr;
2535
2536 if (action_get_target_kind(paction) != ATK_TILE) {
2537 /* Not tile targeted */
2538 return NULL;
2539 }
2540
2541 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
2542 if (local_diplrel == NULL) {
2543 /* No local diplrel */
2544 return NULL;
2545 }
2546
2547 /* Tile is unclaimed as a requirement. */
2548 tile_is_unclaimed.range = REQ_RANGE_TILE;
2549 tile_is_unclaimed.survives = FALSE;
2550 tile_is_unclaimed.source.kind = VUT_CITYTILE;
2551 tile_is_unclaimed.present = FALSE;
2552 tile_is_unclaimed.source.value.citytile = CITYT_CLAIMED;
2553
2554 claimed_req = req_vec_first_contradiction_in_vec(&tile_is_unclaimed,
2555 &enabler->target_reqs);
2556
2557 if (claimed_req) {
2558 /* Already clear */
2559 return NULL;
2560 }
2561
2562 /* Tile is claimed as a requirement. */
2563 tile_is_claimed.range = REQ_RANGE_TILE;
2564 tile_is_claimed.survives = FALSE;
2565 tile_is_claimed.source.kind = VUT_CITYTILE;
2566 tile_is_claimed.present = TRUE;
2567 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
2568
2569 out = req_vec_problem_new(
2570 1,
2571 /* TRANS: ruledit shows this when an enabler for a tile targeted
2572 * action requires that the actor has a diplomatic relationship to
2573 * the target but doesn't require that the target tile is claimed.
2574 * (DiplRel requirements to an unclaimed tile are never fulfilled
2575 * so this is implicit.) */
2576 N_("Requirement {%s} of action \"%s\" implies a claimed "
2577 "tile. No diplomatic relation to Nature."),
2578 req_to_fstring(local_diplrel, &astr), action_rule_name(paction));
2579
2580 astr_free(&astr);
2581
2582 /* The solution is to add the requirement that the tile is claimed */
2583 out->suggested_solutions[0].req = tile_is_claimed;
2584 out->suggested_solutions[0].vector_number
2585 = action_enabler_vector_number(enabler, &enabler->target_reqs);
2586 out->suggested_solutions[0].operation = RVCO_APPEND;
2587
2588 return out;
2589}
2590
2591/**********************************************************************/
2597static struct req_vec_problem *
2598enabler_first_self_contradiction(const struct action_enabler *enabler)
2599{
2600 struct req_vec_problem *out;
2601 struct requirement *local_diplrel;
2602 struct requirement *unclaimed_req;
2603 struct requirement tile_is_claimed;
2604 struct action *paction = enabler_get_action(enabler);
2605 struct astring astr1;
2606 struct astring astr2;
2607
2608 if (action_get_target_kind(paction) != ATK_TILE) {
2609 /* Not tile targeted */
2610 return NULL;
2611 }
2612
2613 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
2614 if (local_diplrel == NULL) {
2615 /* No local diplrel */
2616 return NULL;
2617 }
2618
2619 /* Tile is claimed as a requirement. */
2620 tile_is_claimed.range = REQ_RANGE_TILE;
2621 tile_is_claimed.survives = FALSE;
2622 tile_is_claimed.source.kind = VUT_CITYTILE;
2623 tile_is_claimed.present = TRUE;
2624 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
2625
2626 unclaimed_req = req_vec_first_contradiction_in_vec(&tile_is_claimed,
2627 &enabler->target_reqs);
2628
2629 if (unclaimed_req == NULL) {
2630 /* No unclaimed req */
2631 return NULL;
2632 }
2633
2634 out = req_vec_problem_new(
2635 2,
2636 /* TRANS: ruledit shows this when an enabler for a tile targeted
2637 * action requires that the target tile is unclaimed and that the
2638 * actor has a diplomatic relationship to the target. (DiplRel
2639 * requirements to an unclaimed tile are never fulfilled.) */
2640 N_("In enabler for \"%s\": No diplomatic relation to Nature."
2641 " Requirements {%s} and {%s} contradict each other."),
2642 action_rule_name(paction),
2643 req_to_fstring(local_diplrel, &astr1),
2644 req_to_fstring(unclaimed_req, &astr2));
2645
2646 astr_free(&astr1);
2647 astr_free(&astr2);
2648
2649 /* The first suggestion is to remove the diplrel */
2650 out->suggested_solutions[0].req = *local_diplrel;
2651 out->suggested_solutions[0].vector_number
2652 = action_enabler_vector_number(enabler, &enabler->actor_reqs);
2653 out->suggested_solutions[0].operation = RVCO_REMOVE;
2654
2655 /* The 2nd is to remove the requirement that the tile is unclaimed */
2656 out->suggested_solutions[1].req = *unclaimed_req;
2657 out->suggested_solutions[1].vector_number
2658 = action_enabler_vector_number(enabler, &enabler->target_reqs);
2659 out->suggested_solutions[1].operation = RVCO_REMOVE;
2660
2661 return out;
2662}
2663
2664/**********************************************************************/
2669struct req_vec_problem *
2670action_enabler_suggest_repair(const struct action_enabler *enabler)
2671{
2672 struct req_vec_problem *out;
2673
2674 out = action_enabler_suggest_repair_oblig(enabler);
2675 if (out != NULL) {
2676 return out;
2677 }
2678
2679 /* Look for errors in the requirement vectors. */
2680 out = req_vec_suggest_repair(&enabler->actor_reqs,
2681 action_enabler_vector_number,
2682 enabler);
2683 if (out != NULL) {
2684 return out;
2685 }
2686
2687 out = req_vec_suggest_repair(&enabler->target_reqs,
2688 action_enabler_vector_number,
2689 enabler);
2690 if (out != NULL) {
2691 return out;
2692 }
2693
2694 /* Enabler specific contradictions. */
2695 out = enabler_first_self_contradiction(enabler);
2696 if (out != NULL) {
2697 return out;
2698 }
2699
2700 /* Needed in action not enabled explanation finding. */
2701 out = enabler_tile_tgt_local_diplrel_implies_claimed(enabler);
2702 if (out != NULL) {
2703 return out;
2704 }
2705
2706 /* No problems found. */
2707 return NULL;
2708}
2709
2710/**********************************************************************/
2717static struct req_vec_problem *
2718enabler_first_clarification(const struct action_enabler *enabler)
2719{
2720 struct req_vec_problem *out;
2721
2722 out = NULL;
2723
2724 return out;
2725}
2726
2727/**********************************************************************/
2735struct req_vec_problem *
2736action_enabler_suggest_improvement(const struct action_enabler *enabler)
2737{
2738 struct action *paction;
2739 struct req_vec_problem *out;
2740
2741 out = action_enabler_suggest_repair(enabler);
2742 if (out) {
2743 /* A bug, not just a potential improvement */
2744 return out;
2745 }
2746
2747 paction = enabler_get_action(enabler);
2748
2749 /* Look for improvement suggestions to the requirement vectors. */
2750 out = req_vec_suggest_improvement(&enabler->actor_reqs,
2751 action_enabler_vector_number,
2752 enabler);
2753 if (out) {
2754 return out;
2755 }
2756 out = req_vec_suggest_improvement(&enabler->target_reqs,
2757 action_enabler_vector_number,
2758 enabler);
2759 if (out) {
2760 return out;
2761 }
2762
2763 /* Detect unused action enablers. */
2764 if (action_get_actor_kind(paction) == AAK_UNIT) {
2765 bool has_user = FALSE;
2766
2767 unit_type_iterate(pactor) {
2768 if (action_actor_utype_hard_reqs_ok(paction, pactor)
2769 && requirement_fulfilled_by_unit_type(pactor,
2770 &(enabler->actor_reqs))) {
2771 has_user = TRUE;
2772 break;
2773 }
2774 } unit_type_iterate_end;
2775
2776 if (!has_user) {
2777 /* TRANS: ruledit warns a user about an unused action enabler */
2778 out = req_vec_problem_new(0, N_("Action enabler for \"%s\" is never"
2779 " used by any unit."),
2780 action_rule_name(paction));
2781 }
2782 }
2783 if (out != NULL) {
2784 return out;
2785 }
2786
2787 out = enabler_first_clarification(enabler);
2788
2789 return out;
2790}
2791
2792/**********************************************************************/
2799 req_vec_num_in_item
2800action_enabler_vector_number(const void *enabler,
2801 const struct requirement_vector *vec)
2802{
2803 struct action_enabler *ae = (struct action_enabler *)enabler;
2804
2805 if (vec == &ae->actor_reqs) {
2806 return 0;
2807 } else if (vec == &ae->target_reqs) {
2808 return 1;
2809 } else {
2810 return -1;
2811 }
2812}
2813
2814/********************************************************************/
2822struct requirement_vector *
2823action_enabler_vector_by_number(const void *enabler,
2824 req_vec_num_in_item number)
2825{
2826 struct action_enabler *ae = (struct action_enabler *)enabler;
2827
2828 fc_assert_ret_val(number >= 0, NULL);
2829
2830 switch (number) {
2831 case 0:
2832 return &ae->actor_reqs;
2833 case 1:
2834 return &ae->target_reqs;
2835 default:
2836 return NULL;
2837 }
2838}
2839
2840/*********************************************************************/
2847 const char *action_enabler_vector_by_number_name(req_vec_num_in_item vec)
2848{
2849 switch (vec) {
2850 case 0:
2851 /* TRANS: requirement vector in an action enabler (ruledit) */
2852 return _("actor_reqs");
2853 case 1:
2854 /* TRANS: requirement vector in an action enabler (ruledit) */
2855 return _("target_reqs");
2856 default:
2857 return NULL;
2858 }
2859}
2860
2861/**********************************************************************/
2866static const struct impr_type *
2867tgt_city_local_building(const struct city *target_city)
2868{
2869 /* Only used with city targets */
2870 fc_assert_ret_val(target_city, NULL);
2871
2872 if (target_city->production.kind == VUT_IMPROVEMENT) {
2873 /* The local building is what the target city currently is building. */
2874 return target_city->production.value.building;
2875 } else {
2876 /* In the current semantic the local building is always the building
2877 * being built. */
2878 /* TODO: Consider making the local building the target building for
2879 * actions that allows specifying a building target. */
2880 return NULL;
2881 }
2882}
2883
2884/**********************************************************************/
2889static const struct unit_type *
2890tgt_city_local_utype(const struct city *target_city)
2891{
2892 /* Only used with city targets */
2893 fc_assert_ret_val(target_city, NULL);
2894
2895 if (target_city->production.kind == VUT_UTYPE) {
2896 /* The local unit type is what the target city currently is
2897 * building. */
2898 return target_city->production.value.utype;
2899 } else {
2900 /* In the current semantic the local utype is always the type of the
2901 * unit being built. */
2902 return NULL;
2903 }
2904}
2905
2906/**********************************************************************/
2914static const struct tile *
2915blocked_find_target_tile(const struct action *act,
2916 const struct unit *actor_unit,
2917 const struct tile *target_tile_arg,
2918 const struct city *target_city,
2919 const struct unit *target_unit)
2920{
2921 if (target_tile_arg != NULL) {
2922 /* Trust the caller. */
2923 return target_tile_arg;
2924 }
2925
2926 /* Action should always be set */
2927 fc_assert_ret_val(act, NULL);
2928
2929 switch (action_get_target_kind(act)) {
2930 case ATK_CITY:
2931 fc_assert_ret_val(target_city, NULL);
2932 return city_tile(target_city);
2933 case ATK_UNIT:
2934 if (target_unit == NULL) {
2935 fc_assert(target_unit != NULL);
2936 return NULL;
2937 }
2938 return unit_tile(target_unit);
2939 case ATK_UNITS:
2940 fc_assert_ret_val(target_unit || target_tile_arg, NULL);
2941 if (target_unit) {
2942 return unit_tile(target_unit);
2943 }
2944
2945 fc__fallthrough;
2946 case ATK_TILE:
2947 case ATK_EXTRAS:
2948 fc_assert_ret_val(target_tile_arg, NULL);
2949 return target_tile_arg;
2950 case ATK_SELF:
2951 fc_assert_ret_val(actor_unit, NULL);
2952 return unit_tile(actor_unit);
2953 case ATK_COUNT:
2954 /* Handled below. */
2955 break;
2956 }
2957
2958 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
2959 action_get_target_kind(act), action_rule_name(act));
2960 return NULL;
2961}
2962
2963/**********************************************************************/
2972static const struct city *
2973blocked_find_target_city(const struct action *act,
2974 const struct unit *actor_unit,
2975 const struct tile *target_tile,
2976 const struct city *target_city_arg,
2977 const struct unit *target_unit)
2978{
2979 if (target_city_arg != NULL) {
2980 /* Trust the caller. */
2981 return target_city_arg;
2982 }
2983
2984 /* action should always be set */
2985 fc_assert_ret_val(act, NULL);
2986
2987 switch (action_get_target_kind(act)) {
2988 case ATK_CITY:
2989 fc_assert_ret_val(target_city_arg, NULL);
2990 return target_city_arg;
2991 case ATK_UNIT:
2992 fc_assert_ret_val(target_unit, NULL);
2993 fc_assert_ret_val(unit_tile(target_unit), NULL);
2994 return tile_city(unit_tile(target_unit));
2995 case ATK_UNITS:
2996 fc_assert_ret_val(target_unit || target_tile, NULL);
2997 if (target_unit) {
2998 fc_assert_ret_val(unit_tile(target_unit), NULL);
2999 return tile_city(unit_tile(target_unit));
3000 }
3001
3002 fc__fallthrough;
3003 case ATK_TILE:
3004 case ATK_EXTRAS:
3005 fc_assert_ret_val(target_tile, NULL);
3006 return tile_city(target_tile);
3007 case ATK_SELF:
3008 fc_assert_ret_val(actor_unit, NULL);
3009 fc_assert_ret_val(unit_tile(actor_unit), NULL);
3010 return tile_city(unit_tile(actor_unit));
3011 case ATK_COUNT:
3012 /* Handled below. */
3013 break;
3014 }
3015
3016 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
3017 action_get_target_kind(act), action_rule_name(act));
3018 return NULL;
3019}
3020
3021/**********************************************************************/
3027 struct action *action_is_blocked_by(const struct action *act,
3028 const struct unit *actor_unit,
3029 const struct tile *target_tile_arg,
3030 const struct city *target_city_arg,
3031 const struct unit *target_unit)
3032{
3033 const struct tile *target_tile
3034 = blocked_find_target_tile(act, actor_unit, target_tile_arg,
3035 target_city_arg, target_unit);
3036 const struct city *target_city
3037 = blocked_find_target_city(act, actor_unit, target_tile,
3038 target_city_arg, target_unit);
3039 const struct civ_map *nmap = &(wld.map);
3040
3041 action_iterate(blocker_id) {
3042 struct action *blocker = action_by_number(blocker_id);
3043
3044 fc_assert_action(action_get_actor_kind(blocker) == AAK_UNIT,
3045 continue);
3046
3047 if (!action_would_be_blocked_by(act, blocker)) {
3048 /* It doesn't matter if it is legal. It won't block the action. */
3049 continue;
3050 }
3051
3052 switch (action_get_target_kind(blocker)) {
3053 case ATK_CITY:
3054 if (!target_city) {
3055 /* Can't be enabled. No target. */
3056 continue;
3057 }
3058 if (is_action_enabled_unit_on_city(nmap, blocker->id,
3059 actor_unit, target_city)) {
3060 return blocker;
3061 }
3062 break;
3063 case ATK_UNIT:
3064 if (!target_unit) {
3065 /* Can't be enabled. No target. */
3066 continue;
3067 }
3068 if (is_action_enabled_unit_on_unit(nmap, blocker->id,
3069 actor_unit, target_unit)) {
3070 return blocker;
3071 }
3072 break;
3073 case ATK_UNITS:
3074 if (!target_tile) {
3075 /* Can't be enabled. No target. */
3076 continue;
3077 }
3078 if (is_action_enabled_unit_on_stack(nmap, blocker->id,
3079 actor_unit, target_tile)) {
3080 return blocker;
3081 }
3082 break;
3083 case ATK_TILE:
3084 if (!target_tile) {
3085 /* Can't be enabled. No target. */
3086 continue;
3087 }
3088 if (is_action_enabled_unit_on_tile(nmap, blocker->id,
3089 actor_unit, target_tile, NULL)) {
3090 return blocker;
3091 }
3092 break;
3093 case ATK_EXTRAS:
3094 if (!target_tile) {
3095 /* Can't be enabled. No target. */
3096 continue;
3097 }
3098 if (is_action_enabled_unit_on_extras(blocker->id,
3099 actor_unit, target_tile, NULL)) {
3100 return blocker;
3101 }
3102 break;
3103 case ATK_SELF:
3104 if (is_action_enabled_unit_on_self(blocker->id, actor_unit)) {
3105 return blocker;
3106 }
3107 break;
3108 case ATK_COUNT:
3109 fc_assert_action(action_id_get_target_kind(blocker->id) != ATK_COUNT,
3110 continue);
3111 break;
3112 }
3113 } action_iterate_end;
3114
3115 /* Not blocked. */
3116 return NULL;
3117}
3118
3119/**********************************************************************/
3139static bool
3140action_actor_utype_hard_reqs_ok_full(const struct action *paction,
3141 const struct unit_type *actor_unittype,
3142 bool ignore_third_party)
3143{
3144 switch (paction->result) {
3145 case ACTRES_JOIN_CITY:
3146 if (actor_unittype->pop_cost <= 0) {
3147 /* Reason: Must have population to add. */
3148 return FALSE;
3149 }
3150 break;
3151
3152 case ACTRES_BOMBARD:
3153 if (actor_unittype->bombard_rate <= 0) {
3154 /* Reason: Can't bombard if it never fires. */
3155 return FALSE;
3156 }
3157
3158 if (actor_unittype->attack_strength <= 0) {
3159 /* Reason: Can't bombard without attack strength. */
3160 return FALSE;
3161 }
3162
3163 break;
3164
3165 case ACTRES_UPGRADE_UNIT:
3166 if (actor_unittype->obsoleted_by == U_NOT_OBSOLETED) {
3167 /* Reason: Nothing to upgrade to. */
3168 return FALSE;
3169 }
3170 break;
3171
3172 case ACTRES_ATTACK:
3173 case ACTRES_WIPE_UNITS:
3174 case ACTRES_COLLECT_RANSOM:
3175 if (actor_unittype->attack_strength <= 0) {
3176 /* Reason: Can't attack without strength. */
3177 return FALSE;
3178 }
3179 break;
3180
3181 case ACTRES_CONVERT:
3182 if (!actor_unittype->converted_to) {
3183 /* Reason: must be able to convert to something. */
3184 return FALSE;
3185 }
3186 break;
3187
3188 case ACTRES_TRANSPORT_UNLOAD:
3189 if (actor_unittype->transport_capacity < 1) {
3190 /* Reason: can't transport anything to unload. */
3191 return FALSE;
3192 }
3193 break;
3194
3195 case ACTRES_TRANSPORT_LOAD:
3196 if (actor_unittype->transport_capacity < 1) {
3197 /* Reason: can't transport anything to load. */
3198 return FALSE;
3199 }
3200 break;
3201
3202 case ACTRES_TRANSPORT_BOARD:
3203 case ACTRES_TRANSPORT_EMBARK:
3204 case ACTRES_TRANSPORT_DEBOARD:
3205 case ACTRES_TRANSPORT_DISEMBARK:
3206 if (!ignore_third_party) {
3207 bool has_transporter = FALSE;
3208
3209 unit_type_iterate(utrans) {
3210 if (can_unit_type_transport(utrans, utype_class(actor_unittype))) {
3211 has_transporter = TRUE;
3212 break;
3213 }
3214 } unit_type_iterate_end;
3215
3216 if (!has_transporter) {
3217 /* Reason: no other unit can transport this unit. */
3218 return FALSE;
3219 }
3220 }
3221 break;
3222
3223 case ACTRES_CONQUER_EXTRAS:
3224 if (!ignore_third_party) {
3225 bool has_target = FALSE;
3226 struct unit_class *pclass = utype_class(actor_unittype);
3227
3228 /* Use cache when it has been initialized */
3229 if (pclass->cache.native_bases != NULL) {
3230 /* Extra being native one is a hard requirement */
3231 extra_type_list_iterate(pclass->cache.native_bases, pextra) {
3232 if (!territory_claiming_base(pextra->data.base)) {
3233 /* Hard requirement */
3234 continue;
3235 }
3236
3237 has_target = TRUE;
3238 break;
3239 } extra_type_list_iterate_end;
3240 } else {
3241 struct extra_type_list *terr_claimers = extra_type_list_of_terr_claimers();
3242
3243 extra_type_list_iterate(terr_claimers, pextra) {
3244 if (!is_native_extra_to_uclass(pextra, pclass)) {
3245 /* Hard requirement */
3246 continue;
3247 }
3248
3249 has_target = TRUE;
3250 break;
3251 } extra_type_list_iterate_end;
3252 }
3253
3254 if (!has_target) {
3255 /* Reason: no extras can be conquered by this unit. */
3256 return FALSE;
3257 }
3258 }
3259 break;
3260
3261 case ACTRES_PARADROP:
3262 case ACTRES_PARADROP_CONQUER:
3263 if (actor_unittype->paratroopers_range <= 0) {
3264 /* Reason: Can't paradrop 0 tiles. */
3265 return FALSE;
3266 }
3267 break;
3268
3269 case ACTRES_HUT_ENTER:
3270 case ACTRES_HUT_FRIGHTEN:
3271 case ACTRES_ESTABLISH_EMBASSY:
3272 case ACTRES_SPY_INVESTIGATE_CITY:
3273 case ACTRES_SPY_POISON:
3274 case ACTRES_SPY_STEAL_GOLD:
3275 case ACTRES_SPY_SPREAD_PLAGUE:
3276 case ACTRES_SPY_SABOTAGE_CITY:
3277 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
3278 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
3279 case ACTRES_SPY_STEAL_TECH:
3280 case ACTRES_SPY_TARGETED_STEAL_TECH:
3281 case ACTRES_SPY_INCITE_CITY:
3282 case ACTRES_SPY_ESCAPE:
3283 case ACTRES_TRADE_ROUTE:
3284 case ACTRES_MARKETPLACE:
3285 case ACTRES_HELP_WONDER:
3286 case ACTRES_SPY_BRIBE_UNIT:
3287 case ACTRES_SPY_SABOTAGE_UNIT:
3288 case ACTRES_CAPTURE_UNITS:
3289 case ACTRES_FOUND_CITY:
3290 case ACTRES_STEAL_MAPS:
3291 case ACTRES_SPY_NUKE:
3292 case ACTRES_NUKE:
3293 case ACTRES_NUKE_UNITS:
3294 case ACTRES_DESTROY_CITY:
3295 case ACTRES_EXPEL_UNIT:
3296 case ACTRES_DISBAND_UNIT_RECOVER:
3297 case ACTRES_DISBAND_UNIT:
3298 case ACTRES_HOME_CITY:
3299 case ACTRES_HOMELESS:
3300 case ACTRES_AIRLIFT:
3301 case ACTRES_STRIKE_BUILDING:
3302 case ACTRES_STRIKE_PRODUCTION:
3303 case ACTRES_CONQUER_CITY:
3304 case ACTRES_HEAL_UNIT:
3305 case ACTRES_PILLAGE:
3306 case ACTRES_CLEAN:
3307 case ACTRES_FORTIFY:
3308 case ACTRES_TRANSFORM_TERRAIN:
3309 case ACTRES_CULTIVATE:
3310 case ACTRES_PLANT:
3311 case ACTRES_ROAD:
3312 case ACTRES_BASE:
3313 case ACTRES_MINE:
3314 case ACTRES_IRRIGATE:
3315 case ACTRES_SPY_ATTACK:
3316 case ACTRES_UNIT_MOVE:
3317 case ACTRES_TELEPORT:
3318 case ACTRES_TELEPORT_CONQUER:
3319 case ACTRES_ENABLER_CHECK:
3320 case ACTRES_NONE:
3321 /* No hard unit type requirements. */
3322 break;
3323
3324 ASSERT_UNUSED_ACTRES_CASES;
3325 }
3326
3327 return TRUE;
3328}
3329
3330/**********************************************************************/
3346bool
3347action_actor_utype_hard_reqs_ok(const struct action *paction,
3348 const struct unit_type *actor_unittype)
3349{
3350 return action_actor_utype_hard_reqs_ok_full(paction,
3351 actor_unittype, FALSE);
3352}
3353
3354/**********************************************************************/
3366static enum fc_tristate
3367action_hard_reqs_actor(const struct civ_map *nmap,
3368 const struct action *paction,
3369 const struct req_context *actor,
3370 const bool omniscient,
3371 const struct city *homecity)
3372{
3373 enum action_result result = paction->result;
3374
3375 if (actor == NULL) {
3376 actor = req_context_empty();
3377 }
3378
3379 if (!action_actor_utype_hard_reqs_ok_full(paction, actor->unittype,
3380 TRUE)) {
3381 /* Info leak: The actor player knows the type of their unit. */
3382 /* The actor unit type can't perform the action because of hard
3383 * unit type requirements. */
3384 return TRI_NO;
3385 }
3386
3387 switch (result) {
3388 case ACTRES_PARADROP:
3389 case ACTRES_PARADROP_CONQUER:
3390 /* Reason: Keep the old rules. */
3391 /* Info leak: The player knows if their unit already has paradropped this
3392 * turn. */
3393 if (actor->unit->paradropped) {
3394 return TRI_NO;
3395 }
3396
3397 break;
3398
3399 case ACTRES_AIRLIFT:
3400 {
3401 /* Obligatory hard requirement. Checked here too since
3402 * action_hard_reqs_actor() may be called before any
3403 * action enablers are checked. */
3404 if (actor->city == NULL) {
3405 /* No city to airlift from. */
3406 return TRI_NO;
3407 }
3408
3409 if (actor->player != city_owner(actor->city)
3410 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_SRC
3411 && pplayers_allied(actor->player,
3412 city_owner(actor->city)))) {
3413 /* Not allowed to airlift from this source. */
3414 return TRI_NO;
3415 }
3416
3417 if (!(omniscient || city_owner(actor->city) == actor->player)) {
3418 /* Can't check for airlifting capacity. */
3419 return TRI_MAYBE;
3420 }
3421
3422 if (0 >= actor->city->airlift
3423 && (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)
3424 || !game.info.airlift_from_always_enabled)) {
3425 /* The source cannot airlift for this turn (maybe already airlifted
3426 * or no airport).
3427 *
3428 * See also do_airline() in server/unittools.h. */
3429 return TRI_NO;
3430 }
3431 }
3432 break;
3433
3434 case ACTRES_CONVERT:
3435 /* Reason: Keep the old rules. */
3436 /* Info leak: The player knows their unit's cargo and location. */
3437 if (!unit_can_convert(nmap, actor->unit)) {
3438 return TRI_NO;
3439 }
3440 break;
3441
3442 case ACTRES_TRANSPORT_BOARD:
3443 case ACTRES_TRANSPORT_EMBARK:
3444 if (unit_transported(actor->unit)) {
3445 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
3446 /* Can't leave current transport. */
3447 return TRI_NO;
3448 }
3449 }
3450 break;
3451
3452 case ACTRES_TRANSPORT_DISEMBARK:
3453 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
3454 /* Keep the old rules about Unreachable and disembarks. */
3455 return TRI_NO;
3456 }
3457 break;
3458
3459 case ACTRES_HOMELESS:
3460 case ACTRES_UNIT_MOVE:
3461 case ACTRES_TELEPORT:
3462 case ACTRES_TELEPORT_CONQUER:
3463 case ACTRES_ESTABLISH_EMBASSY:
3464 case ACTRES_SPY_INVESTIGATE_CITY:
3465 case ACTRES_SPY_POISON:
3466 case ACTRES_SPY_STEAL_GOLD:
3467 case ACTRES_SPY_SPREAD_PLAGUE:
3468 case ACTRES_SPY_SABOTAGE_CITY:
3469 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
3470 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
3471 case ACTRES_SPY_STEAL_TECH:
3472 case ACTRES_SPY_TARGETED_STEAL_TECH:
3473 case ACTRES_SPY_INCITE_CITY:
3474 case ACTRES_SPY_ESCAPE:
3475 case ACTRES_TRADE_ROUTE:
3476 case ACTRES_MARKETPLACE:
3477 case ACTRES_HELP_WONDER:
3478 case ACTRES_SPY_BRIBE_UNIT:
3479 case ACTRES_SPY_SABOTAGE_UNIT:
3480 case ACTRES_CAPTURE_UNITS:
3481 case ACTRES_FOUND_CITY:
3482 case ACTRES_JOIN_CITY:
3483 case ACTRES_STEAL_MAPS:
3484 case ACTRES_BOMBARD:
3485 case ACTRES_SPY_NUKE:
3486 case ACTRES_NUKE:
3487 case ACTRES_NUKE_UNITS:
3488 case ACTRES_DESTROY_CITY:
3489 case ACTRES_EXPEL_UNIT:
3490 case ACTRES_DISBAND_UNIT_RECOVER:
3491 case ACTRES_DISBAND_UNIT:
3492 case ACTRES_HOME_CITY:
3493 case ACTRES_UPGRADE_UNIT:
3494 case ACTRES_ATTACK:
3495 case ACTRES_WIPE_UNITS:
3496 case ACTRES_COLLECT_RANSOM:
3497 case ACTRES_STRIKE_BUILDING:
3498 case ACTRES_STRIKE_PRODUCTION:
3499 case ACTRES_CONQUER_CITY:
3500 case ACTRES_CONQUER_EXTRAS:
3501 case ACTRES_HEAL_UNIT:
3502 case ACTRES_TRANSFORM_TERRAIN:
3503 case ACTRES_CULTIVATE:
3504 case ACTRES_PLANT:
3505 case ACTRES_PILLAGE:
3506 case ACTRES_CLEAN:
3507 case ACTRES_FORTIFY:
3508 case ACTRES_ROAD:
3509 case ACTRES_BASE:
3510 case ACTRES_MINE:
3511 case ACTRES_IRRIGATE:
3512 case ACTRES_TRANSPORT_DEBOARD:
3513 case ACTRES_TRANSPORT_UNLOAD:
3514 case ACTRES_TRANSPORT_LOAD:
3515 case ACTRES_SPY_ATTACK:
3516 case ACTRES_HUT_ENTER:
3517 case ACTRES_HUT_FRIGHTEN:
3518 case ACTRES_ENABLER_CHECK:
3519 case ACTRES_NONE:
3520 /* No hard unit requirements. */
3521 break;
3522
3523 ASSERT_UNUSED_ACTRES_CASES;
3524 }
3525
3526 return TRI_YES;
3527}
3528
3529/**********************************************************************/
3552static enum fc_tristate
3553is_action_possible(const struct civ_map *nmap,
3554 const action_id wanted_action,
3555 const struct req_context *actor,
3556 const struct req_context *target,
3557 const struct extra_type *target_extra,
3558 const bool omniscient,
3559 const struct city *homecity)
3560{
3561 enum fc_tristate out;
3562 struct action *paction = action_by_number(wanted_action);
3563 enum action_target_kind tkind = action_get_target_kind(paction);
3564
3565 if (actor == NULL) {
3566 actor = req_context_empty();
3567 }
3568 if (target == NULL) {
3569 target = req_context_empty();
3570 }
3571
3572 fc_assert_msg((tkind == ATK_CITY && target->city != NULL)
3573 || (tkind == ATK_TILE && target->tile != NULL)
3574 || (tkind == ATK_EXTRAS && target->tile != NULL)
3575 || (tkind == ATK_UNIT && target->unit != NULL)
3576 /* At this level each individual unit is tested. */
3577 || (tkind == ATK_UNITS && target->unit != NULL)
3578 || (tkind == ATK_SELF),
3579 "Missing target!");
3580
3581 /* Info leak: The player knows where their unit is. */
3582 if (tkind != ATK_SELF
3583 && !action_distance_accepted(paction,
3584 real_map_distance(actor->tile,
3585 target->tile))) {
3586 /* The distance between the actor and the target isn't inside the
3587 * action's accepted range. */
3588 return TRI_NO;
3589 }
3590
3591 switch (tkind) {
3592 case ATK_UNIT:
3593 /* The Freeciv code for all actions that is controlled by action
3594 * enablers and targets a unit assumes that the acting
3595 * player can see the target unit.
3596 * Examples:
3597 * - action_prob_vs_unit()'s quick check that the distance between actor
3598 * and target is acceptable would leak distance to target unit if the
3599 * target unit can't be seen.
3600 */
3601 if (!can_player_see_unit(actor->player, target->unit)) {
3602 return TRI_NO;
3603 }
3604 break;
3605 case ATK_CITY:
3606 /* The Freeciv code assumes that the player is aware of the target
3607 * city's existence. (How can you order an airlift to a city when you
3608 * don't know its city ID?) */
3609 if (fc_funcs->player_tile_city_id_get(city_tile(target->city),
3610 actor->player)
3611 != target->city->id) {
3612 return TRI_NO;
3613 }
3614 break;
3615 case ATK_UNITS:
3616 case ATK_TILE:
3617 case ATK_EXTRAS:
3618 case ATK_SELF:
3619 /* No special player knowledge checks. */
3620 break;
3621 case ATK_COUNT:
3622 fc_assert(tkind != ATK_COUNT);
3623 break;
3624 }
3625
3626 if (action_is_blocked_by(paction, actor->unit,
3627 target->tile, target->city, target->unit)) {
3628 /* Allows an action to block an other action. If a blocking action is
3629 * legal the actions it blocks becomes illegal. */
3630 return TRI_NO;
3631 }
3632
3633 /* Actor specific hard requirements. */
3634 out = action_hard_reqs_actor(nmap, paction, actor, omniscient, homecity);
3635
3636 if (out == TRI_NO) {
3637 /* Illegal because of a hard actor requirement. */
3638 return TRI_NO;
3639 }
3640
3641 /* Quick checks for action itself */
3642 if (paction->result == ACTRES_ATTACK
3643 || paction->result == ACTRES_WIPE_UNITS
3644 || paction->result == ACTRES_COLLECT_RANSOM) {
3645 /* Reason: Keep the old rules. */
3646 if (!can_unit_attack_tile(actor->unit, paction, target->tile)) {
3647 return TRI_NO;
3648 }
3649 }
3650
3651 /* Hard requirements for results. */
3652 out = actres_possible(nmap,
3653 paction->result, actor,
3654 target, target_extra, out, omniscient,
3655 homecity);
3656
3657 if (out == TRI_NO) {
3658 /* Illegal because of a hard actor requirement. */
3659 return TRI_NO;
3660 }
3661
3662 if (paction->result == ACTRES_NUKE_UNITS) {
3663 if (unit_attack_units_at_tile_result(actor->unit, paction,
3664 target->tile)
3665 != ATT_OK) {
3666 /* Unreachable. */
3667 return TRI_NO;
3668 }
3669 } else if (paction->result == ACTRES_PARADROP
3670 || paction->result == ACTRES_PARADROP_CONQUER) {
3671 if (can_player_see_tile(actor->player, target->tile)) {
3672 /* Check for seen stuff that may kill the actor unit. */
3673
3674 /* Reason: Keep the old rules. Be merciful. */
3675 /* Info leak: The player sees the target tile. */
3676 if (!can_unit_exist_at_tile(nmap, actor->unit, target->tile)
3677 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
3678 || !unit_could_load_at(actor->unit, target->tile))) {
3679 return TRI_NO;
3680 }
3681
3682 /* Reason: Keep the old rules. Be merciful. */
3683 /* Info leak: The player sees the target tile. */
3684 if (is_non_attack_city_tile(target->tile, actor->player)) {
3685 return TRI_NO;
3686 }
3687
3688 /* Reason: Be merciful. */
3689 /* Info leak: The player sees all units checked. Invisible units are
3690 * ignored. */
3691 unit_list_iterate(target->tile->units, pother) {
3692 if (can_player_see_unit(actor->player, pother)
3693 && !pplayers_allied(actor->player, unit_owner(pother))) {
3694 return TRI_NO;
3695 }
3696 } unit_list_iterate_end;
3697 }
3698 }
3699
3700 return out;
3701}
3702
3703/**********************************************************************/
3709 static bool is_enabler_active(const struct action_enabler *enabler,
3710 const struct req_context *actor,
3711 const struct req_context *target)
3712{
3713 return are_reqs_active(actor, target != NULL ? target->player : NULL,
3714 &enabler->actor_reqs, RPT_CERTAIN)
3715 && are_reqs_active(target, actor != NULL ? actor->player : NULL,
3716 &enabler->target_reqs, RPT_CERTAIN);
3717}
3718
3719/**********************************************************************/
3728 static bool is_action_enabled(const struct civ_map *nmap,
3729 const action_id wanted_action,
3730 const struct req_context *actor,
3731 const struct req_context *target,
3732 const struct extra_type *target_extra,
3733 const struct city *actor_home)
3734{
3735 enum fc_tristate possible;
3736
3737 possible = is_action_possible(nmap, wanted_action, actor, target, target_extra,
3738 TRUE, actor_home);
3739
3740 if (possible != TRI_YES) {
3741 /* This context is omniscient. Should be yes or no. */
3742 fc_assert_msg(possible != TRI_MAYBE,
3743 "Is omniscient, should get yes or no.");
3744
3745 /* The action enablers are irrelevant since the action it self is
3746 * impossible. */
3747 return FALSE;
3748 }
3749
3750 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
3751 enabler) {
3752 if (is_enabler_active(enabler, actor, target)) {
3753 return TRUE;
3754 }
3755 } action_enabler_list_iterate_end;
3756
3757 return FALSE;
3758}
3759
3760/**********************************************************************/
3766static bool
3767is_action_enabled_unit_on_city_full(const struct civ_map *nmap,
3768 const action_id wanted_action,
3769 const struct unit *actor_unit,
3770 const struct city *actor_home,
3771 const struct tile *actor_tile,
3772 const struct city *target_city)
3773{
3774 const struct impr_type *target_building;
3775 const struct unit_type *target_utype;
3776
3777 if (actor_unit == NULL || target_city == NULL) {
3778 /* Can't do an action when actor or target are missing. */
3779 return FALSE;
3780 }
3781
3782 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3783 FALSE, "Action %s is performed by %s not %s",
3784 action_id_rule_name(wanted_action),
3785 action_actor_kind_name(
3786 action_id_get_actor_kind(wanted_action)),
3787 action_actor_kind_name(AAK_UNIT));
3788
3789 fc_assert_ret_val_msg(ATK_CITY
3790 == action_id_get_target_kind(wanted_action),
3791 FALSE, "Action %s is against %s not %s",
3792 action_id_rule_name(wanted_action),
3793 action_target_kind_name(
3794 action_id_get_target_kind(wanted_action)),
3795 action_target_kind_name(ATK_CITY));
3796
3797 fc_assert_ret_val(actor_tile, FALSE);
3798
3799 if (!unit_can_do_action(actor_unit, wanted_action)) {
3800 /* No point in continuing. */
3801 return FALSE;
3802 }
3803
3804 target_building = tgt_city_local_building(target_city);
3805 target_utype = tgt_city_local_utype(target_city);
3806
3807 return is_action_enabled(nmap, wanted_action,
3808 &(const struct req_context) {
3809 .player = unit_owner(actor_unit),
3810 .city = tile_city(actor_tile),
3811 .tile = actor_tile,
3812 .unit = actor_unit,
3813 .unittype = unit_type_get(actor_unit),
3814 },
3815 &(const struct req_context) {
3816 .player = city_owner(target_city),
3817 .city = target_city,
3818 .building = target_building,
3819 .tile = city_tile(target_city),
3820 .unittype = target_utype,
3821 },
3822 NULL,
3823 actor_home);
3824}
3825
3826/**********************************************************************/
3832 bool is_action_enabled_unit_on_city(const struct civ_map *nmap,
3833 const action_id wanted_action,
3834 const struct unit *actor_unit,
3835 const struct city *target_city)
3836{
3837 return is_action_enabled_unit_on_city_full(nmap, wanted_action, actor_unit,
3838 unit_home(actor_unit),
3839 unit_tile(actor_unit),
3840 target_city);
3841}
3842
3843/**********************************************************************/
3849static bool
3850is_action_enabled_unit_on_unit_full(const struct civ_map *nmap,
3851 const action_id wanted_action,
3852 const struct unit *actor_unit,
3853 const struct city *actor_home,
3854 const struct tile *actor_tile,
3855 const struct unit *target_unit)
3856{
3857 if (actor_unit == NULL || target_unit == NULL) {
3858 /* Can't do an action when actor or target are missing. */
3859 return FALSE;
3860 }
3861
3862 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3863 FALSE, "Action %s is performed by %s not %s",
3864 action_id_rule_name(wanted_action),
3865 action_actor_kind_name(
3866 action_id_get_actor_kind(wanted_action)),
3867 action_actor_kind_name(AAK_UNIT));
3868
3869 fc_assert_ret_val_msg(ATK_UNIT
3870 == action_id_get_target_kind(wanted_action),
3871 FALSE, "Action %s is against %s not %s",
3872 action_id_rule_name(wanted_action),
3873 action_target_kind_name(
3874 action_id_get_target_kind(wanted_action)),
3875 action_target_kind_name(ATK_UNIT));
3876
3877 fc_assert_ret_val(actor_tile, FALSE);
3878
3879 if (!unit_can_do_action(actor_unit, wanted_action)) {
3880 /* No point in continuing. */
3881 return FALSE;
3882 }
3883
3884 return is_action_enabled(nmap, wanted_action,
3885 &(const struct req_context) {
3886 .player = unit_owner(actor_unit),
3887 .city = tile_city(actor_tile),
3888 .tile = actor_tile,
3889 .unit = actor_unit,
3890 .unittype = unit_type_get(actor_unit),
3891 },
3892 &(const struct req_context) {
3893 .player = unit_owner(target_unit),
3894 .city = tile_city(unit_tile(target_unit)),
3895 .tile = unit_tile(target_unit),
3896 .unit = target_unit,
3897 .unittype = unit_type_get(target_unit),
3898 },
3899 NULL,
3900 actor_home);
3901}
3902
3903/**********************************************************************/
3909 bool is_action_enabled_unit_on_unit(const struct civ_map *nmap,
3910 const action_id wanted_action,
3911 const struct unit *actor_unit,
3912 const struct unit *target_unit)
3913{
3914 return is_action_enabled_unit_on_unit_full(nmap, wanted_action, actor_unit,
3915 unit_home(actor_unit),
3916 unit_tile(actor_unit),
3917 target_unit);
3918}
3919
3920/**********************************************************************/
3926static bool
3927is_action_enabled_unit_on_stack_full(const struct civ_map *nmap,
3928 const action_id wanted_action,
3929 const struct unit *actor_unit,
3930 const struct city *actor_home,
3931 const struct tile *actor_tile,
3932 const struct tile *target_tile)
3933{
3934 const struct req_context *actor_ctxt;
3935
3936 if (actor_unit == NULL || target_tile == NULL
3937 || unit_list_size(target_tile->units) == 0) {
3938 /* Can't do an action when actor or target are missing. */
3939 return FALSE;
3940 }
3941
3942 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3943 FALSE, "Action %s is performed by %s not %s",
3944 action_id_rule_name(wanted_action),
3945 action_actor_kind_name(
3946 action_id_get_actor_kind(wanted_action)),
3947 action_actor_kind_name(AAK_UNIT));
3948
3949 fc_assert_ret_val_msg(ATK_UNITS
3950 == action_id_get_target_kind(wanted_action),
3951 FALSE, "Action %s is against %s not %s",
3952 action_id_rule_name(wanted_action),
3953 action_target_kind_name(
3954 action_id_get_target_kind(wanted_action)),
3955 action_target_kind_name(ATK_UNITS));
3956
3957 fc_assert_ret_val(actor_tile, FALSE);
3958
3959 if (!unit_can_do_action(actor_unit, wanted_action)) {
3960 /* No point in continuing. */
3961 return FALSE;
3962 }
3963
3964 actor_ctxt = &(const struct req_context) {
3965 .player = unit_owner(actor_unit),
3966 .city = tile_city(actor_tile),
3967 .tile = actor_tile,
3968 .unit = actor_unit,
3969 .unittype = unit_type_get(actor_unit),
3970 };
3971
3972 unit_list_iterate(target_tile->units, target_unit) {
3973 if (!is_action_enabled(nmap, wanted_action, actor_ctxt,
3974 &(const struct req_context) {
3975 .player = unit_owner(target_unit),
3976 .city = tile_city(unit_tile(target_unit)),
3977 .tile = unit_tile(target_unit),
3978 .unit = target_unit,
3979 .unittype = unit_type_get(target_unit),
3980 },
3981 NULL, actor_home)) {
3982 /* One unit makes it impossible for all units. */
3983 return FALSE;
3984 }
3985 } unit_list_iterate_end;
3986
3987 /* Not impossible for any of the units at the tile. */
3988 return TRUE;
3989}
3990
3991/**********************************************************************/
3997 bool is_action_enabled_unit_on_stack(const struct civ_map *nmap,
3998 const action_id wanted_action,
3999 const struct unit *actor_unit,
4000 const struct tile *target_tile)
4001{
4002 return is_action_enabled_unit_on_stack_full(nmap, wanted_action, actor_unit,
4003 unit_home(actor_unit),
4004 unit_tile(actor_unit),
4005 target_tile);
4006}
4007
4008/**********************************************************************/
4014static bool
4015is_action_enabled_unit_on_tile_full(const struct civ_map *nmap,
4016 const action_id wanted_action,
4017 const struct unit *actor_unit,
4018 const struct city *actor_home,
4019 const struct tile *actor_tile,
4020 const struct tile *target_tile,
4021 const struct extra_type *target_extra)
4022{
4023 if (actor_unit == NULL || target_tile == NULL) {
4024 /* Can't do an action when actor or target are missing. */
4025 return FALSE;
4026 }
4027
4028 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4029 FALSE, "Action %s is performed by %s not %s",
4030 action_id_rule_name(wanted_action),
4031 action_actor_kind_name(
4032 action_id_get_actor_kind(wanted_action)),
4033 action_actor_kind_name(AAK_UNIT));
4034
4035 fc_assert_ret_val_msg(ATK_TILE
4036 == action_id_get_target_kind(wanted_action),
4037 FALSE, "Action %s is against %s not %s",
4038 action_id_rule_name(wanted_action),
4039 action_target_kind_name(
4040 action_id_get_target_kind(wanted_action)),
4041 action_target_kind_name(ATK_TILE));
4042
4043 fc_assert_ret_val(actor_tile, FALSE);
4044
4045 if (!unit_can_do_action(actor_unit, wanted_action)) {
4046 /* No point in continuing. */
4047 return FALSE;
4048 }
4049
4050 return is_action_enabled(nmap, wanted_action,
4051 &(const struct req_context) {
4052 .player = unit_owner(actor_unit),
4053 .city = tile_city(actor_tile),
4054 .tile = actor_tile,
4055 .unit = actor_unit,
4056 .unittype = unit_type_get(actor_unit),
4057 },
4058 &(const struct req_context) {
4059 .player = tile_owner(target_tile),
4060 .city = tile_city(target_tile),
4061 .tile = target_tile,
4062 },
4063 target_extra,
4064 actor_home);
4065}
4066
4067/**********************************************************************/
4073 bool is_action_enabled_unit_on_tile(const struct civ_map *nmap,
4074 const action_id wanted_action,
4075 const struct unit *actor_unit,
4076 const struct tile *target_tile,
4077 const struct extra_type *target_extra)
4078{
4079 return is_action_enabled_unit_on_tile_full(nmap, wanted_action, actor_unit,
4080 unit_home(actor_unit),
4081 unit_tile(actor_unit),
4082 target_tile, target_extra);
4083}
4084
4085/**********************************************************************/
4091static bool
4092is_action_enabled_unit_on_extras_full(const struct civ_map *nmap,
4093 const action_id wanted_action,
4094 const struct unit *actor_unit,
4095 const struct city *actor_home,
4096 const struct tile *actor_tile,
4097 const struct tile *target_tile,
4098 const struct extra_type *target_extra)
4099{
4100 if (actor_unit == NULL || target_tile == NULL) {
4101 /* Can't do an action when actor or target are missing. */
4102 return FALSE;
4103 }
4104
4105 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4106 FALSE, "Action %s is performed by %s not %s",
4107 action_id_rule_name(wanted_action),
4108 action_actor_kind_name(
4109 action_id_get_actor_kind(wanted_action)),
4110 action_actor_kind_name(AAK_UNIT));
4111
4112 fc_assert_ret_val_msg(ATK_EXTRAS
4113 == action_id_get_target_kind(wanted_action),
4114 FALSE, "Action %s is against %s not %s",
4115 action_id_rule_name(wanted_action),
4116 action_target_kind_name(
4117 action_id_get_target_kind(wanted_action)),
4118 action_target_kind_name(ATK_EXTRAS));
4119
4120 fc_assert_ret_val(actor_tile, FALSE);
4121
4122 if (!unit_can_do_action(actor_unit, wanted_action)) {
4123 /* No point in continuing. */
4124 return FALSE;
4125 }
4126
4127 return is_action_enabled(nmap, wanted_action,
4128 &(const struct req_context) {
4129 .player = unit_owner(actor_unit),
4130 .city = tile_city(actor_tile),
4131 .tile = actor_tile,
4132 .unit = actor_unit,
4133 .unittype = unit_type_get(actor_unit),
4134 },
4135 &(const struct req_context) {
4136 .player = target_tile->extras_owner,
4137 .city = tile_city(target_tile),
4138 .tile = target_tile,
4139 },
4140 target_extra,
4141 actor_home);
4142}
4143
4144/**********************************************************************/
4150 bool is_action_enabled_unit_on_extras(const action_id wanted_action,
4151 const struct unit *actor_unit,
4152 const struct tile *target_tile,
4153 const struct extra_type *target_extra)
4154{
4155 const struct civ_map *nmap = &(wld.map);
4156
4157 return is_action_enabled_unit_on_extras_full(nmap, wanted_action, actor_unit,
4158 unit_home(actor_unit),
4159 unit_tile(actor_unit),
4160 target_tile, target_extra);
4161}
4162
4163/**********************************************************************/
4170static bool
4171is_action_enabled_unit_on_self_full(const struct civ_map *nmap,
4172 const action_id wanted_action,
4173 const struct unit *actor_unit,
4174 const struct city *actor_home,
4175 const struct tile *actor_tile)
4176{
4177 if (actor_unit == NULL) {
4178 /* Can't do an action when the actor is missing. */
4179 return FALSE;
4180 }
4181
4182 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
4183 FALSE, "Action %s is performed by %s not %s",
4184 action_id_rule_name(wanted_action),
4185 action_actor_kind_name(
4186 action_id_get_actor_kind(wanted_action)),
4187 action_actor_kind_name(AAK_UNIT));
4188
4189 fc_assert_ret_val_msg(ATK_SELF
4190 == action_id_get_target_kind(wanted_action),
4191 FALSE, "Action %s is against %s not %s",
4192 action_id_rule_name(wanted_action),
4193 action_target_kind_name(
4194 action_id_get_target_kind(wanted_action)),
4195 action_target_kind_name(ATK_SELF));
4196
4197 fc_assert_ret_val(actor_tile, FALSE);
4198
4199 if (!unit_can_do_action(actor_unit, wanted_action)) {
4200 /* No point in continuing. */
4201 return FALSE;
4202 }
4203
4204 return is_action_enabled(nmap, wanted_action,
4205 &(const struct req_context) {
4206 .player = unit_owner(actor_unit),
4207 .city = tile_city(actor_tile),
4208 .tile = actor_tile,
4209 .unit = actor_unit,
4210 .unittype = unit_type_get(actor_unit),
4211 },
4212 NULL, NULL,
4213 actor_home);
4214}
4215
4216/**********************************************************************/
4223 bool is_action_enabled_unit_on_self(const action_id wanted_action,
4224 const struct unit *actor_unit)
4225{
4226 const struct civ_map *nmap = &(wld.map);
4227
4228 return is_action_enabled_unit_on_self_full(nmap, wanted_action, actor_unit,
4229 unit_home(actor_unit),
4230 unit_tile(actor_unit));
4231}
4232
4233/**********************************************************************/
4251static enum fc_tristate
4252action_enabled_local(const action_id wanted_action,
4253 const struct req_context *actor,
4254 const struct req_context *target)
4255{
4256 enum fc_tristate current;
4257 enum fc_tristate result;
4258
4259 if (actor == NULL || actor->player == NULL) {
4260 /* Need actor->player for point of view */
4261 return TRI_MAYBE;
4262 }
4263
4264 if (target == NULL) {
4265 target = req_context_empty();
4266 }
4267
4268 result = TRI_NO;
4269 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
4270 enabler) {
4271 current = fc_tristate_and(mke_eval_reqs(actor->player, actor,
4272 target->player,
4273 &enabler->actor_reqs,
4274 RPT_CERTAIN),
4275 mke_eval_reqs(actor->player, target,
4276 actor->player,
4277 &enabler->target_reqs,
4278 RPT_CERTAIN));
4279 if (current == TRI_YES) {
4280 return TRI_YES;
4281 } else if (current == TRI_MAYBE) {
4282 result = TRI_MAYBE;
4283 }
4284 } action_enabler_list_iterate_end;
4285
4286 return result;
4287}
4288
4289/**********************************************************************/
4298 static bool is_effect_val_known(enum effect_type effect_type,
4299 const struct player *pov_player,
4300 const struct req_context *context,
4301 const struct player *other_player)
4302{
4303 effect_list_iterate(get_effects(effect_type), peffect) {
4304 if (TRI_MAYBE == mke_eval_reqs(pov_player, context,
4305 other_player,
4306 &(peffect->reqs), RPT_CERTAIN)) {
4307 return FALSE;
4308 }
4309 } effect_list_iterate_end;
4310
4311 return TRUE;
4312}
4313
4314/**********************************************************************/
4317static enum fc_tristate
4318tech_can_be_stolen(const struct player *actor_player,
4319 const struct player *target_player)
4320{
4321 const struct research *actor_research = research_get(actor_player);
4322 const struct research *target_research = research_get(target_player);
4323
4324 if (actor_research != target_research) {
4325 if (can_see_techs_of_target(actor_player, target_player)) {
4326 advance_iterate(padvance) {
4327 Tech_type_id i = advance_number(padvance);
4328
4329 if (research_invention_state(target_research, i) == TECH_KNOWN
4330 && research_invention_gettable(actor_research, i,
4331 game.info.tech_steal_allow_holes)
4332 && (research_invention_state(actor_research, i) == TECH_UNKNOWN
4333 || (research_invention_state(actor_research, i)
4334 == TECH_PREREQS_KNOWN))) {
4335 return TRI_YES;
4336 }
4337 } advance_iterate_end;
4338 } else {
4339 return TRI_MAYBE;
4340 }
4341 }
4342
4343 return TRI_NO;
4344}
4345
4346/**********************************************************************/
4354 static struct act_prob ap_dipl_battle_win(const struct unit *pattacker,
4355 const struct unit *pdefender)
4356{
4357 /* Keep unconverted until the end to avoid scaling each step */
4358 int chance;
4359 struct act_prob out;
4360
4361 /* Superspy always win */
4362 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
4363 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
4364 return ACTPROB_IMPOSSIBLE;
4365 }
4366 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
4367 /* An attacking UTYF_SUPERSPY will defeat every possible defender
4368 * except another UTYF_SUPERSPY. */
4369 return ACTPROB_CERTAIN;
4370 }
4371
4372 /* Base chance is 50% */
4373 chance = 50;
4374
4375 /* Spy attack bonus */
4376 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
4377 chance += 25;
4378 }
4379
4380 /* Spy defense bonus */
4381 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
4382 chance -= 25;
4383 }
4384
4385 /* Veteran attack and defense bonus */
4386 {
4387 const struct veteran_level *vatt =
4388 utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
4389 const struct veteran_level *vdef =
4390 utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
4391
4392 chance += vatt->power_fact - vdef->power_fact;
4393 }
4394
4395 /* Defense bonus. */
4396 {
4397 const struct req_context defender_ctxt = {
4398 .player = tile_owner(pdefender->tile),
4399 .city = tile_city(pdefender->tile),
4400 .tile = pdefender->tile,
4401 };
4402 if (!is_effect_val_known(EFT_SPY_RESISTANT, unit_owner(pattacker),
4403 &defender_ctxt,
4404 NULL)) {
4405 return ACTPROB_NOT_KNOWN;
4406 }
4407
4408 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
4409 chance -= chance * get_target_bonus_effects(
4410 NULL,
4411 &defender_ctxt,
4412 NULL,
4413 EFT_SPY_RESISTANT
4414 ) / 100;
4415 }
4416
4417 chance = CLIP(0, chance, 100);
4418
4419 /* Convert to action probability */
4420 out.min = chance * ACTPROB_VAL_1_PCT;
4421 out.max = chance * ACTPROB_VAL_1_PCT;
4422
4423 return out;
4424}
4425
4426/**********************************************************************/
4431 static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
4432 const struct unit *pvictim,
4433 const struct tile *tgt_tile,
4434 const struct action *paction)
4435{
4436 struct unit *pdefender;
4437
4438 if (!can_player_see_hypotetic_units_at(unit_owner(pattacker),
4439 tgt_tile)) {
4440 /* Don't leak information about unseen defenders. */
4441 return ACTPROB_NOT_KNOWN;
4442 }
4443
4444 pdefender = get_diplomatic_defender(pattacker, pvictim, tgt_tile,
4445 paction);
4446
4447 if (pdefender) {
4448 /* There will be a diplomatic battle instead of an action. */
4449 return ap_dipl_battle_win(pattacker, pdefender);
4450 };
4451
4452 /* No diplomatic battle will occur. */
4453 return ACTPROB_CERTAIN;
4454}
4455
4456/**********************************************************************/
4459 static struct act_prob act_prob_unseen_target(const struct civ_map *nmap,
4460 action_id act_id,
4461 const struct unit *actor_unit)
4462{
4463 if (action_maybe_possible_actor_unit(nmap, act_id, actor_unit)) {
4464 /* Unknown because the target is unseen. */
4465 return ACTPROB_NOT_KNOWN;
4466 } else {
4467 /* The actor it self can't do this. */
4468 return ACTPROB_IMPOSSIBLE;
4469 }
4470}
4471
4472/**********************************************************************/
4476static struct act_prob
4477action_prob_pre_action_dice_roll(const struct player *act_player,
4478 const struct unit *act_unit,
4479 const struct city *tgt_city,
4480 const struct player *tgt_player,
4481 const struct action *paction)
4482{
4483 if (is_effect_val_known(EFT_ACTION_ODDS_PCT, act_player,
4484 &(const struct req_context) {
4485 .player = act_player,
4486 .city = tgt_city,
4487 .unit = act_unit,
4488 .unittype = unit_type_get(act_unit),
4489 },
4490 tgt_player)
4491 && is_effect_val_known(EFT_ACTION_RESIST_PCT, act_player,
4492 &(const struct req_context) {
4493 .player = tgt_player,
4494 .city = tgt_city,
4495 .unit = act_unit,
4496 },
4497 act_player)) {
4498 int unconverted = action_dice_roll_odds(act_player, act_unit, tgt_city,
4499 tgt_player, paction);
4500 struct act_prob result = { .min = unconverted * ACTPROB_VAL_1_PCT,
4501 .max = unconverted * ACTPROB_VAL_1_PCT };
4502
4503 return result;
4504 } else {
4505 /* Could be improved to return a more exact probability in some cases.
4506 * Example: The player has enough information to know that the
4507 * probability always will be above 25% and always under 75% because
4508 * the only effect with unknown requirements that may apply adds (or
4509 * subtracts) 50% while all the requirements of the other effects that
4510 * may apply are known. */
4511 return ACTPROB_NOT_KNOWN;
4512 }
4513}
4514
4515/**********************************************************************/
4520static struct act_prob
4521action_prob_battle_then_dice_roll(const struct player *act_player,
4522 const struct unit *act_unit,
4523 const struct city *tgt_city,
4524 const struct unit *tgt_unit,
4525 const struct tile *tgt_tile,
4526 const struct player *tgt_player,
4527 const struct action *paction)
4528{
4529 struct act_prob battle;
4530 struct act_prob dice_roll;
4531
4532 battle = ACTPROB_CERTAIN;
4533 switch (actres_get_battle_kind(paction->result)) {
4534 case ABK_NONE:
4535 /* No pre action battle. */
4536 break;
4537 case ABK_DIPLOMATIC:
4538 battle = ap_diplomat_battle(act_unit, tgt_unit, tgt_tile,
4539 paction);
4540 break;
4541 case ABK_STANDARD:
4542 /* Not supported here yet. Implement when users appear. */
4543 fc_assert(actres_get_battle_kind(paction->result) != ABK_STANDARD);
4544 break;
4545 case ABK_COUNT:
4546 fc_assert(actres_get_battle_kind(paction->result) != ABK_COUNT);
4547 break;
4548 }
4549
4550 dice_roll = action_prob_pre_action_dice_roll(act_player, act_unit,
4551 tgt_city, tgt_player,
4552 paction);
4553
4554 return action_prob_and(&battle, &dice_roll);
4555}
4556
4557/**********************************************************************/
4568static struct act_prob
4569action_prob(const struct civ_map *nmap,
4570 const action_id wanted_action,
4571 const struct req_context *actor,
4572 const struct city *actor_home,
4573 const struct req_context *target,
4574 const struct extra_type *target_extra)
4575{
4576 int known;
4577 struct act_prob chance;
4578 const struct action *paction = action_by_number(wanted_action);
4579
4580 if (actor == NULL) {
4581 actor = req_context_empty();
4582 }
4583 if (target == NULL) {
4584 target = req_context_empty();
4585 }
4586
4587 known = is_action_possible(nmap, wanted_action, actor, target,
4588 target_extra,
4589 FALSE, actor_home);
4590
4591 if (known == TRI_NO) {
4592 /* The action enablers are irrelevant since the action it self is
4593 * impossible. */
4594 return ACTPROB_IMPOSSIBLE;
4595 }
4596
4597 chance = ACTPROB_NOT_IMPLEMENTED;
4598
4599 known = fc_tristate_and(known,
4600 action_enabled_local(wanted_action,
4601 actor, target));
4602
4603 switch (paction->result) {
4604 case ACTRES_SPY_POISON:
4605 /* All uncertainty comes from potential diplomatic battles and the
4606 * (diplchance server setting and the) Action_Odds_Pct effect controlled
4607 * dice roll before the action. */
4608 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
4609 target->city, target->unit,
4610 target->tile, target->player,
4611 paction);
4612 break;
4613 case ACTRES_SPY_STEAL_GOLD:
4614 /* TODO */
4615 break;
4616 case ACTRES_SPY_SPREAD_PLAGUE:
4617 /* TODO */
4618 break;
4619 case ACTRES_STEAL_MAPS:
4620 /* TODO */
4621 break;
4622 case ACTRES_SPY_SABOTAGE_UNIT:
4623 /* All uncertainty comes from potential diplomatic battles. */
4624 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile,
4625 paction);
4626 break;
4627 case ACTRES_SPY_BRIBE_UNIT:
4628 /* All uncertainty comes from potential diplomatic battles. */
4629 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile,
4630 paction);
4631 break;
4632 case ACTRES_SPY_ATTACK:
4633 /* All uncertainty comes from potential diplomatic battles. */
4634 chance = ap_diplomat_battle(actor->unit, NULL, target->tile,
4635 paction);
4636 break;
4637 case ACTRES_SPY_SABOTAGE_CITY:
4638 /* TODO */
4639 break;
4640 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
4641 /* TODO */
4642 break;
4643 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
4644 /* TODO */
4645 break;
4646 case ACTRES_SPY_INCITE_CITY:
4647 /* TODO */
4648 break;
4649 case ACTRES_ESTABLISH_EMBASSY:
4650 chance = ACTPROB_CERTAIN;
4651 break;
4652 case ACTRES_SPY_STEAL_TECH:
4653 /* Do the victim have anything worth taking? */
4654 known = fc_tristate_and(known,
4655 tech_can_be_stolen(actor->player,
4656 target->player));
4657
4658 /* TODO: Calculate actual chance */
4659
4660 break;
4661 case ACTRES_SPY_TARGETED_STEAL_TECH:
4662 /* Do the victim have anything worth taking? */
4663 known = fc_tristate_and(known,
4664 tech_can_be_stolen(actor->player,
4665 target->player));
4666
4667 /* TODO: Calculate actual chance */
4668
4669 break;
4670 case ACTRES_SPY_INVESTIGATE_CITY:
4671 /* There is no risk that the city won't get investigated. */
4672 chance = ACTPROB_CERTAIN;
4673 break;
4674 case ACTRES_SPY_ESCAPE:
4675 /* TODO */
4676 break;
4677 case ACTRES_TRADE_ROUTE:
4678 /* TODO */
4679 break;
4680 case ACTRES_MARKETPLACE:
4681 /* Possible when not blocked by is_action_possible() */
4682 chance = ACTPROB_CERTAIN;
4683 break;
4684 case ACTRES_HELP_WONDER:
4685 /* Possible when not blocked by is_action_possible() */
4686 chance = ACTPROB_CERTAIN;
4687 break;
4688 case ACTRES_CAPTURE_UNITS:
4689 /* No battle is fought first. */
4690 chance = ACTPROB_CERTAIN;
4691 break;
4692 case ACTRES_EXPEL_UNIT:
4693 /* No battle is fought first. */
4694 chance = ACTPROB_CERTAIN;
4695 break;
4696 case ACTRES_BOMBARD:
4697 /* No battle is fought first. */
4698 chance = ACTPROB_CERTAIN;
4699 break;
4700 case ACTRES_FOUND_CITY:
4701 /* Possible when not blocked by is_action_possible() */
4702 chance = ACTPROB_CERTAIN;
4703 break;
4704 case ACTRES_JOIN_CITY:
4705 /* Possible when not blocked by is_action_possible() */
4706 chance = ACTPROB_CERTAIN;
4707 break;
4708 case ACTRES_SPY_NUKE:
4709 /* All uncertainty comes from potential diplomatic battles and the
4710 * (diplchance server setting and the) Action_Odds_Pct effect controlled
4711 * dice roll before the action. */
4712 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
4713 target->city, target->unit,
4714 target->tile,
4715 target->player,
4716 paction);
4717 break;
4718 case ACTRES_NUKE:
4719 /* TODO */
4720 break;
4721 case ACTRES_NUKE_UNITS:
4722 /* TODO */
4723 break;
4724 case ACTRES_DESTROY_CITY:
4725 /* No battle is fought first. */
4726 chance = ACTPROB_CERTAIN;
4727 break;
4728 case ACTRES_DISBAND_UNIT_RECOVER:
4729 /* No battle is fought first. */
4730 chance = ACTPROB_CERTAIN;
4731 break;
4732 case ACTRES_DISBAND_UNIT:
4733 /* No battle is fought first. */
4734 chance = ACTPROB_CERTAIN;
4735 break;
4736 case ACTRES_HOME_CITY:
4737 /* No battle is fought first. */
4738 chance = ACTPROB_CERTAIN;
4739 break;
4740 case ACTRES_HOMELESS:
4741 /* No battle is fought first. */
4742 chance = ACTPROB_CERTAIN;
4743 break;
4744 case ACTRES_UPGRADE_UNIT:
4745 /* No battle is fought first. */
4746 chance = ACTPROB_CERTAIN;
4747 break;
4748 case ACTRES_PARADROP:
4749 case ACTRES_PARADROP_CONQUER:
4750 /* TODO */
4751 break;
4752 case ACTRES_AIRLIFT:
4753 /* Possible when not blocked by is_action_possible() */
4754 chance = ACTPROB_CERTAIN;
4755 break;
4756 case ACTRES_ATTACK:
4757 case ACTRES_COLLECT_RANSOM:
4758 {
4759 struct unit *defender_unit = get_defender(nmap, actor->unit,
4760 target->tile, paction);
4761
4762 if (can_player_see_unit(actor->player, defender_unit)) {
4763 double unconverted = unit_win_chance(nmap, actor->unit,
4764 defender_unit, paction);
4765
4766 chance.min = MAX(ACTPROB_VAL_MIN,
4767 floor((double)ACTPROB_VAL_MAX * unconverted));
4768 chance.max = MIN(ACTPROB_VAL_MAX,
4769 ceil((double)ACTPROB_VAL_MAX * unconverted));
4770 } else if (known == TRI_YES) {
4771 known = TRI_MAYBE;
4772 }
4773 }
4774 break;
4775 case ACTRES_WIPE_UNITS:
4776 chance = ACTPROB_CERTAIN;
4777 break;
4778 case ACTRES_STRIKE_BUILDING:
4779 /* TODO: not implemented yet because:
4780 * - dice roll 100% * Action_Odds_Pct could be handled with
4781 * action_prob_pre_action_dice_roll().
4782 * - sub target building may be missing. May be missing without player
4783 * knowledge if it isn't visible. See is_improvement_visible() and
4784 * can_player_see_city_internals(). */
4785 break;
4786 case ACTRES_STRIKE_PRODUCTION:
4787 /* All uncertainty comes from the (diplchance server setting and the)
4788 * Action_Odds_Pct effect controlled dice roll before the action. */
4789 chance = action_prob_pre_action_dice_roll(actor->player, actor->unit,
4790 target->city, target->player,
4791 paction);
4792 break;
4793 case ACTRES_CONQUER_CITY:
4794 /* No battle is fought first. */
4795 chance = ACTPROB_CERTAIN;
4796 break;
4797 case ACTRES_CONQUER_EXTRAS:
4798 /* No battle is fought first. */
4799 chance = ACTPROB_CERTAIN;
4800 break;
4801 case ACTRES_HEAL_UNIT:
4802 /* No battle is fought first. */
4803 chance = ACTPROB_CERTAIN;
4804 break;
4805 case ACTRES_TRANSFORM_TERRAIN:
4806 case ACTRES_CULTIVATE:
4807 case ACTRES_PLANT:
4808 case ACTRES_PILLAGE:
4809 case ACTRES_CLEAN:
4810 case ACTRES_FORTIFY:
4811 case ACTRES_ROAD:
4812 case ACTRES_CONVERT:
4813 case ACTRES_BASE:
4814 case ACTRES_MINE:
4815 case ACTRES_IRRIGATE:
4816 chance = ACTPROB_CERTAIN;
4817 break;
4818 case ACTRES_TRANSPORT_DEBOARD:
4819 chance = ACTPROB_CERTAIN;
4820 break;
4821 case ACTRES_TRANSPORT_BOARD:
4822 chance = ACTPROB_CERTAIN;
4823 break;
4824 case ACTRES_TRANSPORT_EMBARK:
4825 chance = ACTPROB_CERTAIN;
4826 break;
4827 case ACTRES_TRANSPORT_UNLOAD:
4828 chance = ACTPROB_CERTAIN;
4829 break;
4830 case ACTRES_TRANSPORT_LOAD:
4831 chance = ACTPROB_CERTAIN;
4832 break;
4833 case ACTRES_TRANSPORT_DISEMBARK:
4834 chance = ACTPROB_CERTAIN;
4835 break;
4836 case ACTRES_HUT_ENTER:
4837 case ACTRES_HUT_FRIGHTEN:
4838 /* Entering the hut happens with a probability of 100%. What happens
4839 * next is probably up to dice rolls in Lua. */
4840 chance = ACTPROB_NOT_IMPLEMENTED;
4841 break;
4842 case ACTRES_UNIT_MOVE:
4843 case ACTRES_TELEPORT:
4844 case ACTRES_TELEPORT_CONQUER:
4845 chance = ACTPROB_CERTAIN;
4846 break;
4847 /* Not UI action, so chance is meaningless */
4848 case ACTRES_ENABLER_CHECK:
4849 chance = ACTPROB_CERTAIN;
4850 break;
4851 case ACTRES_NONE:
4852 /* Accommodate ruleset authors that wishes to roll the dice in Lua.
4853 * Would be ACTPROB_CERTAIN if not for that. */
4854 /* TODO: maybe allow the ruleset author to give a probability from
4855 * Lua? */
4856 chance = ACTPROB_NOT_IMPLEMENTED;
4857 break;
4858
4859 case ACTRES_UNUSED_1:
4860 chance = ACTPROB_NOT_IMPLEMENTED;
4861 break;
4862 }
4863
4864 /* Non signal action probabilities should be in range. */
4865 fc_assert_action((action_prob_is_signal(chance)
4866 || chance.max <= ACTPROB_VAL_MAX),
4867 chance.max = ACTPROB_VAL_MAX);
4868 fc_assert_action((action_prob_is_signal(chance)
4869 || chance.min >= ACTPROB_VAL_MIN),
4870 chance.min = ACTPROB_VAL_MIN);
4871
4872 switch (known) {
4873 case TRI_NO:
4874 return ACTPROB_IMPOSSIBLE;
4875 break;
4876 case TRI_MAYBE:
4877 return ACTPROB_NOT_KNOWN;
4878 break;
4879 case TRI_YES:
4880 return chance;
4881 break;
4882 };
4883
4884 fc_assert_msg(FALSE, "Should be yes, maybe or no");
4885
4886 return ACTPROB_NOT_IMPLEMENTED;
4887}
4888
4889/**********************************************************************/
4893static struct act_prob
4894action_prob_vs_city_full(const struct civ_map *nmap,
4895 const struct unit *actor_unit,
4896 const struct city *actor_home,
4897 const struct tile *actor_tile,
4898 const action_id act_id,
4899 const struct city *target_city)
4900{
4901 const struct impr_type *target_building;
4902 const struct unit_type *target_utype;
4903 const struct action *act = action_by_number(act_id);
4904
4905 if (actor_unit == NULL || target_city == NULL) {
4906 /* Can't do an action when actor or target are missing. */
4907 return ACTPROB_IMPOSSIBLE;
4908 }
4909
4910 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4911 ACTPROB_IMPOSSIBLE,
4912 "Action %s is performed by %s not %s",
4913 action_id_rule_name(act_id),
4914 action_actor_kind_name(
4915 action_id_get_actor_kind(act_id)),
4916 action_actor_kind_name(AAK_UNIT));
4917
4918 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
4919 ACTPROB_IMPOSSIBLE,
4920 "Action %s is against %s not %s",
4921 action_id_rule_name(act_id),
4922 action_target_kind_name(
4923 action_id_get_target_kind(act_id)),
4924 action_target_kind_name(ATK_CITY));
4925
4926 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4927
4928 if (!unit_can_do_action(actor_unit, act_id)) {
4929 /* No point in continuing. */
4930 return ACTPROB_IMPOSSIBLE;
4931 }
4932
4933 /* Doesn't leak information about city position since an unknown city
4934 * can't be targeted and a city can't move. */
4935 if (!action_id_distance_accepted(act_id,
4936 real_map_distance(actor_tile,
4937 city_tile(target_city)))) {
4938 /* No point in continuing. */
4939 return ACTPROB_IMPOSSIBLE;
4940 }
4941
4942 /* Doesn't leak information since it must be 100% certain from the
4943 * player's perspective that the blocking action is legal. */
4944 if (action_is_blocked_by(act, actor_unit,
4945 city_tile(target_city), target_city, NULL)) {
4946 /* Don't offer to perform an action known to be blocked. */
4947 return ACTPROB_IMPOSSIBLE;
4948 }
4949
4950 if (!player_can_see_city_externals(unit_owner(actor_unit), target_city)) {
4951 /* The invisible city at this tile may, as far as the player knows, not
4952 * exist anymore. */
4953 return act_prob_unseen_target(nmap, act_id, actor_unit);
4954 }
4955
4956 target_building = tgt_city_local_building(target_city);
4957 target_utype = tgt_city_local_utype(target_city);
4958
4959 return action_prob(nmap, act_id,
4960 &(const struct req_context) {
4961 .player = unit_owner(actor_unit),
4962 .city = tile_city(actor_tile),
4963 .tile = actor_tile,
4964 .unit = actor_unit,
4965 .unittype = unit_type_get(actor_unit),
4966 },
4967 actor_home,
4968 &(const struct req_context) {
4969 .player = city_owner(target_city),
4970 .city = target_city,
4971 .building = target_building,
4972 .tile = city_tile(target_city),
4973 .unittype = target_utype,
4974 }, NULL);
4975}
4976
4977/**********************************************************************/
4981 struct act_prob action_prob_vs_city(const struct unit *actor_unit,
4982 const action_id act_id,
4983 const struct city *target_city)
4984{
4985 const struct civ_map *nmap = &(wld.map);
4986
4987 return action_prob_vs_city_full(nmap, actor_unit,
4988 unit_home(actor_unit),
4989 unit_tile(actor_unit),
4990 act_id, target_city);
4991}
4992
4993/**********************************************************************/
4997static struct act_prob
4998action_prob_vs_unit_full(const struct civ_map *nmap,
4999 const struct unit *actor_unit,
5000 const struct city *actor_home,
5001 const struct tile *actor_tile,
5002 const action_id act_id,
5003 const struct unit *target_unit)
5004{
5005 if (actor_unit == NULL || target_unit == NULL) {
5006 /* Can't do an action when actor or target are missing. */
5007 return ACTPROB_IMPOSSIBLE;
5008 }
5009
5010 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5011 ACTPROB_IMPOSSIBLE,
5012 "Action %s is performed by %s not %s",
5013 action_id_rule_name(act_id),
5014 action_actor_kind_name(
5015 action_id_get_actor_kind(act_id)),
5016 action_actor_kind_name(AAK_UNIT));
5017
5018 fc_assert_ret_val_msg(ATK_UNIT == action_id_get_target_kind(act_id),
5019 ACTPROB_IMPOSSIBLE,
5020 "Action %s is against %s not %s",
5021 action_id_rule_name(act_id),
5022 action_target_kind_name(
5023 action_id_get_target_kind(act_id)),
5024 action_target_kind_name(ATK_UNIT));
5025
5026 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5027
5028 if (!unit_can_do_action(actor_unit, act_id)) {
5029 /* No point in continuing. */
5030 return ACTPROB_IMPOSSIBLE;
5031 }
5032
5033 /* Doesn't leak information about unit position since an unseen unit can't
5034 * be targeted. */
5035 if (!action_id_distance_accepted(act_id,
5036 real_map_distance(actor_tile,
5037 unit_tile(target_unit)))) {
5038 /* No point in continuing. */
5039 return ACTPROB_IMPOSSIBLE;
5040 }
5041
5042 return action_prob(nmap, act_id,
5043 &(const struct req_context) {
5044 .player = unit_owner(actor_unit),
5045 .city = tile_city(actor_tile),
5046 .tile = actor_tile,
5047 .unit = actor_unit,
5048 .unittype = unit_type_get(actor_unit),
5049 },
5050 actor_home,
5051 &(const struct req_context) {
5052 .player = unit_owner(target_unit),
5053 .city = tile_city(unit_tile(target_unit)),
5054 .tile = unit_tile(target_unit),
5055 .unit = target_unit,
5056 .unittype = unit_type_get(target_unit),
5057 },
5058 NULL);
5059}
5060
5061/**********************************************************************/
5065 struct act_prob action_prob_vs_unit(const struct unit *actor_unit,
5066 const action_id act_id,
5067 const struct unit *target_unit)
5068{
5069 const struct civ_map *nmap = &(wld.map);
5070
5071 return action_prob_vs_unit_full(nmap, actor_unit,
5072 unit_home(actor_unit),
5073 unit_tile(actor_unit),
5074 act_id,
5075 target_unit);
5076}
5077
5078/**********************************************************************/
5082static struct act_prob
5083action_prob_vs_stack_full(const struct civ_map *nmap,
5084 const struct unit *actor_unit,
5085 const struct city *actor_home,
5086 const struct tile *actor_tile,
5087 const action_id act_id,
5088 const struct tile *target_tile)
5089{
5090 struct act_prob prob_all;
5091 const struct req_context *actor_ctxt;
5092 const struct action *act = action_by_number(act_id);
5093
5094 if (actor_unit == NULL || target_tile == NULL) {
5095 /* Can't do an action when actor or target are missing. */
5096 return ACTPROB_IMPOSSIBLE;
5097 }
5098
5099 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5100 ACTPROB_IMPOSSIBLE,
5101 "Action %s is performed by %s not %s",
5102 action_id_rule_name(act_id),
5103 action_actor_kind_name(
5104 action_id_get_actor_kind(act_id)),
5105 action_actor_kind_name(AAK_UNIT));
5106
5107 fc_assert_ret_val_msg(ATK_UNITS == action_id_get_target_kind(act_id),
5108 ACTPROB_IMPOSSIBLE,
5109 "Action %s is against %s not %s",
5110 action_id_rule_name(act_id),
5111 action_target_kind_name(
5112 action_id_get_target_kind(act_id)),
5113 action_target_kind_name(ATK_UNITS));
5114
5115 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5116
5117 if (!unit_can_do_action(actor_unit, act_id)) {
5118 /* No point in continuing. */
5119 return ACTPROB_IMPOSSIBLE;
5120 }
5121
5122 /* Doesn't leak information about unit stack position since it is
5123 * specified as a tile and an unknown tile's position is known. */
5124 if (!action_id_distance_accepted(act_id,
5125 real_map_distance(actor_tile,
5126 target_tile))) {
5127 /* No point in continuing. */
5128 return ACTPROB_IMPOSSIBLE;
5129 }
5130
5131 /* Doesn't leak information since the actor player can see the target
5132 * tile. */
5133 if (tile_is_seen(target_tile, unit_owner(actor_unit))
5134 && tile_city(target_tile) != NULL
5135 && !utype_can_do_act_if_tgt_citytile(unit_type_get(actor_unit),
5136 act_id,
5137 CITYT_CENTER, TRUE)) {
5138 /* Don't offer to perform actions that never can target a unit stack in
5139 * a city. */
5140 return ACTPROB_IMPOSSIBLE;
5141 }
5142
5143 /* Doesn't leak information since it must be 100% certain from the
5144 * player's perspective that the blocking action is legal. */
5145 unit_list_iterate(target_tile->units, target_unit) {
5146 if (action_is_blocked_by(act, actor_unit,
5147 target_tile, tile_city(target_tile),
5148 target_unit)) {
5149 /* Don't offer to perform an action known to be blocked. */
5150 return ACTPROB_IMPOSSIBLE;
5151 }
5152 } unit_list_iterate_end;
5153
5154 /* Must be done here since an empty unseen tile will result in
5155 * ACTPROB_IMPOSSIBLE. */
5156 if (unit_list_size(target_tile->units) == 0) {
5157 /* Can't act against an empty tile. */
5158
5159 if (player_can_trust_tile_has_no_units(unit_owner(actor_unit),
5160 target_tile)) {
5161 /* Known empty tile. */
5162 return ACTPROB_IMPOSSIBLE;
5163 } else {
5164 /* The player doesn't know that the tile is empty. */
5165 return act_prob_unseen_target(nmap, act_id, actor_unit);
5166 }
5167 }
5168
5169 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK)
5170 || action_id_has_result_safe(act_id, ACTRES_WIPE_UNITS)
5171 || action_id_has_result_safe(act_id, ACTRES_COLLECT_RANSOM))
5172 && tile_city(target_tile) != NULL
5173 && !pplayers_at_war(city_owner(tile_city(target_tile)),
5174 unit_owner(actor_unit))) {
5175 /* Hard coded rule: can't "Bombard", "Suicide Attack", or "Attack"
5176 * units in non enemy cities. */
5177 return ACTPROB_IMPOSSIBLE;
5178 }
5179
5180 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK)
5181 || action_id_has_result_safe(act_id, ACTRES_WIPE_UNITS)
5182 || action_id_has_result_safe(act_id, ACTRES_NUKE_UNITS)
5183 || action_id_has_result_safe(act_id, ACTRES_COLLECT_RANSOM))
5184 && !is_native_tile(unit_type_get(actor_unit), target_tile)
5185 && !can_attack_non_native(unit_type_get(actor_unit))) {
5186 /* Hard coded rule: can't "Nuke Units", "Wipe Units", "Suicide Attack",
5187 * or "Attack" units on non native tile without "AttackNonNative" and
5188 * not "Only_Native_Attack". */
5189 return ACTPROB_IMPOSSIBLE;
5190 }
5191
5192 /* Invisible units at this tile can make the action legal or illegal.
5193 * Invisible units can be stacked with visible units. The possible
5194 * existence of invisible units therefore makes the result uncertain. */
5195 prob_all = (can_player_see_hypotetic_units_at(unit_owner(actor_unit),
5196 target_tile)
5197 ? ACTPROB_CERTAIN : ACTPROB_NOT_KNOWN);
5198
5199 actor_ctxt = &(const struct req_context) {
5200 .player = unit_owner(actor_unit),
5201 .city = tile_city(actor_tile),
5202 .tile = actor_tile,
5203 .unit = actor_unit,
5204 .unittype = unit_type_get(actor_unit),
5205 };
5206
5207 unit_list_iterate(target_tile->units, target_unit) {
5208 struct act_prob prob_unit;
5209
5210 if (!can_player_see_unit(unit_owner(actor_unit), target_unit)) {
5211 /* Only visible units are considered. The invisible units contributed
5212 * their uncertainty to prob_all above. */
5213 continue;
5214 }
5215
5216 prob_unit = action_prob(nmap, act_id, actor_ctxt, actor_home,
5217 &(const struct req_context) {
5218 .player = unit_owner(target_unit),
5219 .city = tile_city(unit_tile(target_unit)),
5220 .tile = unit_tile(target_unit),
5221 .unit = target_unit,
5222 .unittype = unit_type_get(target_unit),
5223 },
5224 NULL);
5225
5226 if (!action_prob_possible(prob_unit)) {
5227 /* One unit makes it impossible for all units. */
5228 return ACTPROB_IMPOSSIBLE;
5229 } else if (action_prob_not_impl(prob_unit)) {
5230 /* Not implemented dominates all except impossible. */
5231 prob_all = ACTPROB_NOT_IMPLEMENTED;
5232 } else {
5233 fc_assert_msg(!action_prob_is_signal(prob_unit),
5234 "Invalid probability [%d, %d]",
5235 prob_unit.min, prob_unit.max);
5236
5237 if (action_prob_is_signal(prob_all)) {
5238 /* Special values dominate regular values. */
5239 continue;
5240 }
5241
5242 /* Probability against all target units considered until this moment
5243 * and the probability against this target unit. */
5244 prob_all.min = (prob_all.min * prob_unit.min) / ACTPROB_VAL_MAX;
5245 prob_all.max = (prob_all.max * prob_unit.max) / ACTPROB_VAL_MAX;
5246 break;
5247 }
5248 } unit_list_iterate_end;
5249
5250 /* Not impossible for any of the units at the tile. */
5251 return prob_all;
5252}
5253
5254/**********************************************************************/
5258 struct act_prob action_prob_vs_stack(const struct unit *actor_unit,
5259 const action_id act_id,
5260 const struct tile *target_tile)
5261{
5262 const struct civ_map *nmap = &(wld.map);
5263
5264 return action_prob_vs_stack_full(nmap, actor_unit,
5265 unit_home(actor_unit),
5266 unit_tile(actor_unit),
5267 act_id,
5268 target_tile);
5269}
5270
5271/**********************************************************************/
5275static struct act_prob
5276action_prob_vs_tile_full(const struct civ_map *nmap,
5277 const struct unit *actor_unit,
5278 const struct city *actor_home,
5279 const struct tile *actor_tile,
5280 const action_id act_id,
5281 const struct tile *target_tile,
5282 const struct extra_type *target_extra)
5283{
5284 if (actor_unit == NULL || target_tile == NULL) {
5285 /* Can't do an action when actor or target are missing. */
5286 return ACTPROB_IMPOSSIBLE;
5287 }
5288
5289 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5290 ACTPROB_IMPOSSIBLE,
5291 "Action %s is performed by %s not %s",
5292 action_id_rule_name(act_id),
5293 action_actor_kind_name(
5294 action_id_get_actor_kind(act_id)),
5295 action_actor_kind_name(AAK_UNIT));
5296
5297 fc_assert_ret_val_msg(ATK_TILE == action_id_get_target_kind(act_id),
5298 ACTPROB_IMPOSSIBLE,
5299 "Action %s is against %s not %s",
5300 action_id_rule_name(act_id),
5301 action_target_kind_name(
5302 action_id_get_target_kind(act_id)),
5303 action_target_kind_name(ATK_TILE));
5304
5305 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5306
5307 if (!unit_can_do_action(actor_unit, act_id)) {
5308 /* No point in continuing. */
5309 return ACTPROB_IMPOSSIBLE;
5310 }
5311
5312 /* Doesn't leak information about tile position since an unknown tile's
5313 * position is known. */
5314 if (!action_id_distance_accepted(act_id,
5315 real_map_distance(actor_tile,
5316 target_tile))) {
5317 /* No point in continuing. */
5318 return ACTPROB_IMPOSSIBLE;
5319 }
5320
5321 return action_prob(nmap, act_id,
5322 &(const struct req_context) {
5323 .player = unit_owner(actor_unit),
5324 .city = tile_city(actor_tile),
5325 .tile = actor_tile,
5326 .unit = actor_unit,
5327 .unittype = unit_type_get(actor_unit),
5328 },
5329 actor_home,
5330 &(const struct req_context) {
5331 .player = tile_owner(target_tile),
5332 .city = tile_city(target_tile),
5333 .tile = target_tile,
5334 },
5335 target_extra);
5336}
5337
5338/**********************************************************************/
5342 struct act_prob action_prob_vs_tile(const struct unit *actor_unit,
5343 const action_id act_id,
5344 const struct tile *target_tile,
5345 const struct extra_type *target_extra)
5346{
5347 const struct civ_map *nmap = &(wld.map);
5348
5349 return action_prob_vs_tile_full(nmap, actor_unit,
5350 unit_home(actor_unit),
5351 unit_tile(actor_unit),
5352 act_id, target_tile, target_extra);
5353}
5354
5355/**********************************************************************/
5359static struct act_prob
5360action_prob_vs_extras_full(const struct civ_map *nmap,
5361 const struct unit *actor_unit,
5362 const struct city *actor_home,
5363 const struct tile *actor_tile,
5364 const action_id act_id,
5365 const struct tile *target_tile,
5366 const struct extra_type *target_extra)
5367{
5368 if (actor_unit == NULL || target_tile == NULL) {
5369 /* Can't do an action when actor or target are missing. */
5370 return ACTPROB_IMPOSSIBLE;
5371 }
5372
5373 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5374 ACTPROB_IMPOSSIBLE,
5375 "Action %s is performed by %s not %s",
5376 action_id_rule_name(act_id),
5377 action_actor_kind_name(
5378 action_id_get_actor_kind(act_id)),
5379 action_actor_kind_name(AAK_UNIT));
5380
5381 fc_assert_ret_val_msg(ATK_EXTRAS == action_id_get_target_kind(act_id),
5382 ACTPROB_IMPOSSIBLE,
5383 "Action %s is against %s not %s",
5384 action_id_rule_name(act_id),
5385 action_target_kind_name(
5386 action_id_get_target_kind(act_id)),
5387 action_target_kind_name(ATK_EXTRAS));
5388
5389 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5390
5391 if (!unit_can_do_action(actor_unit, act_id)) {
5392 /* No point in continuing. */
5393 return ACTPROB_IMPOSSIBLE;
5394 }
5395
5396 /* Doesn't leak information about tile position since an unknown tile's
5397 * position is known. */
5398 if (!action_id_distance_accepted(act_id,
5399 real_map_distance(actor_tile,
5400 target_tile))) {
5401 /* No point in continuing. */
5402 return ACTPROB_IMPOSSIBLE;
5403 }
5404
5405 return action_prob(nmap, act_id,
5406 &(const struct req_context) {
5407 .player = unit_owner(actor_unit),
5408 .city = tile_city(actor_tile),
5409 .tile = actor_tile,
5410 .unit = actor_unit,
5411 .unittype = unit_type_get(actor_unit),
5412 },
5413 actor_home,
5414 &(const struct req_context) {
5415 .player = target_tile->extras_owner,
5416 .city = tile_city(target_tile),
5417 .tile = target_tile,
5418 },
5419 target_extra);
5420}
5421
5422/**********************************************************************/
5426 struct act_prob action_prob_vs_extras(const struct unit *actor_unit,
5427 const action_id act_id,
5428 const struct tile *target_tile,
5429 const struct extra_type *target_extra)
5430{
5431 const struct civ_map *nmap = &(wld.map);
5432
5433 return action_prob_vs_extras_full(nmap, actor_unit,
5434 unit_home(actor_unit),
5435 unit_tile(actor_unit),
5436 act_id, target_tile, target_extra);
5437}
5438
5439/**********************************************************************/
5443static struct act_prob
5444action_prob_self_full(const struct civ_map *nmap,
5445 const struct unit *actor_unit,
5446 const struct city *actor_home,
5447 const struct tile *actor_tile,
5448 const action_id act_id)
5449{
5450 if (actor_unit == NULL) {
5451 /* Can't do the action when the actor is missing. */
5452 return ACTPROB_IMPOSSIBLE;
5453 }
5454
5455 /* No point in checking distance to target. It is always 0. */
5456
5457 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
5458 ACTPROB_IMPOSSIBLE,
5459 "Action %s is performed by %s not %s",
5460 action_id_rule_name(act_id),
5461 action_actor_kind_name(
5462 action_id_get_actor_kind(act_id)),
5463 action_actor_kind_name(AAK_UNIT));
5464
5465 fc_assert_ret_val_msg(ATK_SELF == action_id_get_target_kind(act_id),
5466 ACTPROB_IMPOSSIBLE,
5467 "Action %s is against %s not %s",
5468 action_id_rule_name(act_id),
5469 action_target_kind_name(
5470 action_id_get_target_kind(act_id)),
5471 action_target_kind_name(ATK_SELF));
5472
5473 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
5474
5475 if (!unit_can_do_action(actor_unit, act_id)) {
5476 /* No point in continuing. */
5477 return ACTPROB_IMPOSSIBLE;
5478 }
5479
5480 return action_prob(nmap, act_id,
5481 &(const struct req_context) {
5482 .player = unit_owner(actor_unit),
5483 .city = tile_city(actor_tile),
5484 .tile = actor_tile,
5485 .unit = actor_unit,
5486 .unittype = unit_type_get(actor_unit),
5487 },
5488 actor_home,
5489 NULL,
5490 NULL);
5491}
5492
5493/**********************************************************************/
5497 struct act_prob action_prob_self(const struct unit *actor_unit,
5498 const action_id act_id)
5499{
5500 const struct civ_map *nmap = &(wld.map);
5501
5502 return action_prob_self_full(nmap, actor_unit,
5503 unit_home(actor_unit),
5504 unit_tile(actor_unit),
5505 act_id);
5506}
5507
5508/**********************************************************************/
5519 struct act_prob action_prob_unit_vs_tgt(const struct action *paction,
5520 const struct unit *act_unit,
5521 const struct city *tgt_city,
5522 const struct unit *tgt_unit,
5523 const struct tile *tgt_tile,
5524 const struct extra_type *extra_tgt)
5525{
5526 /* Assume impossible until told otherwise. */
5527 struct act_prob prob = ACTPROB_IMPOSSIBLE;
5528
5529 fc_assert_ret_val(paction, ACTPROB_IMPOSSIBLE);
5530 fc_assert_ret_val(act_unit, ACTPROB_IMPOSSIBLE);
5531
5532 switch (action_get_target_kind(paction)) {
5533 case ATK_UNITS:
5534 if (tgt_tile) {
5535 prob = action_prob_vs_stack(act_unit, paction->id, tgt_tile);
5536 }
5537 break;
5538 case ATK_TILE:
5539 if (tgt_tile) {
5540 prob = action_prob_vs_tile(act_unit, paction->id, tgt_tile, extra_tgt);
5541 }
5542 break;
5543 case ATK_EXTRAS:
5544 if (tgt_tile) {
5545 prob = action_prob_vs_extras(act_unit, paction->id,
5546 tgt_tile, extra_tgt);
5547 }
5548 break;
5549 case ATK_CITY:
5550 if (tgt_city) {
5551 prob = action_prob_vs_city(act_unit, paction->id, tgt_city);
5552 }
5553 break;
5554 case ATK_UNIT:
5555 if (tgt_unit) {
5556 prob = action_prob_vs_unit(act_unit, paction->id, tgt_unit);
5557 }
5558 break;
5559 case ATK_SELF:
5560 prob = action_prob_self(act_unit, paction->id);
5561 break;
5562 case ATK_COUNT:
5563 log_error("Invalid action target kind");
5564 break;
5565 }
5566
5567 return prob;
5568}
5569
5570/**********************************************************************/
5575 struct act_prob action_speculate_unit_on_city(const action_id act_id,
5576 const struct unit *actor,
5577 const struct city *actor_home,
5578 const struct tile *actor_tile,
5579 const bool omniscient_cheat,
5580 const struct city* target)
5581{
5582 /* FIXME: some unit state requirements still depend on the actor unit's
5583 * current position rather than on actor_tile. Maybe this function should
5584 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5585 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5586 const struct civ_map *nmap = &(wld.map);
5587
5588 if (omniscient_cheat) {
5589 if (is_action_enabled_unit_on_city_full(nmap, act_id,
5590 actor, actor_home, actor_tile,
5591 target)) {
5592 return ACTPROB_CERTAIN;
5593 } else {
5594 return ACTPROB_IMPOSSIBLE;
5595 }
5596 } else {
5597 /* FIXME: this branch result depends _directly_ on actor's position.
5598 * I.e., like, not adjacent, no action. Other branch ignores radius. */
5599 return action_prob_vs_city_full(nmap, actor, actor_home, actor_tile,
5600 act_id, target);
5601 }
5602}
5603
5604/**********************************************************************/
5609struct act_prob
5610action_speculate_unit_on_unit(action_id act_id,
5611 const struct unit *actor,
5612 const struct city *actor_home,
5613 const struct tile *actor_tile,
5614 bool omniscient_cheat,
5615 const struct unit *target)
5616{
5617 /* FIXME: some unit state requirements still depend on the actor unit's
5618 * current position rather than on actor_tile. Maybe this function should
5619 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5620 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5621 const struct civ_map *nmap = &(wld.map);
5622
5623 if (omniscient_cheat) {
5624 if (is_action_enabled_unit_on_unit_full(nmap, act_id,
5625 actor, actor_home, actor_tile,
5626 target)) {
5627 return ACTPROB_CERTAIN;
5628 } else {
5629 return ACTPROB_IMPOSSIBLE;
5630 }
5631 } else {
5632 return action_prob_vs_unit_full(nmap, actor, actor_home, actor_tile,
5633 act_id, target);
5634 }
5635}
5636
5637/**********************************************************************/
5642struct act_prob
5643action_speculate_unit_on_stack(action_id act_id,
5644 const struct unit *actor,
5645 const struct city *actor_home,
5646 const struct tile *actor_tile,
5647 bool omniscient_cheat,
5648 const struct tile *target)
5649{
5650 /* FIXME: some unit state requirements still depend on the actor unit's
5651 * current position rather than on actor_tile. Maybe this function should
5652 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5653 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5654 const struct civ_map *nmap = &(wld.map);
5655
5656 if (omniscient_cheat) {
5657 if (is_action_enabled_unit_on_stack_full(nmap, act_id,
5658 actor, actor_home, actor_tile,
5659 target)) {
5660 return ACTPROB_CERTAIN;
5661 } else {
5662 return ACTPROB_IMPOSSIBLE;
5663 }
5664 } else {
5665 return action_prob_vs_stack_full(nmap, actor, actor_home, actor_tile,
5666 act_id, target);
5667 }
5668}
5669
5670/**********************************************************************/
5675struct act_prob
5676action_speculate_unit_on_tile(action_id act_id,
5677 const struct unit *actor,
5678 const struct city *actor_home,
5679 const struct tile *actor_tile,
5680 bool omniscient_cheat,
5681 const struct tile *target_tile,
5682 const struct extra_type *target_extra)
5683{
5684 /* FIXME: some unit state requirements still depend on the actor unit's
5685 * current position rather than on actor_tile. Maybe this function should
5686 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5687 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5688 const struct civ_map *nmap = &(wld.map);
5689
5690 if (omniscient_cheat) {
5691 if (is_action_enabled_unit_on_tile_full(nmap, act_id,
5692 actor, actor_home, actor_tile,
5693 target_tile, target_extra)) {
5694 return ACTPROB_CERTAIN;
5695 } else {
5696 return ACTPROB_IMPOSSIBLE;
5697 }
5698 } else {
5699 return action_prob_vs_tile_full(nmap, actor, actor_home, actor_tile,
5700 act_id, target_tile, target_extra);
5701 }
5702}
5703
5704/**********************************************************************/
5709struct act_prob
5710action_speculate_unit_on_extras(action_id act_id,
5711 const struct unit *actor,
5712 const struct city *actor_home,
5713 const struct tile *actor_tile,
5714 bool omniscient_cheat,
5715 const struct tile *target_tile,
5716 const struct extra_type *target_extra)
5717{
5718 /* FIXME: some unit state requirements still depend on the actor unit's
5719 * current position rather than on actor_tile. Maybe this function should
5720 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5721 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5722 const struct civ_map *nmap = &(wld.map);
5723
5724 if (omniscient_cheat) {
5725 if (is_action_enabled_unit_on_extras_full(nmap, act_id,
5726 actor, actor_home, actor_tile,
5727 target_tile, target_extra)) {
5728 return ACTPROB_CERTAIN;
5729 } else {
5730 return ACTPROB_IMPOSSIBLE;
5731 }
5732 } else {
5733 return action_prob_vs_extras_full(nmap, actor, actor_home, actor_tile,
5734 act_id, target_tile, target_extra);
5735 }
5736}
5737
5738/**********************************************************************/
5743struct act_prob
5744action_speculate_unit_on_self(action_id act_id,
5745 const struct unit *actor,
5746 const struct city *actor_home,
5747 const struct tile *actor_tile,
5748 bool omniscient_cheat)
5749{
5750 /* FIXME: some unit state requirements still depend on the actor unit's
5751 * current position rather than on actor_tile. Maybe this function should
5752 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
5753 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
5754 const struct civ_map *nmap = &(wld.map);
5755
5756 if (omniscient_cheat) {
5757 if (is_action_enabled_unit_on_self_full(nmap, act_id,
5758 actor, actor_home, actor_tile)) {
5759 return ACTPROB_CERTAIN;
5760 } else {
5761 return ACTPROB_IMPOSSIBLE;
5762 }
5763 } else {
5764 return action_prob_self_full(nmap, actor, actor_home, actor_tile,
5765 act_id);
5766 }
5767}
5768
5769/**********************************************************************/
5772 struct act_prob action_prob_new_impossible(void)
5773{
5774 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MIN };
5775
5776 return out;
5777}
5778
5779/**********************************************************************/
5782 struct act_prob action_prob_new_certain(void)
5783{
5784 struct act_prob out = { ACTPROB_VAL_MAX, ACTPROB_VAL_MAX };
5785
5786 return out;
5787}
5788
5789/**********************************************************************/
5792 struct act_prob action_prob_new_not_relevant(void)
5793{
5794 struct act_prob out = { ACTPROB_VAL_NA, ACTPROB_VAL_MIN};
5795
5796 return out;
5797}
5798
5799/**********************************************************************/
5802 struct act_prob action_prob_new_not_impl(void)
5803{
5804 struct act_prob out = { ACTPROB_VAL_NOT_IMPL, ACTPROB_VAL_MIN };
5805
5806 return out;
5807}
5808
5809/**********************************************************************/
5812 struct act_prob action_prob_new_unknown(void)
5813{
5814 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MAX };
5815
5816 return out;
5817}
5818
5819/**********************************************************************/
5823 bool action_prob_possible(const struct act_prob probability)
5824{
5825 return (ACTPROB_VAL_MIN < probability.max
5826 || action_prob_not_impl(probability));
5827}
5828
5829/**********************************************************************/
5833 bool action_prob_certain(const struct act_prob probability)
5834{
5835 return (ACTPROB_VAL_MAX == probability.min
5836 && ACTPROB_VAL_MAX == probability.max);
5837}
5838
5839/**********************************************************************/
5843static inline bool
5844action_prob_not_relevant(const struct act_prob probability)
5845{
5846 return probability.min == ACTPROB_VAL_NA
5847 && probability.max == ACTPROB_VAL_MIN;
5848}
5849
5850/**********************************************************************/
5854static inline bool
5855action_prob_not_impl(const struct act_prob probability)
5856{
5857 return probability.min == ACTPROB_VAL_NOT_IMPL
5858 && probability.max == ACTPROB_VAL_MIN;
5859}
5860
5861/**********************************************************************/
5865static inline bool
5866action_prob_is_signal(const struct act_prob probability)
5867{
5868 return probability.max < probability.min;
5869}
5870
5871/**********************************************************************/
5874 bool are_action_probabilitys_equal(const struct act_prob *ap1,
5875 const struct act_prob *ap2)
5876{
5877 return ap1->min == ap2->min && ap1->max == ap2->max;
5878}
5879
5880/**********************************************************************/
5883 int action_prob_cmp_pessimist(const struct act_prob ap1,
5884 const struct act_prob ap2)
5885{
5886 struct act_prob my_ap1;
5887 struct act_prob my_ap2;
5888
5889 /* The action probabilities are real. */
5890 fc_assert(!action_prob_not_relevant(ap1));
5891 fc_assert(!action_prob_not_relevant(ap2));
5892
5893 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5894 if (action_prob_is_signal(ap1)) {
5895 /* Assert that it is OK to convert the signal. */
5896 fc_assert(action_prob_not_impl(ap1));
5897
5898 my_ap1 = ACTPROB_NOT_KNOWN;
5899 } else {
5900 my_ap1 = ap1;
5901 }
5902
5903 if (action_prob_is_signal(ap2)) {
5904 /* Assert that it is OK to convert the signal. */
5905 fc_assert(action_prob_not_impl(ap2));
5906
5907 my_ap2 = ACTPROB_NOT_KNOWN;
5908 } else {
5909 my_ap2 = ap2;
5910 }
5911
5912 /* The action probabilities now have a comparison friendly form. */
5913 fc_assert(!action_prob_is_signal(my_ap1));
5914 fc_assert(!action_prob_is_signal(my_ap2));
5915
5916 /* Do the comparison. Start with min. Continue with max. */
5917 if (my_ap1.min < my_ap2.min) {
5918 return -1;
5919 } else if (my_ap1.min > my_ap2.min) {
5920 return 1;
5921 } else if (my_ap1.max < my_ap2.max) {
5922 return -1;
5923 } else if (my_ap1.max > my_ap2.max) {
5924 return 1;
5925 } else {
5926 return 0;
5927 }
5928}
5929
5930/**********************************************************************/
5934 double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
5935{
5936 struct act_prob my_ap;
5937
5938 /* The action probability is real. */
5939 fc_assert(!action_prob_not_relevant(ap));
5940
5941 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5942 if (action_prob_is_signal(ap)) {
5943 /* Assert that it is OK to convert the signal. */
5944 fc_assert(action_prob_not_impl(ap));
5945
5946 my_ap = ACTPROB_NOT_KNOWN;
5947 } else {
5948 my_ap = ap;
5949 }
5950
5951 /* The action probability now has a math friendly form. */
5952 fc_assert(!action_prob_is_signal(my_ap));
5953
5954 return (double)my_ap.min / (double) ACTPROB_VAL_MAX;
5955}
5956
5957/**********************************************************************/
5961 struct act_prob action_prob_and(const struct act_prob *ap1,
5962 const struct act_prob *ap2)
5963{
5964 struct act_prob my_ap1;
5965 struct act_prob my_ap2;
5966 struct act_prob out;
5967
5968 /* The action probabilities are real. */
5969 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
5970 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
5971
5972 if (action_prob_is_signal(*ap1)
5973 && are_action_probabilitys_equal(ap1, ap2)) {
5974 /* Keep the information rather than converting the signal to
5975 * ACTPROB_NOT_KNOWN. */
5976
5977 /* Assert that it is OK to convert the signal. */
5978 fc_assert(action_prob_not_impl(*ap1));
5979
5980 out.min = ap1->min;
5981 out.max = ap2->max;
5982
5983 return out;
5984 }
5985
5986 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5987 if (action_prob_is_signal(*ap1)) {
5988 /* Assert that it is OK to convert the signal. */
5989 fc_assert(action_prob_not_impl(*ap1));
5990
5991 my_ap1.min = ACTPROB_VAL_MIN;
5992 my_ap1.max = ACTPROB_VAL_MAX;
5993 } else {
5994 my_ap1.min = ap1->min;
5995 my_ap1.max = ap1->max;
5996 }
5997
5998 if (action_prob_is_signal(*ap2)) {
5999 /* Assert that it is OK to convert the signal. */
6000 fc_assert(action_prob_not_impl(*ap2));
6001
6002 my_ap2.min = ACTPROB_VAL_MIN;
6003 my_ap2.max = ACTPROB_VAL_MAX;
6004 } else {
6005 my_ap2.min = ap2->min;
6006 my_ap2.max = ap2->max;
6007 }
6008
6009 /* The action probabilities now have a math friendly form. */
6010 fc_assert(!action_prob_is_signal(my_ap1));
6011 fc_assert(!action_prob_is_signal(my_ap2));
6012
6013 /* Do the math. */
6014 out.min = (my_ap1.min * my_ap2.min) / ACTPROB_VAL_MAX;
6015 out.max = (my_ap1.max * my_ap2.max) / ACTPROB_VAL_MAX;
6016
6017 /* Cap at 100%. */
6018 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6019 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6020
6021 return out;
6022}
6023
6024/**********************************************************************/
6031 struct act_prob action_prob_fall_back(const struct act_prob *ap1,
6032 const struct act_prob *ap2)
6033{
6034 struct act_prob my_ap1;
6035 struct act_prob my_ap2;
6036 struct act_prob out;
6037
6038 /* The action probabilities are real. */
6039 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
6040 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
6041
6042 if (action_prob_is_signal(*ap1)
6043 && are_action_probabilitys_equal(ap1, ap2)) {
6044 /* Keep the information rather than converting the signal to
6045 * ACTPROB_NOT_KNOWN. */
6046
6047 /* Assert that it is OK to convert the signal. */
6048 fc_assert(action_prob_not_impl(*ap1));
6049
6050 out.min = ap1->min;
6051 out.max = ap2->max;
6052
6053 return out;
6054 }
6055
6056 /* Convert any signals to ACTPROB_NOT_KNOWN. */
6057 if (action_prob_is_signal(*ap1)) {
6058 /* Assert that it is OK to convert the signal. */
6059 fc_assert(action_prob_not_impl(*ap1));
6060
6061 my_ap1.min = ACTPROB_VAL_MIN;
6062 my_ap1.max = ACTPROB_VAL_MAX;
6063 } else {
6064 my_ap1.min = ap1->min;
6065 my_ap1.max = ap1->max;
6066 }
6067
6068 if (action_prob_is_signal(*ap2)) {
6069 /* Assert that it is OK to convert the signal. */
6070 fc_assert(action_prob_not_impl(*ap2));
6071
6072 my_ap2.min = ACTPROB_VAL_MIN;
6073 my_ap2.max = ACTPROB_VAL_MAX;
6074 } else {
6075 my_ap2.min = ap2->min;
6076 my_ap2.max = ap2->max;
6077 }
6078
6079 /* The action probabilities now have a math friendly form. */
6080 fc_assert(!action_prob_is_signal(my_ap1));
6081 fc_assert(!action_prob_is_signal(my_ap2));
6082
6083 /* Do the math. */
6084 out.min = my_ap1.min + (((ACTPROB_VAL_MAX - my_ap1.min) * my_ap2.min)
6085 / ACTPROB_VAL_MAX);
6086 out.max = my_ap1.max + (((ACTPROB_VAL_MAX - my_ap1.max) * my_ap2.max)
6087 / ACTPROB_VAL_MAX);
6088
6089 /* Cap at 100%. */
6090 out.min = MIN(out.min, ACTPROB_VAL_MAX);
6091 out.max = MIN(out.max, ACTPROB_VAL_MAX);
6092
6093 return out;
6094}
6095
6096/**********************************************************************/
6099 int action_dice_roll_initial_odds(const struct action *paction)
6100{
6101 switch (actres_dice_type(paction->result)) {
6102 case DRT_DIPLCHANCE:
6103 if (BV_ISSET(game.info.diplchance_initial_odds, paction->id)) {
6104 /* Take the initial odds from the diplchance setting. */
6105 return server_setting_value_int_get(
6106 server_setting_by_name("diplchance"));
6107 }
6108 fc__fallthrough;
6109 case DRT_CERTAIN:
6110 return 100;
6111 case DRT_NONE:
6112 break;
6113 }
6114
6115 /* The odds of the action not being stopped by its dice roll when the dice
6116 * isn't thrown is 100%. ACTION_ODDS_PCT_DICE_ROLL_NA is above 100% */
6117 return ACTION_ODDS_PCT_DICE_ROLL_NA;
6118}
6119
6120/**********************************************************************/
6123 int action_dice_roll_odds(const struct player *act_player,
6124 const struct unit *act_unit,
6125 const struct city *tgt_city,
6126 const struct player *tgt_player,
6127 const struct action *paction)
6128{
6129 int odds = action_dice_roll_initial_odds(paction);
6130 const struct unit_type *actu_type = unit_type_get(act_unit);
6131
6132 fc_assert_action_msg(odds >= 0 && odds <= 100,
6133 odds = 100,
6134 "Bad initial odds for action number %d."
6135 " Does it roll the dice at all?",
6136 paction->id);
6137
6138 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
6139 * it this way instead of rolling twice is that Action_Odds_Pct can
6140 * increase the odds. */
6141 odds = odds
6142 + ((odds
6143 * get_target_bonus_effects(NULL,
6144 &(const struct req_context) {
6145 .player = act_player,
6146 .city = tgt_city,
6147 .unit = act_unit,
6148 .unittype = actu_type,
6149 .action = paction,
6150 },
6151 tgt_player,
6152 EFT_ACTION_ODDS_PCT))
6153 / 100)
6154 - ((odds
6155 * get_target_bonus_effects(NULL,
6156 &(const struct req_context) {
6157 .player = tgt_player,
6158 .city = tgt_city,
6159 .unit = act_unit,
6160 .unittype = actu_type,
6161 .action = paction,
6162 },
6163 act_player,
6164 EFT_ACTION_RESIST_PCT))
6165 / 100);
6166
6167
6168 /* Odds are between 0% and 100%. */
6169 return CLIP(0, odds, 100);
6170}
6171
6172/**********************************************************************/
6175 bool action_immune_government(struct government *gov, action_id act)
6176{
6177 struct action *paction = action_by_number(act);
6178
6179 /* Always immune since its not enabled. Doesn't count. */
6180 if (!action_is_in_use(paction)) {
6181 return FALSE;
6182 }
6183
6184 action_enabler_list_iterate(action_enablers_for_action(act), enabler) {
6185 if (requirement_fulfilled_by_government(gov, &(enabler->target_reqs))) {
6186 return FALSE;
6187 }
6188 } action_enabler_list_iterate_end;
6189
6190 return TRUE;
6191}
6192
6193/**********************************************************************/
6198 static bool is_target_possible(const action_id wanted_action,
6199 const struct player *actor_player,
6200 const struct req_context *target)
6201{
6202 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
6203 enabler) {
6204 if (are_reqs_active(target, actor_player,
6205 &enabler->target_reqs, RPT_POSSIBLE)) {
6206 return TRUE;
6207 }
6208 } action_enabler_list_iterate_end;
6209
6210 return FALSE;
6211}
6212
6213/**********************************************************************/
6216 bool is_action_possible_on_city(action_id act_id,
6217 const struct player *actor_player,
6218 const struct city* target_city)
6219{
6220 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
6221 FALSE, "Action %s is against %s not cities",
6222 action_id_rule_name(act_id),
6223 action_target_kind_name(
6224 action_id_get_target_kind(act_id)));
6225
6226 return is_target_possible(act_id, actor_player,
6227 &(const struct req_context) {
6228 .player = city_owner(target_city),
6229 .city = target_city,
6230 .tile = city_tile(target_city),
6231 });
6232}
6233
6234/**********************************************************************/
6239 bool action_maybe_possible_actor_unit(const struct civ_map *nmap,
6240 const action_id act_id,
6241 const struct unit *actor_unit)
6242{
6243 const struct player *actor_player = unit_owner(actor_unit);
6244 const struct req_context actor_ctxt = {
6245 .player = actor_player,
6246 .city = tile_city(unit_tile(actor_unit)),
6247 .tile = unit_tile(actor_unit),
6248 .unit = actor_unit,
6249 .unittype = unit_type_get(actor_unit),
6250 };
6251 const struct action *paction = action_by_number(act_id);
6252
6253 enum fc_tristate result;
6254
6255 fc_assert_ret_val(actor_unit, FALSE);
6256
6257 if (!utype_can_do_action(actor_unit->utype, act_id)) {
6258 /* The unit type can't perform the action. */
6259 return FALSE;
6260 }
6261
6262 result = action_hard_reqs_actor(nmap, paction, &actor_ctxt, FALSE,
6263 unit_home(actor_unit));
6264
6265 if (result == TRI_NO) {
6266 /* The hard requirements aren't fulfilled. */
6267 return FALSE;
6268 }
6269
6270 action_enabler_list_iterate(action_enablers_for_action(act_id),
6271 enabler) {
6272 const enum fc_tristate current
6273 = mke_eval_reqs(actor_player, &actor_ctxt, NULL,
6274 &enabler->actor_reqs,
6275 /* Needed since no player to evaluate DiplRel
6276 * requirements against. */
6277 RPT_POSSIBLE);
6278
6279 if (current == TRI_YES
6280 || current == TRI_MAYBE) {
6281 /* The ruleset requirements may be fulfilled. */
6282 return TRUE;
6283 }
6284 } action_enabler_list_iterate_end;
6285
6286 /* No action enabler allows this action. */
6287 return FALSE;
6288}
6289
6290/**********************************************************************/
6294 bool action_mp_full_makes_legal(const struct unit *actor,
6295 const action_id act_id)
6296{
6297 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
6298
6299 /* Check if full movement points may enable the specified action. */
6300 return !utype_may_act_move_frags(unit_type_get(actor),
6301 act_id,
6302 actor->moves_left)
6303 && utype_may_act_move_frags(unit_type_get(actor),
6304 act_id,
6305 unit_move_rate(actor));
6306}
6307
6308/**********************************************************************/
6317 bool action_enabler_utype_possible_actor(const struct action_enabler *ae,
6318 const struct unit_type *act_utype)
6319{
6320 const struct action *paction = enabler_get_action(ae);
6321 struct universal actor_univ = { .kind = VUT_UTYPE,
6322 .value.utype = act_utype };
6323
6324 fc_assert_ret_val(paction != NULL, FALSE);
6325 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
6326 fc_assert_ret_val(act_utype != NULL, FALSE);
6327
6328 return (action_actor_utype_hard_reqs_ok(paction, act_utype)
6329 && !req_vec_is_impossible_to_fulfill(&ae->actor_reqs)
6330 && universal_fulfills_requirements(FALSE, &ae->actor_reqs,
6331 &actor_univ));
6332}
6333
6334/**********************************************************************/
6344 bool action_enabler_possible_actor(const struct action_enabler *ae)
6345{
6346 const struct action *paction = enabler_get_action(ae);
6347
6348 switch (action_get_actor_kind(paction)) {
6349 case AAK_UNIT:
6350 unit_type_iterate(putype) {
6351 if (action_enabler_utype_possible_actor(ae, putype)) {
6352 /* A possible actor unit type has been found. */
6353 return TRUE;
6354 }
6355 } unit_type_iterate_end;
6356
6357 /* No actor detected. */
6358 return FALSE;
6359 case AAK_COUNT:
6360 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
6361 break;
6362 }
6363
6364 /* No actor detected. */
6365 return FALSE;
6366}
6367
6368/**********************************************************************/
6375 static bool action_has_possible_actor_hard_reqs(struct action *paction)
6376{
6377 switch (action_get_actor_kind(paction)) {
6378 case AAK_UNIT:
6379 unit_type_iterate(putype) {
6380 if (action_actor_utype_hard_reqs_ok(paction, putype)) {
6381 return TRUE;
6382 }
6383 } unit_type_iterate_end;
6384 break;
6385 case AAK_COUNT:
6386 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
6387 break;
6388 }
6389
6390 /* No actor detected. */
6391 return FALSE;
6392}
6393
6394/**********************************************************************/
6400 bool action_is_in_use(struct action *paction)
6401{
6402 struct action_enabler_list *enablers;
6403
6404 if (!action_has_possible_actor_hard_reqs(paction)) {
6405 /* Hard requirements not fulfilled. */
6406 return FALSE;
6407 }
6408
6409 enablers = action_enablers_for_action(paction->id);
6410
6411 action_enabler_list_re_iterate(enablers, ae) {
6412 /* If this iteration finds any entries, action is enabled. */
6413 return TRUE;
6414 } action_enabler_list_re_iterate_end;
6415
6416 /* No non deleted action enabler. */
6417 return FALSE;
6418}
6419
6420/**********************************************************************/
6423 struct action_auto_perf *action_auto_perf_slot_number(const int num)
6424{
6425 fc_assert_ret_val(num >= 0, NULL);
6426 fc_assert_ret_val(num < MAX_NUM_ACTION_AUTO_PERFORMERS, NULL);
6427
6428 return &auto_perfs[num];
6429}
6430
6431/**********************************************************************/
6439 const struct action_auto_perf *action_auto_perf_by_number(const int num)
6440{
6441 return action_auto_perf_slot_number(num);
6442}
6443
6444/**********************************************************************/
6447 bool action_univs_not_blocking(const struct action *paction,
6448 struct universal *actor_uni,
6449 struct universal *target_uni)
6450{
6451 action_enabler_list_iterate(action_enablers_for_action(paction->id),
6452 enab) {
6453 if ((actor_uni == NULL
6454 || universal_fulfills_requirements(FALSE, &(enab->actor_reqs),
6455 actor_uni))
6456 && (target_uni == NULL
6457 || universal_fulfills_requirements(FALSE, &(enab->target_reqs),
6458 target_uni))) {
6459 return TRUE;
6460 }
6461 } action_enabler_list_iterate_end;
6462
6463 return FALSE;
6464}
6465
6466/**********************************************************************/
6471 void action_array_end(action_id *act_array, int size)
6472{
6473 fc_assert_ret(size <= MAX_NUM_ACTIONS);
6474
6475 if (size < MAX_NUM_ACTIONS) {
6476 /* An action array is terminated by ACTION_NONE */
6477 act_array[size] = ACTION_NONE;
6478 }
6479}
6480
6481/**********************************************************************/
6488 void action_array_add_all_by_result(action_id *act_array,
6489 int *position,
6490 enum action_result result)
6491{
6492 action_iterate(act) {
6493 struct action *paction = action_by_number(act);
6494 if (paction->result == result) {
6495 /* Assume one result for each action. */
6496 fc_assert_ret(*position < MAX_NUM_ACTIONS);
6497
6498 act_array[(*position)++] = paction->id;
6499 }
6500 } action_iterate_end;
6501}
6502
6503/**********************************************************************/
6508 const char *action_ui_name_ruleset_var_name(int act)
6509{
6510 switch ((enum gen_action)act) {
6511 case ACTION_SPY_POISON:
6512 return "ui_name_poison_city";
6513 case ACTION_SPY_POISON_ESC:
6514 return "ui_name_poison_city_escape";
6515 case ACTION_SPY_SABOTAGE_UNIT:
6516 return "ui_name_sabotage_unit";
6517 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6518 return "ui_name_sabotage_unit_escape";
6519 case ACTION_SPY_BRIBE_UNIT:
6520 return "ui_name_bribe_unit";
6521 case ACTION_SPY_SABOTAGE_CITY:
6522 return "ui_name_sabotage_city";
6523 case ACTION_SPY_SABOTAGE_CITY_ESC:
6524 return "ui_name_sabotage_city_escape";
6525 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6526 return "ui_name_targeted_sabotage_city";
6527 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6528 return "ui_name_sabotage_city_production";
6529 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6530 return "ui_name_targeted_sabotage_city_escape";
6531 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6532 return "ui_name_sabotage_city_production_escape";
6533 case ACTION_SPY_INCITE_CITY:
6534 return "ui_name_incite_city";
6535 case ACTION_SPY_INCITE_CITY_ESC:
6536 return "ui_name_incite_city_escape";
6537 case ACTION_ESTABLISH_EMBASSY:
6538 return "ui_name_establish_embassy";
6539 case ACTION_ESTABLISH_EMBASSY_STAY:
6540 return "ui_name_establish_embassy_stay";
6541 case ACTION_SPY_STEAL_TECH:
6542 return "ui_name_steal_tech";
6543 case ACTION_SPY_STEAL_TECH_ESC:
6544 return "ui_name_steal_tech_escape";
6545 case ACTION_SPY_TARGETED_STEAL_TECH:
6546 return "ui_name_targeted_steal_tech";
6547 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6548 return "ui_name_targeted_steal_tech_escape";
6549 case ACTION_SPY_INVESTIGATE_CITY:
6550 return "ui_name_investigate_city";
6551 case ACTION_INV_CITY_SPEND:
6552 return "ui_name_investigate_city_spend_unit";
6553 case ACTION_SPY_STEAL_GOLD:
6554 return "ui_name_steal_gold";
6555 case ACTION_SPY_STEAL_GOLD_ESC:
6556 return "ui_name_steal_gold_escape";
6557 case ACTION_SPY_SPREAD_PLAGUE:
6558 return "ui_name_spread_plague";
6559 case ACTION_STEAL_MAPS:
6560 return "ui_name_steal_maps";
6561 case ACTION_STEAL_MAPS_ESC:
6562 return "ui_name_steal_maps_escape";
6563 case ACTION_TRADE_ROUTE:
6564 return "ui_name_establish_trade_route";
6565 case ACTION_MARKETPLACE:
6566 return "ui_name_enter_marketplace";
6567 case ACTION_HELP_WONDER:
6568 return "ui_name_help_wonder";
6569 case ACTION_CAPTURE_UNITS:
6570 return "ui_name_capture_units";
6571 case ACTION_EXPEL_UNIT:
6572 return "ui_name_expel_unit";
6573 case ACTION_FOUND_CITY:
6574 return "ui_name_found_city";
6575 case ACTION_JOIN_CITY:
6576 return "ui_name_join_city";
6577 case ACTION_BOMBARD:
6578 return "ui_name_bombard";
6579 case ACTION_BOMBARD2:
6580 return "ui_name_bombard_2";
6581 case ACTION_BOMBARD3:
6582 return "ui_name_bombard_3";
6583 case ACTION_BOMBARD_LETHAL:
6584 return "ui_name_bombard_lethal";
6585 case ACTION_BOMBARD_LETHAL2:
6586 return "ui_name_bombard_lethal_2";
6587 case ACTION_SPY_NUKE:
6588 return "ui_name_suitcase_nuke";
6589 case ACTION_SPY_NUKE_ESC:
6590 return "ui_name_suitcase_nuke_escape";
6591 case ACTION_NUKE:
6592 return "ui_name_explode_nuclear";
6593 case ACTION_NUKE_CITY:
6594 return "ui_name_nuke_city";
6595 case ACTION_NUKE_UNITS:
6596 return "ui_name_nuke_units";
6597 case ACTION_DESTROY_CITY:
6598 return "ui_name_destroy_city";
6599 case ACTION_DISBAND_UNIT_RECOVER:
6600 return "ui_name_disband_unit_recover";
6601 case ACTION_DISBAND_UNIT:
6602 return "ui_name_disband_unit";
6603 case ACTION_HOME_CITY:
6604 return "ui_name_home_city";
6605 case ACTION_HOMELESS:
6606 return "ui_name_homeless";
6607 case ACTION_UPGRADE_UNIT:
6608 return "ui_name_upgrade_unit";
6609 case ACTION_PARADROP:
6610 return "ui_name_paradrop_unit";
6611 case ACTION_PARADROP_CONQUER:
6612 return "ui_name_paradrop_unit_conquer";
6613 case ACTION_PARADROP_FRIGHTEN:
6614 return "ui_name_paradrop_unit_frighten";
6615 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6616 return "ui_name_paradrop_unit_frighten_conquer";
6617 case ACTION_PARADROP_ENTER:
6618 return "ui_name_paradrop_unit_enter";
6619 case ACTION_PARADROP_ENTER_CONQUER:
6620 return "ui_name_paradrop_unit_enter_conquer";
6621 case ACTION_AIRLIFT:
6622 return "ui_name_airlift_unit";
6623 case ACTION_ATTACK:
6624 return "ui_name_attack";
6625 case ACTION_ATTACK2:
6626 return "ui_name_attack_2";
6627 case ACTION_SUICIDE_ATTACK:
6628 return "ui_name_suicide_attack";
6629 case ACTION_SUICIDE_ATTACK2:
6630 return "ui_name_suicide_attack_2";
6631 case ACTION_WIPE_UNITS:
6632 return "ui_name_wipe_units";
6633 case ACTION_COLLECT_RANSOM:
6634 return "ui_name_collect_ransom";
6635 case ACTION_STRIKE_BUILDING:
6636 return "ui_name_surgical_strike_building";
6637 case ACTION_STRIKE_PRODUCTION:
6638 return "ui_name_surgical_strike_production";
6639 case ACTION_CONQUER_CITY:
6640 return "ui_name_conquer_city";
6641 case ACTION_CONQUER_CITY2:
6642 return "ui_name_conquer_city_2";
6643 case ACTION_CONQUER_CITY3:
6644 return "ui_name_conquer_city_3";
6645 case ACTION_CONQUER_CITY4:
6646 return "ui_name_conquer_city_4";
6647 case ACTION_CONQUER_EXTRAS:
6648 return "ui_name_conquer_extras";
6649 case ACTION_CONQUER_EXTRAS2:
6650 return "ui_name_conquer_extras_2";
6651 case ACTION_CONQUER_EXTRAS3:
6652 return "ui_name_conquer_extras_3";
6653 case ACTION_CONQUER_EXTRAS4:
6654 return "ui_name_conquer_extras_4";
6655 case ACTION_HEAL_UNIT:
6656 return "ui_name_heal_unit";
6657 case ACTION_HEAL_UNIT2:
6658 return "ui_name_heal_unit_2";
6659 case ACTION_TRANSFORM_TERRAIN:
6660 return "ui_name_transform_terrain";
6661 case ACTION_CULTIVATE:
6662 return "ui_name_cultivate";
6663 case ACTION_PLANT:
6664 return "ui_name_plant";
6665 case ACTION_PILLAGE:
6666 return "ui_name_pillage";
6667 case ACTION_CLEAN:
6668 return "ui_name_clean";
6669 case ACTION_FORTIFY:
6670 return "ui_name_fortify";
6671 case ACTION_ROAD:
6672 return "ui_name_build_road";
6673 case ACTION_CONVERT:
6674 return "ui_name_convert_unit";
6675 case ACTION_BASE:
6676 return "ui_name_build_base";
6677 case ACTION_MINE:
6678 return "ui_name_build_mine";
6679 case ACTION_IRRIGATE:
6680 return "ui_name_irrigate";
6681 case ACTION_TRANSPORT_DEBOARD:
6682 return "ui_name_transport_deboard";
6683 case ACTION_TRANSPORT_BOARD:
6684 return "ui_name_transport_board";
6685 case ACTION_TRANSPORT_BOARD2:
6686 return "ui_name_transport_board_2";
6687 case ACTION_TRANSPORT_BOARD3:
6688 return "ui_name_transport_board_3";
6689 case ACTION_TRANSPORT_EMBARK:
6690 return "ui_name_transport_embark";
6691 case ACTION_TRANSPORT_EMBARK2:
6692 return "ui_name_transport_embark_2";
6693 case ACTION_TRANSPORT_EMBARK3:
6694 return "ui_name_transport_embark_3";
6695 case ACTION_TRANSPORT_EMBARK4:
6696 return "ui_name_transport_embark_4";
6697 case ACTION_TRANSPORT_UNLOAD:
6698 return "ui_name_transport_unload";
6699 case ACTION_TRANSPORT_LOAD:
6700 return "ui_name_transport_load";
6701 case ACTION_TRANSPORT_LOAD2:
6702 return "ui_name_transport_load_2";
6703 case ACTION_TRANSPORT_LOAD3:
6704 return "ui_name_transport_load_3";
6705 case ACTION_TRANSPORT_DISEMBARK1:
6706 return "ui_name_transport_disembark";
6707 case ACTION_TRANSPORT_DISEMBARK2:
6708 return "ui_name_transport_disembark_2";
6709 case ACTION_TRANSPORT_DISEMBARK3:
6710 return "ui_name_transport_disembark_3";
6711 case ACTION_TRANSPORT_DISEMBARK4:
6712 return "ui_name_transport_disembark_4";
6713 case ACTION_HUT_ENTER:
6714 return "ui_name_enter_hut";
6715 case ACTION_HUT_ENTER2:
6716 return "ui_name_enter_hut_2";
6717 case ACTION_HUT_ENTER3:
6718 return "ui_name_enter_hut_3";
6719 case ACTION_HUT_ENTER4:
6720 return "ui_name_enter_hut_4";
6721 case ACTION_HUT_FRIGHTEN:
6722 return "ui_name_frighten_hut";
6723 case ACTION_HUT_FRIGHTEN2:
6724 return "ui_name_frighten_hut_2";
6725 case ACTION_HUT_FRIGHTEN3:
6726 return "ui_name_frighten_hut_3";
6727 case ACTION_HUT_FRIGHTEN4:
6728 return "ui_name_frighten_hut_4";
6729 case ACTION_SPY_ATTACK:
6730 return "ui_name_spy_attack";
6731 case ACTION_UNIT_MOVE:
6732 return "ui_name_unit_move";
6733 case ACTION_UNIT_MOVE2:
6734 return "ui_name_unit_move_2";
6735 case ACTION_UNIT_MOVE3:
6736 return "ui_name_unit_move_3";
6737 case ACTION_TELEPORT:
6738 return "ui_name_teleport";
6739 case ACTION_TELEPORT_CONQUER:
6740 return "ui_name_teleport_conquer";
6741 case ACTION_TELEPORT_FRIGHTEN:
6742 return "ui_name_teleport_frighten";
6743 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6744 return "ui_name_teleport_frighten_conquer";
6745 case ACTION_TELEPORT_ENTER:
6746 return "ui_name_teleport_enter";
6747 case ACTION_TELEPORT_ENTER_CONQUER:
6748 return "ui_name_teleport_enter_conquer";
6749 case ACTION_SPY_ESCAPE:
6750 return "ui_name_escape";
6751 case ACTION_USER_ACTION1:
6752 return "ui_name_user_action_1";
6753 case ACTION_USER_ACTION2:
6754 return "ui_name_user_action_2";
6755 case ACTION_USER_ACTION3:
6756 return "ui_name_user_action_3";
6757 case ACTION_USER_ACTION4:
6758 return "ui_name_user_action_4";
6759 case ACTION_COUNT:
6760 break;
6761
6762 ASSERT_UNUSED_ACTION_CASES;
6763 }
6764
6765 fc_assert(act >= 0 && act < ACTION_COUNT);
6766
6767 return NULL;
6768}
6769
6770/**********************************************************************/
6773 const char *action_ui_name_default(int act)
6774{
6775 switch ((enum gen_action)act) {
6776 case ACTION_SPY_POISON:
6777 /* TRANS: _Poison City (3% chance of success). */
6778 return N_("%sPoison City%s");
6779 case ACTION_SPY_POISON_ESC:
6780 /* TRANS: _Poison City and Escape (3% chance of success). */
6781 return N_("%sPoison City and Escape%s");
6782 case ACTION_SPY_SABOTAGE_UNIT:
6783 /* TRANS: S_abotage Enemy Unit (3% chance of success). */
6784 return N_("S%sabotage Enemy Unit%s");
6785 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6786 /* TRANS: S_abotage Enemy Unit and Escape (3% chance of success). */
6787 return N_("S%sabotage Enemy Unit and Escape%s");
6788 case ACTION_SPY_BRIBE_UNIT:
6789 /* TRANS: Bribe Enemy _Unit (3% chance of success). */
6790 return N_("Bribe Enemy %sUnit%s");
6791 case ACTION_SPY_SABOTAGE_CITY:
6792 /* TRANS: _Sabotage City (3% chance of success). */
6793 return N_("%sSabotage City%s");
6794 case ACTION_SPY_SABOTAGE_CITY_ESC:
6795 /* TRANS: _Sabotage City and Escape (3% chance of success). */
6796 return N_("%sSabotage City and Escape%s");
6797 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6798 /* TRANS: Industria_l Sabotage (3% chance of success). */
6799 return N_("Industria%sl Sabotage%s");
6800 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6801 /* TRANS: Industria_l Sabotage Production (3% chance of success). */
6802 return N_("Industria%sl Sabotage Production%s");
6803 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6804 /* TRANS: Industria_l Sabotage and Escape (3% chance of success). */
6805 return N_("Industria%sl Sabotage and Escape%s");
6806 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6807 /* TRANS: Industria_l Sabotage Production and Escape (3% chance of success). */
6808 return N_("Industria%sl Sabotage Production and Escape%s");
6809 case ACTION_SPY_INCITE_CITY:
6810 /* TRANS: Incite a Re_volt (3% chance of success). */
6811 return N_("Incite a Re%svolt%s");
6812 case ACTION_SPY_INCITE_CITY_ESC:
6813 /* TRANS: Incite a Re_volt and Escape (3% chance of success). */
6814 return N_("Incite a Re%svolt and Escape%s");
6815 case ACTION_ESTABLISH_EMBASSY:
6816 /* TRANS: Establish _Embassy (100% chance of success). */
6817 return N_("Establish %sEmbassy%s");
6818 case ACTION_ESTABLISH_EMBASSY_STAY:
6819 /* TRANS: Becom_e Ambassador (100% chance of success). */
6820 return N_("Becom%se Ambassador%s");
6821 case ACTION_SPY_STEAL_TECH:
6822 /* TRANS: Steal _Technology (3% chance of success). */
6823 return N_("Steal %sTechnology%s");
6824 case ACTION_SPY_STEAL_TECH_ESC:
6825 /* TRANS: Steal _Technology and Escape (3% chance of success). */
6826 return N_("Steal %sTechnology and Escape%s");
6827 case ACTION_SPY_TARGETED_STEAL_TECH:
6828 /* TRANS: In_dustrial Espionage (3% chance of success). */
6829 return N_("In%sdustrial Espionage%s");
6830 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6831 /* TRANS: In_dustrial Espionage and Escape (3% chance of success). */
6832 return N_("In%sdustrial Espionage and Escape%s");
6833 case ACTION_SPY_INVESTIGATE_CITY:
6834 /* TRANS: _Investigate City (100% chance of success). */
6835 return N_("%sInvestigate City%s");
6836 case ACTION_INV_CITY_SPEND:
6837 /* TRANS: _Investigate City (spends the unit) (100% chance of
6838 * success). */
6839 return N_("%sInvestigate City (spends the unit)%s");
6840 case ACTION_SPY_STEAL_GOLD:
6841 /* TRANS: Steal _Gold (100% chance of success). */
6842 return N_("Steal %sGold%s");
6843 case ACTION_SPY_STEAL_GOLD_ESC:
6844 /* TRANS: Steal _Gold and Escape (100% chance of success). */
6845 return N_("Steal %sGold and Escape%s");
6846 case ACTION_SPY_SPREAD_PLAGUE:
6847 /* TRANS: Spread _Plague (100% chance of success). */
6848 return N_("Spread %sPlague%s");
6849 case ACTION_STEAL_MAPS:
6850 /* TRANS: Steal _Maps (100% chance of success). */
6851 return N_("Steal %sMaps%s");
6852 case ACTION_STEAL_MAPS_ESC:
6853 /* TRANS: Steal _Maps and Escape (100% chance of success). */
6854 return N_("Steal %sMaps and Escape%s");
6855 case ACTION_TRADE_ROUTE:
6856 /* TRANS: Establish Trade _Route (100% chance of success). */
6857 return N_("Establish Trade %sRoute%s");
6858 case ACTION_MARKETPLACE:
6859 /* TRANS: Enter _Marketplace (100% chance of success). */
6860 return N_("Enter %sMarketplace%s");
6861 case ACTION_HELP_WONDER:
6862 /* TRANS: Help _build Wonder (100% chance of success). */
6863 return N_("Help %sbuild Wonder%s");
6864 case ACTION_CAPTURE_UNITS:
6865 /* TRANS: _Capture Units (100% chance of success). */
6866 return N_("%sCapture Units%s");
6867 case ACTION_EXPEL_UNIT:
6868 /* TRANS: _Expel Unit (100% chance of success). */
6869 return N_("%sExpel Unit%s");
6870 case ACTION_FOUND_CITY:
6871 /* TRANS: _Found City (100% chance of success). */
6872 return N_("%sFound City%s");
6873 case ACTION_JOIN_CITY:
6874 /* TRANS: _Join City (100% chance of success). */
6875 return N_("%sJoin City%s");
6876 case ACTION_BOMBARD:
6877 /* TRANS: B_ombard (100% chance of success). */
6878 return N_("B%sombard%s");
6879 case ACTION_BOMBARD2:
6880 /* TRANS: B_ombard 2 (100% chance of success). */
6881 return N_("B%sombard 2%s");
6882 case ACTION_BOMBARD3:
6883 /* TRANS: B_ombard 3 (100% chance of success). */
6884 return N_("B%sombard 3%s");
6885 case ACTION_BOMBARD_LETHAL:
6886 case ACTION_BOMBARD_LETHAL2:
6887 /* TRANS: Lethal B_ombard (100% chance of success). */
6888 return N_("Lethal B%sombard%s");
6889 case ACTION_SPY_NUKE:
6890 /* TRANS: Suitcase _Nuke (100% chance of success). */
6891 return N_("Suitcase %sNuke%s");
6892 case ACTION_SPY_NUKE_ESC:
6893 /* TRANS: Suitcase _Nuke and Escape (100% chance of success). */
6894 return N_("Suitcase %sNuke and Escape%s");
6895 case ACTION_NUKE:
6896 /* TRANS: Explode _Nuclear (100% chance of success). */
6897 return N_("Explode %sNuclear%s");
6898 case ACTION_NUKE_CITY:
6899 /* TRANS: _Nuke City (100% chance of success). */
6900 return N_("%sNuke City%s");
6901 case ACTION_NUKE_UNITS:
6902 /* TRANS: _Nuke Units (100% chance of success). */
6903 return N_("%sNuke Units%s");
6904 case ACTION_DESTROY_CITY:
6905 /* TRANS: Destroy _City (100% chance of success). */
6906 return N_("Destroy %sCity%s");
6907 case ACTION_DISBAND_UNIT_RECOVER:
6908 /* TRANS: Dis_band recovering production (100% chance of success). */
6909 return N_("Dis%sband recovering production%s");
6910 case ACTION_DISBAND_UNIT:
6911 /* TRANS: Dis_band without recovering production (100% chance of success). */
6912 return N_("Dis%sband without recovering production%s");
6913 case ACTION_HOME_CITY:
6914 /* TRANS: Set _Home City (100% chance of success). */
6915 return N_("Set %sHome City%s");
6916 case ACTION_HOMELESS:
6917 /* TRANS: Make _Homeless (100% chance of success). */
6918 return N_("Make %sHomeless%s");
6919 case ACTION_UPGRADE_UNIT:
6920 /* TRANS: _Upgrade Unit (100% chance of success). */
6921 return N_("%sUpgrade Unit%s");
6922 case ACTION_PARADROP:
6923 /* TRANS: Drop _Paratrooper (100% chance of success). */
6924 return N_("Drop %sParatrooper%s");
6925 case ACTION_PARADROP_CONQUER:
6926 /* TRANS: Drop _Paratrooper (100% chance of success). */
6927 return N_("Drop %sParatrooper%s");
6928 case ACTION_PARADROP_FRIGHTEN:
6929 /* TRANS: Drop _Paratrooper (100% chance of success). */
6930 return N_("Drop %sParatrooper%s");
6931 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6932 /* TRANS: Drop _Paratrooper (100% chance of success). */
6933 return N_("Drop %sParatrooper%s");
6934 case ACTION_PARADROP_ENTER:
6935 /* TRANS: Drop _Paratrooper (100% chance of success). */
6936 return N_("Drop %sParatrooper%s");
6937 case ACTION_PARADROP_ENTER_CONQUER:
6938 /* TRANS: Drop _Paratrooper (100% chance of success). */
6939 return N_("Drop %sParatrooper%s");
6940 case ACTION_AIRLIFT:
6941 /* TRANS: _Airlift to City (100% chance of success). */
6942 return N_("%sAirlift to City%s");
6943 case ACTION_ATTACK:
6944 case ACTION_ATTACK2:
6945 /* TRANS: _Attack (100% chance of success). */
6946 return N_("%sAttack%s");
6947 case ACTION_SUICIDE_ATTACK:
6948 case ACTION_SUICIDE_ATTACK2:
6949 /* TRANS: _Suicide Attack (100% chance of success). */
6950 return N_("%sSuicide Attack%s");
6951 case ACTION_WIPE_UNITS:
6952 /* TRANS: _Wipe Units (100% chance of success). */
6953 return N_("%sWipe Units%s");
6954 case ACTION_COLLECT_RANSOM:
6955 /* TRANS: Collect _Ransom (100% chance of success). */
6956 return N_("Collect %sRansom%s");
6957 case ACTION_STRIKE_BUILDING:
6958 /* TRANS: Surgical Str_ike Building (100% chance of success). */
6959 return N_("Surgical Str%sike Building%s");
6960 case ACTION_STRIKE_PRODUCTION:
6961 /* TRANS: Surgical Str_ike Production (100% chance of success). */
6962 return N_("Surgical Str%sike Production%s");
6963 case ACTION_CONQUER_CITY:
6964 case ACTION_CONQUER_CITY3:
6965 case ACTION_CONQUER_CITY4:
6966 /* TRANS: _Conquer City (100% chance of success). */
6967 return N_("%sConquer City%s");
6968 case ACTION_CONQUER_CITY2:
6969 /* TRANS: _Conquer City 2 (100% chance of success). */
6970 return N_("%sConquer City 2%s");
6971 case ACTION_CONQUER_EXTRAS:
6972 case ACTION_CONQUER_EXTRAS3:
6973 case ACTION_CONQUER_EXTRAS4:
6974 /* TRANS: _Conquer Extras (100% chance of success). */
6975 return N_("%sConquer Extras%s");
6976 case ACTION_CONQUER_EXTRAS2:
6977 /* TRANS: _Conquer Extras 2 (100% chance of success). */
6978 return N_("%sConquer Extras 2%s");
6979 case ACTION_HEAL_UNIT:
6980 case ACTION_HEAL_UNIT2:
6981 /* TRANS: Heal _Unit (3% chance of success). */
6982 return N_("Heal %sUnit%s");
6983 case ACTION_TRANSFORM_TERRAIN:
6984 /* TRANS: _Transform Terrain (3% chance of success). */
6985 return N_("%sTransform Terrain%s");
6986 case ACTION_CULTIVATE:
6987 /* TRANS: Transform by _Cultivating (3% chance of success). */
6988 return N_("Transform by %sCultivating%s");
6989 case ACTION_PLANT:
6990 /* TRANS: Transform by _Planting (3% chance of success). */
6991 return N_("Transform by %sPlanting%s");
6992 case ACTION_PILLAGE:
6993 /* TRANS: Pilla_ge (100% chance of success). */
6994 return N_("Pilla%sge%s");
6995 case ACTION_CLEAN:
6996 /* TRANS: Clean (100% chance of success). */
6997 return N_("%sClean%s");
6998 case ACTION_FORTIFY:
6999 /* TRANS: _Fortify (100% chance of success). */
7000 return N_("%sFortify%s");
7001 case ACTION_ROAD:
7002 /* TRANS: Build _Road (100% chance of success). */
7003 return N_("Build %sRoad%s");
7004 case ACTION_CONVERT:
7005 /* TRANS: _Convert Unit (100% chance of success). */
7006 return N_("%sConvert Unit%s");
7007 case ACTION_BASE:
7008 /* TRANS: _Build Base (100% chance of success). */
7009 return N_("%sBuild Base%s");
7010 case ACTION_MINE:
7011 /* TRANS: Build _Mine (100% chance of success). */
7012 return N_("Build %sMine%s");
7013 case ACTION_IRRIGATE:
7014 /* TRANS: Build _Irrigation (100% chance of success). */
7015 return N_("Build %sIrrigation%s");
7016 case ACTION_TRANSPORT_DEBOARD:
7017 /* TRANS: _Deboard (100% chance of success). */
7018 return N_("%sDeboard%s");
7019 case ACTION_TRANSPORT_BOARD:
7020 case ACTION_TRANSPORT_BOARD2:
7021 case ACTION_TRANSPORT_BOARD3:
7022 /* TRANS: _Board (100% chance of success). */
7023 return N_("%sBoard%s");
7024 case ACTION_TRANSPORT_EMBARK:
7025 case ACTION_TRANSPORT_EMBARK2:
7026 case ACTION_TRANSPORT_EMBARK3:
7027 case ACTION_TRANSPORT_EMBARK4:
7028 /* TRANS: _Embark (100% chance of success). */
7029 return N_("%sEmbark%s");
7030 case ACTION_TRANSPORT_UNLOAD:
7031 /* TRANS: _Unload (100% chance of success). */
7032 return N_("%sUnload%s");
7033 case ACTION_TRANSPORT_LOAD:
7034 case ACTION_TRANSPORT_LOAD2:
7035 case ACTION_TRANSPORT_LOAD3:
7036 /* TRANS: _Load (100% chance of success). */
7037 return N_("%sLoad%s");
7038 case ACTION_TRANSPORT_DISEMBARK1:
7039 case ACTION_TRANSPORT_DISEMBARK3:
7040 case ACTION_TRANSPORT_DISEMBARK4:
7041 /* TRANS: _Disembark (100% chance of success). */
7042 return N_("%sDisembark%s");
7043 case ACTION_TRANSPORT_DISEMBARK2:
7044 /* TRANS: _Disembark 2 (100% chance of success). */
7045 return N_("%sDisembark 2%s");
7046 case ACTION_SPY_ATTACK:
7047 /* TRANS: _Eliminate Diplomat (100% chance of success). */
7048 return N_("%sEliminate Diplomat%s");
7049 case ACTION_HUT_ENTER:
7050 case ACTION_HUT_ENTER2:
7051 case ACTION_HUT_ENTER3:
7052 case ACTION_HUT_ENTER4:
7053 /* TRANS: Enter _Hut (100% chance of success). */
7054 return N_("Enter %sHut%s");
7055 case ACTION_HUT_FRIGHTEN:
7056 case ACTION_HUT_FRIGHTEN2:
7057 case ACTION_HUT_FRIGHTEN3:
7058 case ACTION_HUT_FRIGHTEN4:
7059 /* TRANS: Frighten _Hut (100% chance of success). */
7060 return N_("Frighten %sHut%s");
7061 case ACTION_UNIT_MOVE:
7062 case ACTION_UNIT_MOVE2:
7063 case ACTION_UNIT_MOVE3:
7064 /* TRANS: Regular _Move (100% chance of success). */
7065 return N_("Regular %sMove%s");
7066 case ACTION_TELEPORT:
7067 /* TRANS: _Teleport (100% chance of success). */
7068 return N_("%sTeleport%s");
7069 case ACTION_TELEPORT_CONQUER:
7070 /* TRANS: _Teleport (100% chance of success). */
7071 return N_("%sTeleport%s");
7072 case ACTION_TELEPORT_FRIGHTEN:
7073 /* TRANS: _Teleport (100% chance of success). */
7074 return N_("%sTeleport%s");
7075 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7076 /* TRANS: _Teleport (100% chance of success). */
7077 return N_("%sTeleport%s");
7078 case ACTION_TELEPORT_ENTER:
7079 /* TRANS: _Teleport (100% chance of success). */
7080 return N_("%sTeleport%s");
7081 case ACTION_TELEPORT_ENTER_CONQUER:
7082 /* TRANS: _Teleport (100% chance of success). */
7083 return N_("%sTeleport%s");
7084 case ACTION_SPY_ESCAPE:
7085 /* TRANS: _Escape To Nearest City (100% chance of success). */
7086 return N_("%sEscape To Nearest City%s");
7087 case ACTION_USER_ACTION1:
7088 /* TRANS: _User Action 1 (100% chance of success). */
7089 return N_("%sUser Action 1%s");
7090 case ACTION_USER_ACTION2:
7091 /* TRANS: _User Action 2 (100% chance of success). */
7092 return N_("%sUser Action 2%s");
7093 case ACTION_USER_ACTION3:
7094 /* TRANS: _User Action 3 (100% chance of success). */
7095 return N_("%sUser Action 3%s");
7096 case ACTION_USER_ACTION4:
7097 /* TRANS: _User Action 4 (100% chance of success). */
7098 return N_("%sUser Action 4%s");
7099 case ACTION_COUNT:
7100 fc_assert(act != ACTION_COUNT);
7101 break;
7102 }
7103
7104 return NULL;
7105}
7106
7107/**********************************************************************/
7113 const char *action_min_range_ruleset_var_name(int act)
7114{
7115 switch ((enum gen_action)act) {
7116 case ACTION_SPY_POISON:
7117 case ACTION_SPY_POISON_ESC:
7118 case ACTION_SPY_SABOTAGE_UNIT:
7119 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7120 case ACTION_SPY_BRIBE_UNIT:
7121 case ACTION_SPY_SABOTAGE_CITY:
7122 case ACTION_SPY_SABOTAGE_CITY_ESC:
7123 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7124 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7125 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7126 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7127 case ACTION_SPY_INCITE_CITY:
7128 case ACTION_SPY_INCITE_CITY_ESC:
7129 case ACTION_ESTABLISH_EMBASSY:
7130 case ACTION_ESTABLISH_EMBASSY_STAY:
7131 case ACTION_SPY_STEAL_TECH:
7132 case ACTION_SPY_STEAL_TECH_ESC:
7133 case ACTION_SPY_TARGETED_STEAL_TECH:
7134 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7135 case ACTION_SPY_INVESTIGATE_CITY:
7136 case ACTION_INV_CITY_SPEND:
7137 case ACTION_SPY_STEAL_GOLD:
7138 case ACTION_SPY_STEAL_GOLD_ESC:
7139 case ACTION_SPY_SPREAD_PLAGUE:
7140 case ACTION_STEAL_MAPS:
7141 case ACTION_STEAL_MAPS_ESC:
7142 case ACTION_TRADE_ROUTE:
7143 case ACTION_MARKETPLACE:
7144 case ACTION_HELP_WONDER:
7145 case ACTION_CAPTURE_UNITS:
7146 case ACTION_EXPEL_UNIT:
7147 case ACTION_FOUND_CITY:
7148 case ACTION_JOIN_CITY:
7149 case ACTION_SPY_NUKE:
7150 case ACTION_SPY_NUKE_ESC:
7151 case ACTION_DESTROY_CITY:
7152 case ACTION_DISBAND_UNIT_RECOVER:
7153 case ACTION_DISBAND_UNIT:
7154 case ACTION_HOME_CITY:
7155 case ACTION_HOMELESS:
7156 case ACTION_UPGRADE_UNIT:
7157 case ACTION_PARADROP:
7158 case ACTION_PARADROP_CONQUER:
7159 case ACTION_PARADROP_FRIGHTEN:
7160 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7161 case ACTION_PARADROP_ENTER:
7162 case ACTION_PARADROP_ENTER_CONQUER:
7163 case ACTION_AIRLIFT:
7164 case ACTION_ATTACK:
7165 case ACTION_ATTACK2:
7166 case ACTION_SUICIDE_ATTACK:
7167 case ACTION_SUICIDE_ATTACK2:
7168 case ACTION_WIPE_UNITS:
7169 case ACTION_COLLECT_RANSOM:
7170 case ACTION_STRIKE_BUILDING:
7171 case ACTION_STRIKE_PRODUCTION:
7172 case ACTION_CONQUER_CITY:
7173 case ACTION_CONQUER_CITY2:
7174 case ACTION_CONQUER_CITY3:
7175 case ACTION_CONQUER_CITY4:
7176 case ACTION_HEAL_UNIT:
7177 case ACTION_HEAL_UNIT2:
7178 case ACTION_TRANSFORM_TERRAIN:
7179 case ACTION_CULTIVATE:
7180 case ACTION_PLANT:
7181 case ACTION_PILLAGE:
7182 case ACTION_CLEAN:
7183 case ACTION_FORTIFY:
7184 case ACTION_ROAD:
7185 case ACTION_CONVERT:
7186 case ACTION_BASE:
7187 case ACTION_MINE:
7188 case ACTION_IRRIGATE:
7189 case ACTION_TRANSPORT_DEBOARD:
7190 case ACTION_TRANSPORT_BOARD:
7191 case ACTION_TRANSPORT_BOARD2:
7192 case ACTION_TRANSPORT_BOARD3:
7193 case ACTION_TRANSPORT_EMBARK:
7194 case ACTION_TRANSPORT_EMBARK2:
7195 case ACTION_TRANSPORT_EMBARK3:
7196 case ACTION_TRANSPORT_EMBARK4:
7197 case ACTION_TRANSPORT_UNLOAD:
7198 case ACTION_TRANSPORT_LOAD:
7199 case ACTION_TRANSPORT_LOAD2:
7200 case ACTION_TRANSPORT_LOAD3:
7201 case ACTION_TRANSPORT_DISEMBARK1:
7202 case ACTION_TRANSPORT_DISEMBARK2:
7203 case ACTION_TRANSPORT_DISEMBARK3:
7204 case ACTION_TRANSPORT_DISEMBARK4:
7205 case ACTION_BOMBARD:
7206 case ACTION_BOMBARD2:
7207 case ACTION_BOMBARD3:
7208 case ACTION_BOMBARD_LETHAL:
7209 case ACTION_BOMBARD_LETHAL2:
7210 case ACTION_SPY_ATTACK:
7211 case ACTION_CONQUER_EXTRAS:
7212 case ACTION_CONQUER_EXTRAS2:
7213 case ACTION_CONQUER_EXTRAS3:
7214 case ACTION_CONQUER_EXTRAS4:
7215 case ACTION_HUT_ENTER:
7216 case ACTION_HUT_ENTER2:
7217 case ACTION_HUT_ENTER3:
7218 case ACTION_HUT_ENTER4:
7219 case ACTION_HUT_FRIGHTEN:
7220 case ACTION_HUT_FRIGHTEN2:
7221 case ACTION_HUT_FRIGHTEN4:
7222 case ACTION_HUT_FRIGHTEN3:
7223 case ACTION_UNIT_MOVE:
7224 case ACTION_UNIT_MOVE2:
7225 case ACTION_UNIT_MOVE3:
7226 case ACTION_SPY_ESCAPE:
7227 /* Min range is not ruleset changeable */
7228 return NULL;
7229 case ACTION_NUKE:
7230 return "explode_nuclear_min_range";
7231 case ACTION_NUKE_CITY:
7232 return "nuke_city_min_range";
7233 case ACTION_NUKE_UNITS:
7234 return "nuke_units_min_range";
7235 case ACTION_TELEPORT:
7236 return "teleport_min_range";
7237 case ACTION_TELEPORT_CONQUER:
7238 return "teleport_conquer_min_range";
7239 case ACTION_TELEPORT_FRIGHTEN:
7240 return "teleport_frighten_min_range";
7241 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7242 return "teleport_frighten_conquer_min_range";
7243 case ACTION_TELEPORT_ENTER:
7244 return "teleport_enter_min_range";
7245 case ACTION_TELEPORT_ENTER_CONQUER:
7246 return "teleport_enter_conquer_min_range";
7247 case ACTION_USER_ACTION1:
7248 return "user_action_1_min_range";
7249 case ACTION_USER_ACTION2:
7250 return "user_action_2_min_range";
7251 case ACTION_USER_ACTION3:
7252 return "user_action_3_min_range";
7253 case ACTION_USER_ACTION4:
7254 return "user_action_4_min_range";
7255 case ACTION_COUNT:
7256 break;
7257
7258 ASSERT_UNUSED_ACTION_CASES;
7259 }
7260
7261 fc_assert(act >= 0 && act < ACTION_COUNT);
7262
7263 return NULL;
7264}
7265
7266/**********************************************************************/
7272 const char *action_max_range_ruleset_var_name(int act)
7273{
7274 switch ((enum gen_action)act) {
7275 case ACTION_SPY_POISON:
7276 case ACTION_SPY_POISON_ESC:
7277 case ACTION_SPY_SABOTAGE_UNIT:
7278 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7279 case ACTION_SPY_BRIBE_UNIT:
7280 case ACTION_SPY_SABOTAGE_CITY:
7281 case ACTION_SPY_SABOTAGE_CITY_ESC:
7282 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7283 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7284 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7285 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7286 case ACTION_SPY_INCITE_CITY:
7287 case ACTION_SPY_INCITE_CITY_ESC:
7288 case ACTION_ESTABLISH_EMBASSY:
7289 case ACTION_ESTABLISH_EMBASSY_STAY:
7290 case ACTION_SPY_STEAL_TECH:
7291 case ACTION_SPY_STEAL_TECH_ESC:
7292 case ACTION_SPY_TARGETED_STEAL_TECH:
7293 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7294 case ACTION_SPY_INVESTIGATE_CITY:
7295 case ACTION_INV_CITY_SPEND:
7296 case ACTION_SPY_STEAL_GOLD:
7297 case ACTION_SPY_STEAL_GOLD_ESC:
7298 case ACTION_SPY_SPREAD_PLAGUE:
7299 case ACTION_STEAL_MAPS:
7300 case ACTION_STEAL_MAPS_ESC:
7301 case ACTION_TRADE_ROUTE:
7302 case ACTION_MARKETPLACE:
7303 case ACTION_CAPTURE_UNITS:
7304 case ACTION_EXPEL_UNIT:
7305 case ACTION_FOUND_CITY:
7306 case ACTION_JOIN_CITY:
7307 case ACTION_SPY_NUKE:
7308 case ACTION_SPY_NUKE_ESC:
7309 case ACTION_DESTROY_CITY:
7310 case ACTION_DISBAND_UNIT:
7311 case ACTION_HOME_CITY:
7312 case ACTION_HOMELESS:
7313 case ACTION_UPGRADE_UNIT:
7314 case ACTION_PARADROP:
7315 case ACTION_PARADROP_CONQUER:
7316 case ACTION_PARADROP_FRIGHTEN:
7317 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7318 case ACTION_PARADROP_ENTER:
7319 case ACTION_PARADROP_ENTER_CONQUER:
7320 case ACTION_ATTACK:
7321 case ACTION_ATTACK2:
7322 case ACTION_SUICIDE_ATTACK:
7323 case ACTION_SUICIDE_ATTACK2:
7324 case ACTION_WIPE_UNITS:
7325 case ACTION_COLLECT_RANSOM:
7326 case ACTION_STRIKE_BUILDING:
7327 case ACTION_STRIKE_PRODUCTION:
7328 case ACTION_CONQUER_CITY:
7329 case ACTION_CONQUER_CITY2:
7330 case ACTION_CONQUER_CITY3:
7331 case ACTION_CONQUER_CITY4:
7332 case ACTION_HEAL_UNIT:
7333 case ACTION_HEAL_UNIT2:
7334 case ACTION_TRANSFORM_TERRAIN:
7335 case ACTION_CULTIVATE:
7336 case ACTION_PLANT:
7337 case ACTION_PILLAGE:
7338 case ACTION_CLEAN:
7339 case ACTION_FORTIFY:
7340 case ACTION_ROAD:
7341 case ACTION_CONVERT:
7342 case ACTION_BASE:
7343 case ACTION_MINE:
7344 case ACTION_IRRIGATE:
7345 case ACTION_TRANSPORT_DEBOARD:
7346 case ACTION_TRANSPORT_BOARD:
7347 case ACTION_TRANSPORT_BOARD2:
7348 case ACTION_TRANSPORT_BOARD3:
7349 case ACTION_TRANSPORT_EMBARK:
7350 case ACTION_TRANSPORT_EMBARK2:
7351 case ACTION_TRANSPORT_EMBARK3:
7352 case ACTION_TRANSPORT_EMBARK4:
7353 case ACTION_TRANSPORT_UNLOAD:
7354 case ACTION_TRANSPORT_LOAD:
7355 case ACTION_TRANSPORT_LOAD2:
7356 case ACTION_TRANSPORT_LOAD3:
7357 case ACTION_TRANSPORT_DISEMBARK1:
7358 case ACTION_TRANSPORT_DISEMBARK2:
7359 case ACTION_TRANSPORT_DISEMBARK3:
7360 case ACTION_TRANSPORT_DISEMBARK4:
7361 case ACTION_SPY_ATTACK:
7362 case ACTION_CONQUER_EXTRAS:
7363 case ACTION_CONQUER_EXTRAS2:
7364 case ACTION_CONQUER_EXTRAS3:
7365 case ACTION_CONQUER_EXTRAS4:
7366 case ACTION_HUT_ENTER:
7367 case ACTION_HUT_ENTER2:
7368 case ACTION_HUT_ENTER3:
7369 case ACTION_HUT_ENTER4:
7370 case ACTION_HUT_FRIGHTEN:
7371 case ACTION_HUT_FRIGHTEN2:
7372 case ACTION_HUT_FRIGHTEN3:
7373 case ACTION_HUT_FRIGHTEN4:
7374 case ACTION_UNIT_MOVE:
7375 case ACTION_UNIT_MOVE2:
7376 case ACTION_UNIT_MOVE3:
7377 case ACTION_SPY_ESCAPE:
7378 /* Max range is not ruleset changeable */
7379 return NULL;
7380 case ACTION_HELP_WONDER:
7381 return "help_wonder_max_range";
7382 case ACTION_DISBAND_UNIT_RECOVER:
7383 return "disband_unit_recover_max_range";
7384 case ACTION_BOMBARD:
7385 return "bombard_max_range";
7386 case ACTION_BOMBARD2:
7387 return "bombard_2_max_range";
7388 case ACTION_BOMBARD3:
7389 return "bombard_3_max_range";
7390 case ACTION_BOMBARD_LETHAL:
7391 return "bombard_lethal_max_range";
7392 case ACTION_BOMBARD_LETHAL2:
7393 return "bombard_lethal_2_max_range";
7394 case ACTION_NUKE:
7395 return "explode_nuclear_max_range";
7396 case ACTION_NUKE_CITY:
7397 return "nuke_city_max_range";
7398 case ACTION_NUKE_UNITS:
7399 return "nuke_units_max_range";
7400 case ACTION_AIRLIFT:
7401 return "airlift_max_range";
7402 case ACTION_TELEPORT:
7403 return "teleport_max_range";
7404 case ACTION_TELEPORT_CONQUER:
7405 return "teleport_conquer_max_range";
7406 case ACTION_TELEPORT_FRIGHTEN:
7407 return "teleport_frighten_max_range";
7408 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7409 return "teleport_frighten_conquer_max_range";
7410 case ACTION_TELEPORT_ENTER:
7411 return "teleport_enter_max_range";
7412 case ACTION_TELEPORT_ENTER_CONQUER:
7413 return "teleport_enter_conquer_max_range";
7414 case ACTION_USER_ACTION1:
7415 return "user_action_1_max_range";
7416 case ACTION_USER_ACTION2:
7417 return "user_action_2_max_range";
7418 case ACTION_USER_ACTION3:
7419 return "user_action_3_max_range";
7420 case ACTION_USER_ACTION4:
7421 return "user_action_4_max_range";
7422 case ACTION_COUNT:
7423 break;
7424
7425 ASSERT_UNUSED_ACTION_CASES;
7426 }
7427
7428 fc_assert(act >= 0 && act < ACTION_COUNT);
7429
7430 return NULL;
7431}
7432
7433/**********************************************************************/
7439 const char *action_target_kind_ruleset_var_name(int act)
7440{
7441 switch ((enum gen_action)act) {
7442 case ACTION_SPY_POISON:
7443 case ACTION_SPY_POISON_ESC:
7444 case ACTION_SPY_SABOTAGE_UNIT:
7445 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7446 case ACTION_SPY_BRIBE_UNIT:
7447 case ACTION_SPY_SABOTAGE_CITY:
7448 case ACTION_SPY_SABOTAGE_CITY_ESC:
7449 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7450 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7451 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7452 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7453 case ACTION_SPY_INCITE_CITY:
7454 case ACTION_SPY_INCITE_CITY_ESC:
7455 case ACTION_ESTABLISH_EMBASSY:
7456 case ACTION_ESTABLISH_EMBASSY_STAY:
7457 case ACTION_SPY_STEAL_TECH:
7458 case ACTION_SPY_STEAL_TECH_ESC:
7459 case ACTION_SPY_TARGETED_STEAL_TECH:
7460 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7461 case ACTION_SPY_INVESTIGATE_CITY:
7462 case ACTION_INV_CITY_SPEND:
7463 case ACTION_SPY_STEAL_GOLD:
7464 case ACTION_SPY_STEAL_GOLD_ESC:
7465 case ACTION_SPY_SPREAD_PLAGUE:
7466 case ACTION_STEAL_MAPS:
7467 case ACTION_STEAL_MAPS_ESC:
7468 case ACTION_TRADE_ROUTE:
7469 case ACTION_MARKETPLACE:
7470 case ACTION_HELP_WONDER:
7471 case ACTION_CAPTURE_UNITS:
7472 case ACTION_EXPEL_UNIT:
7473 case ACTION_FOUND_CITY:
7474 case ACTION_JOIN_CITY:
7475 case ACTION_SPY_NUKE:
7476 case ACTION_SPY_NUKE_ESC:
7477 case ACTION_NUKE_UNITS:
7478 case ACTION_DESTROY_CITY:
7479 case ACTION_DISBAND_UNIT_RECOVER:
7480 case ACTION_DISBAND_UNIT:
7481 case ACTION_HOME_CITY:
7482 case ACTION_HOMELESS:
7483 case ACTION_UPGRADE_UNIT:
7484 case ACTION_PARADROP:
7485 case ACTION_PARADROP_CONQUER:
7486 case ACTION_PARADROP_FRIGHTEN:
7487 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7488 case ACTION_PARADROP_ENTER:
7489 case ACTION_PARADROP_ENTER_CONQUER:
7490 case ACTION_AIRLIFT:
7491 case ACTION_ATTACK:
7492 case ACTION_ATTACK2:
7493 case ACTION_SUICIDE_ATTACK:
7494 case ACTION_SUICIDE_ATTACK2:
7495 case ACTION_WIPE_UNITS:
7496 case ACTION_COLLECT_RANSOM:
7497 case ACTION_STRIKE_BUILDING:
7498 case ACTION_STRIKE_PRODUCTION:
7499 case ACTION_CONQUER_CITY:
7500 case ACTION_CONQUER_CITY2:
7501 case ACTION_CONQUER_CITY3:
7502 case ACTION_CONQUER_CITY4:
7503 case ACTION_HEAL_UNIT:
7504 case ACTION_HEAL_UNIT2:
7505 case ACTION_TRANSFORM_TERRAIN:
7506 case ACTION_CULTIVATE:
7507 case ACTION_PLANT:
7508 case ACTION_CLEAN:
7509 case ACTION_FORTIFY:
7510 case ACTION_ROAD:
7511 case ACTION_CONVERT:
7512 case ACTION_BASE:
7513 case ACTION_MINE:
7514 case ACTION_IRRIGATE:
7515 case ACTION_TRANSPORT_DEBOARD:
7516 case ACTION_TRANSPORT_BOARD:
7517 case ACTION_TRANSPORT_BOARD2:
7518 case ACTION_TRANSPORT_BOARD3:
7519 case ACTION_TRANSPORT_EMBARK:
7520 case ACTION_TRANSPORT_EMBARK2:
7521 case ACTION_TRANSPORT_EMBARK3:
7522 case ACTION_TRANSPORT_EMBARK4:
7523 case ACTION_TRANSPORT_UNLOAD:
7524 case ACTION_TRANSPORT_LOAD:
7525 case ACTION_TRANSPORT_LOAD2:
7526 case ACTION_TRANSPORT_LOAD3:
7527 case ACTION_TRANSPORT_DISEMBARK1:
7528 case ACTION_TRANSPORT_DISEMBARK2:
7529 case ACTION_TRANSPORT_DISEMBARK3:
7530 case ACTION_TRANSPORT_DISEMBARK4:
7531 case ACTION_BOMBARD:
7532 case ACTION_BOMBARD2:
7533 case ACTION_BOMBARD3:
7534 case ACTION_BOMBARD_LETHAL:
7535 case ACTION_BOMBARD_LETHAL2:
7536 case ACTION_SPY_ATTACK:
7537 case ACTION_CONQUER_EXTRAS:
7538 case ACTION_CONQUER_EXTRAS2:
7539 case ACTION_CONQUER_EXTRAS3:
7540 case ACTION_CONQUER_EXTRAS4:
7541 case ACTION_HUT_ENTER:
7542 case ACTION_HUT_ENTER2:
7543 case ACTION_HUT_ENTER3:
7544 case ACTION_HUT_ENTER4:
7545 case ACTION_HUT_FRIGHTEN:
7546 case ACTION_HUT_FRIGHTEN2:
7547 case ACTION_HUT_FRIGHTEN3:
7548 case ACTION_HUT_FRIGHTEN4:
7549 case ACTION_UNIT_MOVE:
7550 case ACTION_UNIT_MOVE2:
7551 case ACTION_UNIT_MOVE3:
7552 case ACTION_TELEPORT:
7553 case ACTION_TELEPORT_CONQUER:
7554 case ACTION_TELEPORT_FRIGHTEN:
7555 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7556 case ACTION_TELEPORT_ENTER:
7557 case ACTION_TELEPORT_ENTER_CONQUER:
7558 case ACTION_SPY_ESCAPE:
7559 /* Target kind is not ruleset changeable */
7560 return NULL;
7561 case ACTION_NUKE:
7562 return "explode_nuclear_target_kind";
7563 case ACTION_NUKE_CITY:
7564 return "nuke_city_target_kind";
7565 case ACTION_PILLAGE:
7566 return "pillage_target_kind";
7567 case ACTION_USER_ACTION1:
7568 return "user_action_1_target_kind";
7569 case ACTION_USER_ACTION2:
7570 return "user_action_2_target_kind";
7571 case ACTION_USER_ACTION3:
7572 return "user_action_3_target_kind";
7573 case ACTION_USER_ACTION4:
7574 return "user_action_4_target_kind";
7575 case ACTION_COUNT:
7576 break;
7577
7578 ASSERT_UNUSED_ACTION_CASES;
7579 }
7580
7581 fc_assert(act >= 0 && act < ACTION_COUNT);
7582
7583 return NULL;
7584}
7585
7586/**********************************************************************/
7593 const char *action_actor_consuming_always_ruleset_var_name(action_id act)
7594{
7595 switch ((enum gen_action)act) {
7596 case ACTION_SPY_POISON:
7597 case ACTION_SPY_POISON_ESC:
7598 case ACTION_SPY_SABOTAGE_UNIT:
7599 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7600 case ACTION_SPY_BRIBE_UNIT:
7601 case ACTION_SPY_SABOTAGE_CITY:
7602 case ACTION_SPY_SABOTAGE_CITY_ESC:
7603 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7604 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7605 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7606 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7607 case ACTION_SPY_INCITE_CITY:
7608 case ACTION_SPY_INCITE_CITY_ESC:
7609 case ACTION_ESTABLISH_EMBASSY:
7610 case ACTION_ESTABLISH_EMBASSY_STAY:
7611 case ACTION_SPY_STEAL_TECH:
7612 case ACTION_SPY_STEAL_TECH_ESC:
7613 case ACTION_SPY_TARGETED_STEAL_TECH:
7614 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7615 case ACTION_SPY_INVESTIGATE_CITY:
7616 case ACTION_INV_CITY_SPEND:
7617 case ACTION_SPY_STEAL_GOLD:
7618 case ACTION_SPY_STEAL_GOLD_ESC:
7619 case ACTION_STEAL_MAPS:
7620 case ACTION_STEAL_MAPS_ESC:
7621 case ACTION_TRADE_ROUTE:
7622 case ACTION_MARKETPLACE:
7623 case ACTION_HELP_WONDER:
7624 case ACTION_CAPTURE_UNITS:
7625 case ACTION_EXPEL_UNIT:
7626 case ACTION_JOIN_CITY:
7627 case ACTION_SPY_NUKE:
7628 case ACTION_SPY_NUKE_ESC:
7629 case ACTION_DESTROY_CITY:
7630 case ACTION_DISBAND_UNIT_RECOVER:
7631 case ACTION_DISBAND_UNIT:
7632 case ACTION_HOME_CITY:
7633 case ACTION_HOMELESS:
7634 case ACTION_UPGRADE_UNIT:
7635 case ACTION_PARADROP:
7636 case ACTION_PARADROP_CONQUER:
7637 case ACTION_PARADROP_FRIGHTEN:
7638 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7639 case ACTION_PARADROP_ENTER:
7640 case ACTION_PARADROP_ENTER_CONQUER:
7641 case ACTION_AIRLIFT:
7642 case ACTION_ATTACK:
7643 case ACTION_ATTACK2:
7644 case ACTION_SUICIDE_ATTACK:
7645 case ACTION_SUICIDE_ATTACK2:
7646 case ACTION_WIPE_UNITS:
7647 case ACTION_COLLECT_RANSOM:
7648 case ACTION_STRIKE_BUILDING:
7649 case ACTION_STRIKE_PRODUCTION:
7650 case ACTION_CONQUER_CITY:
7651 case ACTION_CONQUER_CITY2:
7652 case ACTION_CONQUER_CITY3:
7653 case ACTION_CONQUER_CITY4:
7654 case ACTION_HEAL_UNIT:
7655 case ACTION_HEAL_UNIT2:
7656 case ACTION_TRANSFORM_TERRAIN:
7657 case ACTION_CULTIVATE:
7658 case ACTION_PLANT:
7659 case ACTION_PILLAGE:
7660 case ACTION_CLEAN:
7661 case ACTION_FORTIFY:
7662 case ACTION_ROAD:
7663 case ACTION_CONVERT:
7664 case ACTION_BASE:
7665 case ACTION_MINE:
7666 case ACTION_IRRIGATE:
7667 case ACTION_TRANSPORT_DEBOARD:
7668 case ACTION_TRANSPORT_BOARD:
7669 case ACTION_TRANSPORT_BOARD2:
7670 case ACTION_TRANSPORT_BOARD3:
7671 case ACTION_TRANSPORT_EMBARK:
7672 case ACTION_TRANSPORT_EMBARK2:
7673 case ACTION_TRANSPORT_EMBARK3:
7674 case ACTION_TRANSPORT_EMBARK4:
7675 case ACTION_TRANSPORT_UNLOAD:
7676 case ACTION_TRANSPORT_LOAD:
7677 case ACTION_TRANSPORT_LOAD2:
7678 case ACTION_TRANSPORT_LOAD3:
7679 case ACTION_TRANSPORT_DISEMBARK1:
7680 case ACTION_TRANSPORT_DISEMBARK2:
7681 case ACTION_TRANSPORT_DISEMBARK3:
7682 case ACTION_TRANSPORT_DISEMBARK4:
7683 case ACTION_BOMBARD:
7684 case ACTION_BOMBARD2:
7685 case ACTION_BOMBARD3:
7686 case ACTION_BOMBARD_LETHAL:
7687 case ACTION_BOMBARD_LETHAL2:
7688 case ACTION_SPY_ATTACK:
7689 case ACTION_CONQUER_EXTRAS:
7690 case ACTION_CONQUER_EXTRAS2:
7691 case ACTION_CONQUER_EXTRAS3:
7692 case ACTION_CONQUER_EXTRAS4:
7693 case ACTION_HUT_ENTER:
7694 case ACTION_HUT_ENTER2:
7695 case ACTION_HUT_ENTER3:
7696 case ACTION_HUT_ENTER4:
7697 case ACTION_HUT_FRIGHTEN:
7698 case ACTION_HUT_FRIGHTEN2:
7699 case ACTION_HUT_FRIGHTEN3:
7700 case ACTION_HUT_FRIGHTEN4:
7701 case ACTION_UNIT_MOVE:
7702 case ACTION_UNIT_MOVE2:
7703 case ACTION_UNIT_MOVE3:
7704 case ACTION_TELEPORT:
7705 case ACTION_TELEPORT_CONQUER:
7706 case ACTION_TELEPORT_FRIGHTEN:
7707 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7708 case ACTION_TELEPORT_ENTER:
7709 case ACTION_TELEPORT_ENTER_CONQUER:
7710 case ACTION_SPY_ESCAPE:
7711 /* Actor consuming always is not ruleset changeable */
7712 return NULL;
7713 case ACTION_FOUND_CITY:
7714 return "found_city_consuming_always";
7715 case ACTION_NUKE:
7716 return "explode_nuclear_consuming_always";
7717 case ACTION_NUKE_CITY:
7718 return "nuke_city_consuming_always";
7719 case ACTION_NUKE_UNITS:
7720 return "nuke_units_consuming_always";
7721 case ACTION_SPY_SPREAD_PLAGUE:
7722 return "spread_plague_actor_consuming_always";
7723 case ACTION_USER_ACTION1:
7724 return "user_action_1_actor_consuming_always";
7725 case ACTION_USER_ACTION2:
7726 return "user_action_2_actor_consuming_always";
7727 case ACTION_USER_ACTION3:
7728 return "user_action_3_actor_consuming_always";
7729 case ACTION_USER_ACTION4:
7730 return "user_action_4_actor_consuming_always";
7731 case ACTION_COUNT:
7732 break;
7733
7734 ASSERT_UNUSED_ACTION_CASES;
7735 }
7736
7737 fc_assert(act >= 0 && act < ACTION_COUNT);
7738
7739 return NULL;
7740}
7741
7742/**********************************************************************/
7749 const char *action_blocked_by_ruleset_var_name(const struct action *act)
7750{
7751 fc_assert_ret_val(act != NULL, NULL);
7752
7753 switch ((enum gen_action)action_number(act)) {
7754 case ACTION_MARKETPLACE:
7755 return "enter_marketplace_blocked_by";
7756 case ACTION_BOMBARD:
7757 return "bombard_blocked_by";
7758 case ACTION_BOMBARD2:
7759 return "bombard_2_blocked_by";
7760 case ACTION_BOMBARD3:
7761 return "bombard_3_blocked_by";
7762 case ACTION_BOMBARD_LETHAL:
7763 return "bombard_lethal_blocked_by";
7764 case ACTION_BOMBARD_LETHAL2:
7765 return "bombard_lethal_2_blocked_by";
7766 case ACTION_NUKE:
7767 return "explode_nuclear_blocked_by";
7768 case ACTION_NUKE_CITY:
7769 return "nuke_city_blocked_by";
7770 case ACTION_NUKE_UNITS:
7771 return "nuke_units_blocked_by";
7772 case ACTION_ATTACK:
7773 return "attack_blocked_by";
7774 case ACTION_ATTACK2:
7775 return "attack_2_blocked_by";
7776 case ACTION_SUICIDE_ATTACK:
7777 return "suicide_attack_blocked_by";
7778 case ACTION_SUICIDE_ATTACK2:
7779 return "suicide_attack_2_blocked_by";
7780 case ACTION_WIPE_UNITS:
7781 return "wipe_units_blocked_by";
7782 case ACTION_COLLECT_RANSOM:
7783 return "collect_ransom_blocked_by";
7784 case ACTION_CONQUER_CITY:
7785 return "conquer_city_blocked_by";
7786 case ACTION_CONQUER_CITY2:
7787 return "conquer_city_2_blocked_by";
7788 case ACTION_CONQUER_CITY3:
7789 return "conquer_city_3_blocked_by";
7790 case ACTION_CONQUER_CITY4:
7791 return "conquer_city_4_blocked_by";
7792 case ACTION_UNIT_MOVE:
7793 return "move_blocked_by";
7794 case ACTION_UNIT_MOVE2:
7795 return "move_2_blocked_by";
7796 case ACTION_UNIT_MOVE3:
7797 return "move_3_blocked_by";
7798 case ACTION_TELEPORT:
7799 return "teleport_blocked_by";
7800 case ACTION_TELEPORT_CONQUER:
7801 return "teleport_conquer_blocked_by";
7802 case ACTION_TELEPORT_FRIGHTEN:
7803 return "teleport_frighten_blocked_by";
7804 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7805 return "teleport_frighten_conquer_blocked_by";
7806 case ACTION_TELEPORT_ENTER:
7807 return "teleport_enter_blocked_by";
7808 case ACTION_TELEPORT_ENTER_CONQUER:
7809 return "teleport_enter_conquer_blocked_by";
7810 case ACTION_SPY_ESCAPE:
7811 case ACTION_SPY_POISON:
7812 case ACTION_SPY_POISON_ESC:
7813 case ACTION_SPY_SABOTAGE_UNIT:
7814 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7815 case ACTION_SPY_BRIBE_UNIT:
7816 case ACTION_SPY_SABOTAGE_CITY:
7817 case ACTION_SPY_SABOTAGE_CITY_ESC:
7818 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7819 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7820 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7821 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7822 case ACTION_SPY_INCITE_CITY:
7823 case ACTION_SPY_INCITE_CITY_ESC:
7824 case ACTION_ESTABLISH_EMBASSY:
7825 case ACTION_ESTABLISH_EMBASSY_STAY:
7826 case ACTION_SPY_STEAL_TECH:
7827 case ACTION_SPY_STEAL_TECH_ESC:
7828 case ACTION_SPY_TARGETED_STEAL_TECH:
7829 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7830 case ACTION_SPY_INVESTIGATE_CITY:
7831 case ACTION_INV_CITY_SPEND:
7832 case ACTION_SPY_STEAL_GOLD:
7833 case ACTION_SPY_STEAL_GOLD_ESC:
7834 case ACTION_STEAL_MAPS:
7835 case ACTION_STEAL_MAPS_ESC:
7836 case ACTION_TRADE_ROUTE:
7837 case ACTION_HELP_WONDER:
7838 case ACTION_CAPTURE_UNITS:
7839 case ACTION_EXPEL_UNIT:
7840 case ACTION_FOUND_CITY:
7841 case ACTION_JOIN_CITY:
7842 case ACTION_SPY_NUKE:
7843 case ACTION_SPY_NUKE_ESC:
7844 case ACTION_DESTROY_CITY:
7845 case ACTION_DISBAND_UNIT_RECOVER:
7846 case ACTION_DISBAND_UNIT:
7847 case ACTION_HOME_CITY:
7848 case ACTION_HOMELESS:
7849 case ACTION_UPGRADE_UNIT:
7850 case ACTION_PARADROP:
7851 case ACTION_PARADROP_CONQUER:
7852 case ACTION_PARADROP_FRIGHTEN:
7853 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7854 case ACTION_PARADROP_ENTER:
7855 case ACTION_PARADROP_ENTER_CONQUER:
7856 case ACTION_AIRLIFT:
7857 case ACTION_STRIKE_BUILDING:
7858 case ACTION_STRIKE_PRODUCTION:
7859 case ACTION_HEAL_UNIT:
7860 case ACTION_HEAL_UNIT2:
7861 case ACTION_TRANSFORM_TERRAIN:
7862 case ACTION_CULTIVATE:
7863 case ACTION_PLANT:
7864 case ACTION_PILLAGE:
7865 case ACTION_CLEAN:
7866 case ACTION_FORTIFY:
7867 case ACTION_ROAD:
7868 case ACTION_CONVERT:
7869 case ACTION_BASE:
7870 case ACTION_MINE:
7871 case ACTION_IRRIGATE:
7872 case ACTION_TRANSPORT_DEBOARD:
7873 case ACTION_TRANSPORT_BOARD:
7874 case ACTION_TRANSPORT_BOARD2:
7875 case ACTION_TRANSPORT_BOARD3:
7876 case ACTION_TRANSPORT_EMBARK:
7877 case ACTION_TRANSPORT_EMBARK2:
7878 case ACTION_TRANSPORT_EMBARK3:
7879 case ACTION_TRANSPORT_EMBARK4:
7880 case ACTION_TRANSPORT_UNLOAD:
7881 case ACTION_TRANSPORT_LOAD:
7882 case ACTION_TRANSPORT_LOAD2:
7883 case ACTION_TRANSPORT_LOAD3:
7884 case ACTION_TRANSPORT_DISEMBARK1:
7885 case ACTION_TRANSPORT_DISEMBARK2:
7886 case ACTION_TRANSPORT_DISEMBARK3:
7887 case ACTION_TRANSPORT_DISEMBARK4:
7888 case ACTION_SPY_SPREAD_PLAGUE:
7889 case ACTION_SPY_ATTACK:
7890 case ACTION_CONQUER_EXTRAS:
7891 case ACTION_CONQUER_EXTRAS2:
7892 case ACTION_CONQUER_EXTRAS3:
7893 case ACTION_CONQUER_EXTRAS4:
7894 case ACTION_HUT_ENTER:
7895 case ACTION_HUT_ENTER2:
7896 case ACTION_HUT_ENTER3:
7897 case ACTION_HUT_ENTER4:
7898 case ACTION_HUT_FRIGHTEN:
7899 case ACTION_HUT_FRIGHTEN2:
7900 case ACTION_HUT_FRIGHTEN3:
7901 case ACTION_HUT_FRIGHTEN4:
7902 case ACTION_USER_ACTION1:
7903 case ACTION_USER_ACTION2:
7904 case ACTION_USER_ACTION3:
7905 case ACTION_USER_ACTION4:
7906 /* blocked_by is not ruleset changeable */
7907 return NULL;
7908 case ACTION_COUNT:
7909 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
7910 break;
7911
7912 ASSERT_UNUSED_ACTION_CASES;
7913 }
7914
7915 return NULL;
7916}
7917
7918/**********************************************************************/
7922const char *
7923action_post_success_forced_ruleset_var_name(const struct action *act)
7924{
7925 fc_assert_ret_val(act != NULL, NULL);
7926
7927 if (!(action_has_result(act, ACTRES_SPY_BRIBE_UNIT)
7928 || action_has_result(act, ACTRES_ATTACK)
7929 || action_has_result(act, ACTRES_WIPE_UNITS)
7930 || action_has_result(act, ACTRES_COLLECT_RANSOM))) {
7931 /* No support in the action performer function */
7932 return NULL;
7933 }
7934
7935 switch ((enum gen_action)action_number(act)) {
7936 case ACTION_SPY_BRIBE_UNIT:
7937 return "bribe_unit_post_success_forced_actions";
7938 case ACTION_ATTACK:
7939 return "attack_post_success_forced_actions";
7940 case ACTION_ATTACK2:
7941 return "attack_2_post_success_forced_actions";
7942 case ACTION_WIPE_UNITS:
7943 return "wipe_units_post_success_forced_actions";
7944 case ACTION_COLLECT_RANSOM:
7945 return "collect_ransom_post_success_forced_actions";
7946 case ACTION_MARKETPLACE:
7947 case ACTION_BOMBARD:
7948 case ACTION_BOMBARD2:
7949 case ACTION_BOMBARD3:
7950 case ACTION_BOMBARD_LETHAL:
7951 case ACTION_BOMBARD_LETHAL2:
7952 case ACTION_NUKE:
7953 case ACTION_NUKE_CITY:
7954 case ACTION_NUKE_UNITS:
7955 case ACTION_SUICIDE_ATTACK:
7956 case ACTION_SUICIDE_ATTACK2:
7957 case ACTION_CONQUER_CITY:
7958 case ACTION_CONQUER_CITY2:
7959 case ACTION_CONQUER_CITY3:
7960 case ACTION_CONQUER_CITY4:
7961 case ACTION_SPY_POISON:
7962 case ACTION_SPY_POISON_ESC:
7963 case ACTION_SPY_SABOTAGE_UNIT:
7964 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7965 case ACTION_SPY_SABOTAGE_CITY:
7966 case ACTION_SPY_SABOTAGE_CITY_ESC:
7967 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7968 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7969 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7970 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7971 case ACTION_SPY_INCITE_CITY:
7972 case ACTION_SPY_INCITE_CITY_ESC:
7973 case ACTION_ESTABLISH_EMBASSY:
7974 case ACTION_ESTABLISH_EMBASSY_STAY:
7975 case ACTION_SPY_STEAL_TECH:
7976 case ACTION_SPY_STEAL_TECH_ESC:
7977 case ACTION_SPY_TARGETED_STEAL_TECH:
7978 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7979 case ACTION_SPY_INVESTIGATE_CITY:
7980 case ACTION_INV_CITY_SPEND:
7981 case ACTION_SPY_STEAL_GOLD:
7982 case ACTION_SPY_STEAL_GOLD_ESC:
7983 case ACTION_STEAL_MAPS:
7984 case ACTION_STEAL_MAPS_ESC:
7985 case ACTION_TRADE_ROUTE:
7986 case ACTION_HELP_WONDER:
7987 case ACTION_CAPTURE_UNITS:
7988 case ACTION_EXPEL_UNIT:
7989 case ACTION_FOUND_CITY:
7990 case ACTION_JOIN_CITY:
7991 case ACTION_SPY_NUKE:
7992 case ACTION_SPY_NUKE_ESC:
7993 case ACTION_DESTROY_CITY:
7994 case ACTION_DISBAND_UNIT_RECOVER:
7995 case ACTION_DISBAND_UNIT:
7996 case ACTION_HOME_CITY:
7997 case ACTION_HOMELESS:
7998 case ACTION_UPGRADE_UNIT:
7999 case ACTION_PARADROP:
8000 case ACTION_PARADROP_CONQUER:
8001 case ACTION_PARADROP_FRIGHTEN:
8002 case ACTION_PARADROP_FRIGHTEN_CONQUER:
8003 case ACTION_PARADROP_ENTER:
8004 case ACTION_PARADROP_ENTER_CONQUER:
8005 case ACTION_AIRLIFT:
8006 case ACTION_STRIKE_BUILDING:
8007 case ACTION_STRIKE_PRODUCTION:
8008 case ACTION_HEAL_UNIT:
8009 case ACTION_HEAL_UNIT2:
8010 case ACTION_TRANSFORM_TERRAIN:
8011 case ACTION_CULTIVATE:
8012 case ACTION_PLANT:
8013 case ACTION_PILLAGE:
8014 case ACTION_CLEAN:
8015 case ACTION_FORTIFY:
8016 case ACTION_ROAD:
8017 case ACTION_CONVERT:
8018 case ACTION_BASE:
8019 case ACTION_MINE:
8020 case ACTION_IRRIGATE:
8021 case ACTION_TRANSPORT_DEBOARD:
8022 case ACTION_TRANSPORT_BOARD:
8023 case ACTION_TRANSPORT_BOARD2:
8024 case ACTION_TRANSPORT_BOARD3:
8025 case ACTION_TRANSPORT_EMBARK:
8026 case ACTION_TRANSPORT_EMBARK2:
8027 case ACTION_TRANSPORT_EMBARK3:
8028 case ACTION_TRANSPORT_EMBARK4:
8029 case ACTION_TRANSPORT_UNLOAD:
8030 case ACTION_TRANSPORT_LOAD:
8031 case ACTION_TRANSPORT_LOAD2:
8032 case ACTION_TRANSPORT_LOAD3:
8033 case ACTION_TRANSPORT_DISEMBARK1:
8034 case ACTION_TRANSPORT_DISEMBARK2:
8035 case ACTION_TRANSPORT_DISEMBARK3:
8036 case ACTION_TRANSPORT_DISEMBARK4:
8037 case ACTION_SPY_SPREAD_PLAGUE:
8038 case ACTION_SPY_ATTACK:
8039 case ACTION_CONQUER_EXTRAS:
8040 case ACTION_CONQUER_EXTRAS2:
8041 case ACTION_CONQUER_EXTRAS3:
8042 case ACTION_CONQUER_EXTRAS4:
8043 case ACTION_HUT_ENTER:
8044 case ACTION_HUT_ENTER2:
8045 case ACTION_HUT_ENTER3:
8046 case ACTION_HUT_ENTER4:
8047 case ACTION_HUT_FRIGHTEN:
8048 case ACTION_HUT_FRIGHTEN2:
8049 case ACTION_HUT_FRIGHTEN3:
8050 case ACTION_HUT_FRIGHTEN4:
8051 case ACTION_UNIT_MOVE:
8052 case ACTION_UNIT_MOVE2:
8053 case ACTION_UNIT_MOVE3:
8054 case ACTION_TELEPORT:
8055 case ACTION_TELEPORT_CONQUER:
8056 case ACTION_TELEPORT_FRIGHTEN:
8057 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
8058 case ACTION_TELEPORT_ENTER:
8059 case ACTION_TELEPORT_ENTER_CONQUER:
8060 case ACTION_SPY_ESCAPE:
8061 case ACTION_USER_ACTION1:
8062 case ACTION_USER_ACTION2:
8063 case ACTION_USER_ACTION3:
8064 case ACTION_USER_ACTION4:
8065 /* Not ruleset changeable */
8066 return NULL;
8067 case ACTION_COUNT:
8068 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
8069 break;
8070
8071 ASSERT_UNUSED_ACTION_CASES;
8072 }
8073
8074 return NULL;
8075}
8076
8077/**********************************************************************/
8081 bool action_ever_possible(action_id action)
8082{
8083 return action_enabler_list_size(action_enablers_for_action(action)) > 0;
8084}
8085
8086/**********************************************************************/
8089 const char *gen_action_name_update_cb(const char *old_name)
8090{
8091 if (is_ruleset_compat_mode()) {
8092 if (!fc_strcasecmp("Transport Alight", old_name)) {
8093 return "Transport Deboard";
8094 }
8095 }
8096
8097 return old_name;
8098}
8099
8100 const char *atk_helpnames[ATK_COUNT] =
8101{
8102 N_("individual cities"), /* ATK_CITY */
8103 N_("individual units"), /* ATK_UNIT */
8104 N_("unit stacks"), /* ATK_UNITS */
8105 N_("tiles"), /* ATK_TILE */
8106 N_("tile extras"), /* ATK_EXTRAS */
8107 N_("itself") /* ATK_SELF */
8108};
8109
8110/**********************************************************************/
8114 const char *action_target_kind_help(enum action_target_kind kind)
8115{
8116 fc_assert(kind >= 0 && kind < ATK_COUNT);
8117
8118 return _(atk_helpnames[kind]);
8119}
8120
8121/************************************************************************/
8124 struct action_list *action_list_by_result(enum action_result result)
8125{
8126 fc_assert(result < ACTRES_LAST);
8127
8128 return actlist_by_result[result];
8129}
8130
8131/************************************************************************/
8134 struct action_list *action_list_by_activity(enum unit_activity activity)
8135{
8136 fc_assert(activity < ACTIVITY_LAST);
8137
8138 return actlist_by_activity[activity];
8139}
is_action_possible_on_city
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:6216
actions
static struct action * actions[MAX_NUM_ACTIONS]
Definition actions.c:97
action_prepare_ui_name
const char * action_prepare_ui_name(action_id act_id, const char *mnemonic, const struct act_prob prob, const char *custom)
Definition actions.c:2064
action_name_translation
const char * action_name_translation(const struct action *action)
Definition actions.c:1982
action_distance_inside_max
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1925
oblig_hard_req_reg
static void oblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:247
is_action_possible
static enum fc_tristate is_action_possible(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct req_context *target, const struct extra_type *target_extra, const bool omniscient, const struct city *homecity)
Definition actions.c:3553
voblig_hard_req_reg
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:203
action_prob_explain
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:2175
action_mp_full_makes_legal
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:6294
action_prob_battle_then_dice_roll
static struct act_prob action_prob_battle_then_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct player *tgt_player, const struct action *paction)
Definition actions.c:4521
is_action_enabled_unit_on_self_full
static bool is_action_enabled_unit_on_self_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile)
Definition actions.c:4171
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1850
action_prob_certain
bool action_prob_certain(const struct act_prob probability)
Definition actions.c:5833
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2002
action_auto_perf_slot_number
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:6423
action_enabler_vector_number
req_vec_num_in_item action_enabler_vector_number(const void *enabler, const struct requirement_vector *vec)
Definition actions.c:2800
action_has_complex_target
bool action_has_complex_target(const struct action *paction)
Definition actions.c:1884
action_actor_utype_hard_reqs_ok_full
static bool action_actor_utype_hard_reqs_ok_full(const struct action *paction, const struct unit_type *actor_unittype, bool ignore_third_party)
Definition actions.c:3140
oblig_hard_reqs_r
static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE]
Definition actions.c:105
action_prob_self
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:5497
action_enabler_suggest_repair
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2670
is_action_enabled_unit_on_tile_full
static bool is_action_enabled_unit_on_tile_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4015
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5823
ACTPROB_VAL_NOT_IMPL
#define ACTPROB_VAL_NOT_IMPL
Definition actions.c:95
auto_perfs
struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS]
Definition actions.c:99
action_actor_utype_hard_reqs_ok
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3347
action_prob_new_not_impl
struct act_prob action_prob_new_not_impl(void)
Definition actions.c:5802
action_enabler_suggest_improvement
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2736
action_enabled_local
static enum fc_tristate action_enabled_local(const action_id wanted_action, const struct req_context *actor, const struct req_context *target)
Definition actions.c:4252
actions_rs_pre_san_gen
void actions_rs_pre_san_gen(void)
Definition actions.c:1645
action_min_range_ruleset_var_name
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:7113
action_blocked_by_ruleset_var_name
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7749
is_action_enabled
static bool is_action_enabled(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct req_context *target, const struct extra_type *target_extra, const struct city *actor_home)
Definition actions.c:3728
ACTPROB_VAL_MAX
#define ACTPROB_VAL_MAX
Definition actions.c:89
action_prob
static struct act_prob action_prob(const struct civ_map *nmap, const action_id wanted_action, const struct req_context *actor, const struct city *actor_home, const struct req_context *target, const struct extra_type *target_extra)
Definition actions.c:4569
action_enabler_suggest_repair_oblig
struct req_vec_problem * action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
Definition actions.c:2430
action_array_add_all_by_result
void action_array_add_all_by_result(action_id *act_array, int *position, enum action_result result)
Definition actions.c:6488
action_dice_roll_odds
int action_dice_roll_odds(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Definition actions.c:6123
action_array_end
void action_array_end(action_id *act_array, int size)
Definition actions.c:6471
req_contradiction_or
static struct ae_contra_or * req_contradiction_or(int alternatives,...)
Definition actions.c:155
is_action_enabled_unit_on_self
bool is_action_enabled_unit_on_self(const action_id wanted_action, const struct unit *actor_unit)
Definition actions.c:4223
action_prob_pre_action_dice_roll
static struct act_prob action_prob_pre_action_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Definition actions.c:4477
atk_helpnames
const char * atk_helpnames[ATK_COUNT]
Definition actions.c:8100
action_hard_reqs_actor
static enum fc_tristate action_hard_reqs_actor(const struct civ_map *nmap, const struct action *paction, const struct req_context *actor, const bool omniscient, const struct city *homecity)
Definition actions.c:3367
hard_code_actions
static void hard_code_actions(void)
Definition actions.c:925
is_action_enabled_unit_on_city_full
static bool is_action_enabled_unit_on_city_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct city *target_city)
Definition actions.c:3767
action_is_in_use
bool action_is_in_use(struct action *paction)
Definition actions.c:6400
action_prob_unit_vs_tgt
struct act_prob action_prob_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:5519
enabler_tile_tgt_local_diplrel_implies_claimed
static struct req_vec_problem * enabler_tile_tgt_local_diplrel_implies_claimed(const struct action_enabler *enabler)
Definition actions.c:2525
action_ever_possible
bool action_ever_possible(action_id action)
Definition actions.c:8081
action_enabler_vector_by_number_name
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:2847
are_action_probabilitys_equal
bool are_action_probabilitys_equal(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:5874
action_prob_vs_city
struct act_prob action_prob_vs_city(const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4981
action_prob_self_full
static struct act_prob action_prob_self_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id)
Definition actions.c:5444
action_post_success_forced_ruleset_var_name
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7923
action_prob_vs_unit
struct act_prob action_prob_vs_unit(const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5065
action_by_rule_name
struct action * action_by_rule_name(const char *name)
Definition actions.c:1831
action_has_possible_actor_hard_reqs
static bool action_has_possible_actor_hard_reqs(struct action *paction)
Definition actions.c:6375
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1968
action_id_rule_name
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1991
action_get_sub_target_kind
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1871
blocked_find_target_tile
static const struct tile * blocked_find_target_tile(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city, const struct unit *target_unit)
Definition actions.c:2915
action_prob_not_relevant
static bool action_prob_not_relevant(const struct act_prob probability)
Definition actions.c:5844
ap_diplomat_battle
static struct act_prob ap_diplomat_battle(const struct unit *pattacker, const struct unit *pvictim, const struct tile *tgt_tile, const struct action *paction) fc__attribute((nonnull(3)))
Definition actions.c:4431
actions_free
void actions_free(void)
Definition actions.c:1655
is_action_enabled_unit_on_extras_full
static bool is_action_enabled_unit_on_extras_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4092
action_enabler_free
void action_enabler_free(struct action_enabler *enabler)
Definition actions.c:2246
action_prob_vs_tile
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5342
is_action_enabled_unit_on_stack
bool is_action_enabled_unit_on_stack(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:3997
ae_contra_close
static void ae_contra_close(struct ae_contra_or *contra)
Definition actions.c:184
tech_can_be_stolen
static enum fc_tristate tech_can_be_stolen(const struct player *actor_player, const struct player *target_player)
Definition actions.c:4318
actlist_by_result
static struct action_list * actlist_by_result[ACTRES_LAST]
Definition actions.c:141
oblig_hard_reqs_sr
static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT]
Definition actions.c:106
oblig_hard_req_reg_sub_res
static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message,...)
Definition actions.c:336
action_list_by_activity
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:8134
action_number
int action_number(const struct action *action)
Definition actions.c:1960
action_prob_new_unknown
struct act_prob action_prob_new_unknown(void)
Definition actions.c:5812
action_would_be_blocked_by
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1948
ACTPROB_VAL_NA
#define ACTPROB_VAL_NA
Definition actions.c:93
enabler_first_clarification
static struct req_vec_problem * enabler_first_clarification(const struct action_enabler *enabler)
Definition actions.c:2718
action_speculate_unit_on_self
struct act_prob action_speculate_unit_on_self(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat)
Definition actions.c:5744
is_effect_val_known
static bool is_effect_val_known(enum effect_type effect_type, const struct player *pov_player, const struct req_context *context, const struct player *other_player)
Definition actions.c:4298
action_prob_not_impl
static bool action_prob_not_impl(const struct act_prob probability)
Definition actions.c:5855
is_action_enabled_unit_on_tile
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4073
action_prob_and
struct act_prob action_prob_and(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:5961
actions_initialized
static bool actions_initialized
Definition actions.c:100
action_actor_consuming_always_ruleset_var_name
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:7593
action_immune_government
bool action_immune_government(struct government *gov, action_id act)
Definition actions.c:6175
voblig_hard_req_reg_sub_res
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition actions.c:294
is_target_possible
static bool is_target_possible(const action_id wanted_action, const struct player *actor_player, const struct req_context *target)
Definition actions.c:6198
ap_dipl_battle_win
static struct act_prob ap_dipl_battle_win(const struct unit *pattacker, const struct unit *pdefender)
Definition actions.c:4354
action_prob_vs_stack_full
static struct act_prob action_prob_vs_stack_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:5083
action_is_blocked_by
struct action * action_is_blocked_by(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:3027
action_prob_new_certain
struct act_prob action_prob_new_certain(void)
Definition actions.c:5782
action_max_range_ruleset_var_name
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:7272
action_speculate_unit_on_stack
struct act_prob action_speculate_unit_on_stack(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:5643
action_prob_vs_city_full
static struct act_prob action_prob_vs_city_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct city *target_city)
Definition actions.c:4894
action_dice_roll_initial_odds
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:6099
action_prob_fall_back
struct act_prob action_prob_fall_back(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:6031
obligatory_req_vector_iterate_end
#define obligatory_req_vector_iterate_end
Definition actions.c:77
tgt_city_local_utype
static const struct unit_type * tgt_city_local_utype(const struct city *target_city)
Definition actions.c:2890
req_vec_first_local_diplrel
static struct requirement * req_vec_first_local_diplrel(const struct requirement_vector *vec)
Definition actions.c:2481
action_prob_vs_stack
struct act_prob action_prob_vs_stack(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:5258
action_prob_vs_tile_full
static struct act_prob action_prob_vs_tile_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5276
action_speculate_unit_on_extras
struct act_prob action_speculate_unit_on_extras(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5710
is_action_enabled_unit_on_city
bool is_action_enabled_unit_on_city(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Definition actions.c:3832
is_action_enabled_unit_on_extras
bool is_action_enabled_unit_on_extras(const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4150
action_list_by_result
struct action_list * action_list_by_result(enum action_result result)
Definition actions.c:8124
action_univs_not_blocking
bool action_univs_not_blocking(const struct action *paction, struct universal *actor_uni, struct universal *target_uni)
Definition actions.c:6447
req_vec_first_contradiction_in_vec
static struct requirement * req_vec_first_contradiction_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition actions.c:2502
actions_are_ready
bool actions_are_ready(void)
Definition actions.c:1708
is_action_enabled_unit_on_unit
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:3909
action_speculate_unit_on_city
struct act_prob action_speculate_unit_on_city(const action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, const bool omniscient_cheat, const struct city *target)
Definition actions.c:5575
action_target_kind_ruleset_var_name
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:7439
obligatory_req_vector_iterate
#define obligatory_req_vector_iterate(obreq_vec, pobreq)
Definition actions.c:75
action_prob_vs_unit_full
static struct act_prob action_prob_vs_unit_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct unit *target_unit)
Definition actions.c:4998
action_maybe_possible_actor_unit
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:6239
is_enabler_active
static bool is_enabler_active(const struct action_enabler *enabler, const struct req_context *actor, const struct req_context *target)
Definition actions.c:3709
action_enablers_by_action
static struct action_enabler_list * action_enablers_by_action[MAX_NUM_ACTIONS]
Definition actions.c:102
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2273
hard_code_oblig_hard_reqs
static void hard_code_oblig_hard_reqs(void)
Definition actions.c:354
action_ui_name_default
const char * action_ui_name_default(int act)
Definition actions.c:6773
ACTPROB_VAL_1_PCT
#define ACTPROB_VAL_1_PCT
Definition actions.c:91
action_enabler_utype_possible_actor
bool action_enabler_utype_possible_actor(const struct action_enabler *ae, const struct unit_type *act_utype)
Definition actions.c:6317
act_prob_unseen_target
static struct act_prob act_prob_unseen_target(const struct civ_map *nmap, action_id act_id, const struct unit *actor_unit)
Definition actions.c:4459
action_enabler_new
struct action_enabler * action_enabler_new(void)
Definition actions.c:2227
action_requires_details
bool action_requires_details(const struct action *paction)
Definition actions.c:1897
action_prob_new_not_relevant
struct act_prob action_prob_new_not_relevant(void)
Definition actions.c:5792
action_target_kind_help
const char * action_target_kind_help(enum action_target_kind kind)
Definition actions.c:8114
enabler_first_self_contradiction
static struct req_vec_problem * enabler_first_self_contradiction(const struct action_enabler *enabler)
Definition actions.c:2598
action_get_role
int action_get_role(const struct action *paction)
Definition actions.c:2215
action_prob_vs_extras
struct act_prob action_prob_vs_extras(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5426
unit_action_new
static struct action * unit_action_new(action_id id, enum action_result result, bool rare_pop_up, bool unitwaittime_controlled, enum moves_actor_kind moves_actor, const int min_distance, const int max_distance, bool actor_consuming_always)
Definition actions.c:1795
action_speculate_unit_on_unit
struct act_prob action_speculate_unit_on_unit(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct unit *target)
Definition actions.c:5610
action_auto_perf_by_number
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:6439
action_prob_new_impossible
struct act_prob action_prob_new_impossible(void)
Definition actions.c:5772
action_enabler_possible_actor
bool action_enabler_possible_actor(const struct action_enabler *ae)
Definition actions.c:6344
blocked_find_target_city
static const struct city * blocked_find_target_city(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:2973
_actions
struct action ** _actions
Definition actions.c:98
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1820
action_enabler_remove
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:2290
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1860
action_prob_is_signal
static bool action_prob_is_signal(const struct act_prob probability)
Definition actions.c:5866
action_enabler_copy
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2258
action_prob_to_text
static const char * action_prob_to_text(const struct act_prob prob)
Definition actions.c:2023
action_prob_cmp_pessimist
int action_prob_cmp_pessimist(const struct act_prob ap1, const struct act_prob ap2)
Definition actions.c:5883
action_id_is_rare_pop_up
bool action_id_is_rare_pop_up(action_id act_id)
Definition actions.c:1912
actions_init
void actions_init(void)
Definition actions.c:1585
action_speculate_unit_on_tile
struct act_prob action_speculate_unit_on_tile(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5676
action_new
static struct action * action_new(action_id id, enum action_result result, const int min_distance, const int max_distance, bool actor_consuming_always)
Definition actions.c:1732
hard_code_oblig_hard_reqs_ruleset
static void hard_code_oblig_hard_reqs_ruleset(void)
Definition actions.c:888
ae_suggest_repair_if_no_oblig
static struct req_vec_problem * ae_suggest_repair_if_no_oblig(const struct action_enabler *enabler, const struct obligatory_req_vector *oblig)
Definition actions.c:2326
tgt_city_local_building
static const struct impr_type * tgt_city_local_building(const struct city *target_city)
Definition actions.c:2867
ui_name_str
static struct astring ui_name_str
Definition actions.c:108
is_action_enabled_unit_on_unit_full
static bool is_action_enabled_unit_on_unit_full(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const struct unit *target_unit)
Definition actions.c:3850
is_action_enabled_unit_on_stack_full
static bool is_action_enabled_unit_on_stack_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:3927
action_prob_to_0_to_1_pessimist
double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
Definition actions.c:5934
oblig_hard_req_register
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition actions.c:267
gen_action_name_update_cb
const char * gen_action_name_update_cb(const char *old_name)
Definition actions.c:8089
actlist_by_activity
static struct action_list * actlist_by_activity[ACTIVITY_LAST]
Definition actions.c:142
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2306
action_enabler_vector_by_number
struct requirement_vector * action_enabler_vector_by_number(const void *enabler, req_vec_num_in_item number)
Definition actions.c:2823
action_distance_accepted
bool action_distance_accepted(const struct action *action, const int distance)
Definition actions.c:1936
action_prob_vs_extras_full
static struct act_prob action_prob_vs_extras_full(const struct civ_map *nmap, const struct unit *actor_unit, const struct city *actor_home, const struct tile *actor_tile, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5360
action_ui_name_ruleset_var_name
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:6508
action_get_ui_name_mnemonic
const char * action_get_ui_name_mnemonic(action_id act_id, const char *mnemonic)
Definition actions.c:2010
ACTPROB_VAL_MIN
#define ACTPROB_VAL_MIN
Definition actions.c:87
actions.h
ACTION_DISTANCE_MAX
#define ACTION_DISTANCE_MAX
Definition actions.h:357
enabler_get_action
#define enabler_get_action(_enabler_)
Definition actions.h:431
ASSERT_UNUSED_ACTION_CASES
#define ASSERT_UNUSED_ACTION_CASES
Definition actions.h:38
ACTPROB_CERTAIN
#define ACTPROB_CERTAIN
Definition actions.h:905
enabler_get_action_id
#define enabler_get_action_id(_enabler_)
Definition actions.h:432
ACTPROB_NA
#define ACTPROB_NA
Definition actions.h:906
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
action_enabler_list_re_iterate_end
#define action_enabler_list_re_iterate_end
Definition actions.h:445
ACTION_DISTANCE_LAST_NON_SIGNAL
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:353
action_enabler_list_re_iterate
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:441
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:429
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:439
ACTION_DISTANCE_UNLIMITED
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:355
action_iterate_end
#define action_iterate_end
Definition actions.h:463
MAX_NUM_ACTIONS
#define MAX_NUM_ACTIONS
Definition actions.h:312
action_iterate_all
#define action_iterate_all(_act_)
Definition actions.h:449
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:646
action_iterate_all_end
#define action_iterate_all_end
Definition actions.h:454
ACTPROB_NOT_KNOWN
#define ACTPROB_NOT_KNOWN
Definition actions.h:908
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:437
action_id_distance_accepted
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:682
ACTPROB_IMPOSSIBLE
#define ACTPROB_IMPOSSIBLE
Definition actions.h:904
ACTPROB_NOT_IMPLEMENTED
#define ACTPROB_NOT_IMPLEMENTED
Definition actions.h:907
action_iterate
#define action_iterate(_act_)
Definition actions.h:459
ACTION_ANY
#define ACTION_ANY
Definition actions.h:306
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:650
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:663
ACTION_ODDS_PCT_DICE_ROLL_NA
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:911
ACTION_NONE
#define ACTION_NONE
Definition actions.h:309
actres_sub_target_kind_default
enum action_sub_target_kind actres_sub_target_kind_default(enum action_result result)
Definition actres.c:669
actres_target_compl_calc
enum act_tgt_compl actres_target_compl_calc(enum action_result result)
Definition actres.c:258
actres_possible
enum fc_tristate actres_possible(const struct civ_map *nmap, enum action_result result, const struct req_context *actor, const struct req_context *target, const struct extra_type *target_extra, enum fc_tristate def, bool omniscient, const struct city *homecity)
Definition actres.c:831
actres_activity_result
enum unit_activity actres_activity_result(enum action_result result)
Definition actres.c:301
actres_dice_type
enum dice_roll_type actres_dice_type(enum action_result result)
Definition actres.c:364
actres_get_battle_kind
enum action_battle_kind actres_get_battle_kind(enum action_result result)
Definition actres.c:272
actres_target_kind_default
enum action_target_kind actres_target_kind_default(enum action_result result)
Definition actres.c:766
ASSERT_UNUSED_ACTRES_CASES
#define ASSERT_UNUSED_ACTRES_CASES
Definition actres.h:37
DRT_DIPLCHANCE
@ DRT_DIPLCHANCE
Definition actres.h:110
DRT_CERTAIN
@ DRT_CERTAIN
Definition actres.h:110
DRT_NONE
@ DRT_NONE
Definition actres.h:110
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
astr_clear
void astr_clear(struct astring *astr)
Definition astring.c:205
astr_add
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
territory_claiming_base
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
city.h
is_non_attack_city_tile
static bool is_non_attack_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:750
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_owner
#define city_owner(_pcity_)
Definition city.h:563
unit_win_chance
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:478
unit_attack_units_at_tile_result
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:256
get_defender
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:834
get_diplomatic_defender
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile, const struct action *paction)
Definition combat.c:940
can_unit_attack_tile
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:311
combat.h
ATT_OK
@ ATT_OK
Definition combat.h:35
enablers
char * enablers
Definition comments.c:55
incite_cost
char * incite_cost
Definition comments.c:74
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:55
actor
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
target_tile
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
target_city
struct unit struct city * target_city
Definition dialogs_g.h:56
target_extra
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:57
id
int int id
Definition editgui_g.h:28
reqs
struct @21::@22 reqs
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:748
get_effects
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:143
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:406
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:404
extra_type_list_of_terr_claimers
struct extra_type_list * extra_type_list_of_terr_claimers(void)
Definition extras.c:275
is_native_extra_to_uclass
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:843
extra_type_list_iterate
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
extra_type_list_iterate_end
#define extra_type_list_iterate_end
Definition extras.h:167
fc_funcs
const struct functions * fc_funcs
Definition fc_interface.c:38
fc_interface.h
Tech_type_id
int Tech_type_id
Definition fc_types.h:380
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:704
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:703
action_id
int action_id
Definition fc_types.h:392
ACTRES_NONE
#define ACTRES_NONE
Definition fc_types.h:330
MAX_NUM_ACTION_AUTO_PERFORMERS
#define MAX_NUM_ACTION_AUTO_PERFORMERS
Definition fc_types.h:54
_
#define _(String)
Definition fcintl.h:67
N_
#define N_(String)
Definition fcintl.h:69
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game.h
is_ruleset_compat_mode
static bool is_ruleset_compat_mode(void)
Definition game.h:361
name
const char * name
Definition inputfile.c:127
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_msg
#define fc_assert_ret_msg(condition, message,...)
Definition log.h:205
fc_assert_action_msg
#define fc_assert_action_msg(condition, action, message,...)
Definition log.h:201
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
fc_assert_action
#define fc_assert_action(condition, action)
Definition log.h:187
log_error
#define log_error(message,...)
Definition log.h:103
FC_STATIC_ASSERT
#define FC_STATIC_ASSERT(cond, tag)
Definition log.h:235
fc_assert_ret_val_msg
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
real_map_distance
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:630
map.h
MAP_DISTANCE_MAX
#define MAP_DISTANCE_MAX
Definition map.h:646
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
can_see_techs_of_target
bool can_see_techs_of_target(const struct player *pow_player, const struct player *target_player)
Definition metaknowledge.c:774
mke_eval_reqs
enum fc_tristate mke_eval_reqs(const struct player *pov_player, const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition metaknowledge.c:748
metaknowledge.h
can_unit_exist_at_tile
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:319
is_native_tile
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:331
unit_move_rate
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
unit_could_load_at
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:911
can_unit_type_transport
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:868
can_attack_non_native
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:214
movement.h
nation_number
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
nation_barbarian_type
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:211
nation.h
nations_iterate_end
#define nations_iterate_end
Definition nation.h:336
nations_iterate
#define nations_iterate(NAME_pnation)
Definition nation.h:333
can_player_see_tile
bool can_player_see_tile(const struct player *plr, const struct tile *ptile)
Definition player.c:1091
can_player_see_unit
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1104
pplayers_at_war
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
player_can_see_city_externals
bool player_can_see_city_externals(const struct player *pow_player, const struct city *target_city)
Definition player.c:1164
pplayers_allied
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
can_player_see_hypotetic_units_at
bool can_player_see_hypotetic_units_at(const struct player *pplayer, const struct tile *ptile)
Definition player.c:993
player_can_trust_tile_has_no_units
bool player_can_trust_tile_has_no_units(const struct player *pplayer, const struct tile *ptile)
Definition player.c:967
universal_never_there
bool universal_never_there(const struct universal *source)
Definition requirements.c:5862
req_context_empty
const struct req_context * req_context_empty(void)
Definition requirements.c:1000
req_to_fstring
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
Definition requirements.c:1015
universal_fulfills_requirements
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Definition requirements.c:7262
req_vec_suggest_repair
struct req_vec_problem * req_vec_suggest_repair(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:6267
req_from_values
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Definition requirements.c:1403
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:5505
are_requirements_contradictions
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
Definition requirements.c:1666
req_vec_problem_new
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *descr,...)
Definition requirements.c:6157
does_req_contradicts_reqs
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:1845
req_vec_is_impossible_to_fulfill
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
Definition requirements.c:5957
req_vec_suggest_improvement
struct req_vec_problem * req_vec_suggest_improvement(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Definition requirements.c:6439
requirement_fulfilled_by_unit_type
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition requirements.h:426
req_vec_num_in_item
signed char req_vec_num_in_item
req_vec_num_in_item a requirement vectors number in an item.
Definition requirements.h:237
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_fulfilled_by_government
#define requirement_fulfilled_by_government(_gov_, _rqs_)
Definition requirements.h:409
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:128
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
research_invention_gettable
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:693
research.h
server_setting_by_name
server_setting_id server_setting_by_name(const char *name)
Definition server_settings.c:29
server_setting_value_int_get
int server_setting_value_int_get(server_setting_id id)
Definition server_settings.c:82
server_settings.h
fc_tristate_and
enum fc_tristate fc_tristate_and(enum fc_tristate one, enum fc_tristate two)
Definition shared.c:124
fc_tristate
fc_tristate
Definition shared.h:46
TRI_YES
@ TRI_YES
Definition shared.h:46
TRI_NO
@ TRI_NO
Definition shared.h:46
TRI_MAYBE
@ TRI_MAYBE
Definition shared.h:46
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
specvec.h
size
size_t size
Definition specvec.h:72
act_prob
Definition fc_types.h:1241
act_prob::max
int max
Definition fc_types.h:1243
act_prob::min
int min
Definition fc_types.h:1242
action_auto_perf
Definition actions.h:559
action_auto_perf::cause
enum action_auto_perf_cause cause
Definition actions.h:561
action_auto_perf::alternatives
action_id alternatives[MAX_NUM_ACTIONS]
Definition actions.h:569
action_enabler_contradiction
Definition actions.c:41
action_enabler_contradiction::is_target
bool is_target
Definition actions.c:47
action_enabler_contradiction::req
struct requirement req
Definition actions.c:43
action_enabler
Definition actions.h:419
action_enabler::action
action_id action
Definition actions.h:420
action_enabler::actor_reqs
struct requirement_vector actor_reqs
Definition actions.h:421
action_enabler::target_reqs
struct requirement_vector target_reqs
Definition actions.h:422
action
Definition actions.h:360
action::unitwaittime_controlled
bool unitwaittime_controlled
Definition actions.h:409
action::id
action_id id
Definition actions.h:361
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:393
action::rare_pop_up
bool rare_pop_up
Definition actions.h:406
action::max_distance
int max_distance
Definition actions.h:376
action::quiet
bool quiet
Definition actions.h:383
action::sub_target_kind
enum action_sub_target_kind sub_target_kind
Definition actions.h:368
action::moves_actor
enum moves_actor_kind moves_actor
Definition actions.h:413
action::is_unit
struct action::@12::@13 is_unit
action::result
enum action_result result
Definition actions.h:363
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:379
action::sub_results
bv_action_sub_results sub_results
Definition actions.h:364
action::actor_kind
enum action_actor_kind actor_kind
Definition actions.h:366
action::target_complexity
enum act_tgt_compl target_complexity
Definition actions.h:371
action::blocked_by
bv_actions blocked_by
Definition actions.h:387
action::actor
union action::@12 actor
action::target_kind
enum action_target_kind target_kind
Definition actions.h:367
action::min_distance
int min_distance
Definition actions.h:376
ae_contra_or
Definition actions.c:51
ae_contra_or::alternative
struct action_enabler_contradiction * alternative
Definition actions.c:55
ae_contra_or::alternatives
int alternatives
Definition actions.c:52
ae_contra_or::users
int users
Definition actions.c:58
astring
Definition astring.h:36
city
Definition city.h:320
city::id
int id
Definition city.h:326
city::tile
struct tile * tile
Definition city.h:322
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:88
functions::player_tile_city_id_get
int(* player_tile_city_id_get)(const struct tile *ptile, const struct player *pplayer)
Definition fc_interface.h:52
government
Definition government.h:52
impr_type
Definition improvement.h:50
obligatory_req
Definition actions.c:62
obligatory_req::contras
struct ae_contra_or * contras
Definition actions.c:65
obligatory_req::error_msg
const char * error_msg
Definition actions.c:69
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:211
packet_game_info::airlifting_style
enum airlifting_style airlifting_style
Definition packets_gen.h:119
packet_game_info::airlift_from_always_enabled
bool airlift_from_always_enabled
Definition packets_gen.h:120
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:148
player
Definition player.h:247
req_context
Definition requirements.h:100
req_context::tile
const struct tile * tile
Definition requirements.h:103
req_context::player
const struct player * player
Definition requirements.h:101
req_context::unit
const struct unit * unit
Definition requirements.h:106
req_context::city
const struct city * city
Definition requirements.h:102
req_vec_problem
Definition requirements.h:295
requirement
Definition requirements.h:81
research
Definition research.h:39
tile
Definition tile.h:50
tile::units
struct unit_list * units
Definition tile.h:58
unit_class
Definition unittype.h:149
unit_type
Definition unittype.h:500
unit_type::veteran
struct veteran_system * veteran
Definition unittype.h:544
unit
Definition unit.h:138
unit::moves_left
int moves_left
Definition unit.h:150
unit::tile
struct tile * tile
Definition unit.h:140
unit::paradropped
bool paradropped
Definition unit.h:174
unit::utype
const struct unit_type * utype
Definition unit.h:139
universal
Definition fc_types.h:901
universal::kind
enum universals_n kind
Definition fc_types.h:903
veteran_level
Definition unittype.h:486
world::map
struct civ_map map
Definition world_object.h:38
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc__attribute
#define fc__attribute(x)
Definition support.h:99
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:119
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
advance_iterate
#define advance_iterate(_p)
Definition tech.h:275
advance_iterate_end
#define advance_iterate_end
Definition tech.h:276
tile_is_seen
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:407
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_owner
#define tile_owner(_tile)
Definition tile.h:96
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2437
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:361
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2421
can_unit_unload
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:748
unit_can_convert
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2031
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:390
unit_owner
#define unit_owner(_pu)
Definition unit.h:389
unit_home
#define unit_home(_pu_)
Definition unit.h:387
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
utype_may_act_move_frags
bool utype_may_act_move_frags(const struct unit_type *punit_type, const action_id act_id, const int move_fragments)
Definition unittype.c:1058
utype_veteran_level
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2583
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
utype_can_do_act_if_tgt_citytile
bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:996
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
utype_class
#define utype_class(_t_)
Definition unittype.h:749
L_LAST
#define L_LAST
Definition unittype.h:439
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:852
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:859
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:528