Freeciv-3.3: /fast/freeciv/nightly/main/common/actions.c Source File

Freeciv-3.3

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 "oblig_reqs.h"
34#include "research.h"
35#include "server_settings.h"
36#include "unit.h"
37
38
39/* Values used to interpret action probabilities.
40 *
41 * Action probabilities are sent over the network. A change in a value here
42 * will therefore change the network protocol.
43 *
44 * A change in a value here should also update the action probability
45 * format documentation in fc_types.h */
46/* The lowest possible probability value (0%) */
47#define ACTPROB_VAL_MIN 0
48/* The highest possible probability value (100%) */
49#define ACTPROB_VAL_MAX 200
50/* A probability increase of 1% corresponds to this increase. */
51#define ACTPROB_VAL_1_PCT (ACTPROB_VAL_MAX / 100)
52/* Action probability doesn't apply when min is this. */
53#define ACTPROB_VAL_NA 253
54/* Action probability unsupported when min is this. */
55#define ACTPROB_VAL_NOT_IMPL 254
56
57 static struct action *actions[MAX_NUM_ACTIONS];
58 struct action **_actions = actions;
59 struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS];
60 static bool actions_initialized = FALSE;
61
62 static struct action_enabler_list *action_enablers_by_action[MAX_NUM_ACTIONS];
63
64 static struct astring ui_name_str = ASTRING_INIT;
65
66static struct action *
67 unit_action_new(action_id id,
68 enum action_result result,
69 bool rare_pop_up,
70 bool unitwaittime_controlled,
71 enum moves_actor_kind moves_actor,
72 const int min_distance,
73 const int max_distance,
74 bool actor_consuming_always);
75
76static bool is_enabler_active(const struct action_enabler *enabler,
77 const struct req_context *actor,
78 const struct req_context *target);
79
80static inline bool
81 action_prob_is_signal(const struct act_prob probability);
82static inline bool
83 action_prob_not_relevant(const struct act_prob probability);
84static inline bool
85 action_prob_not_impl(const struct act_prob probability);
86
87static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
88 const struct unit *pvictim,
89 const struct tile *tgt_tile,
90 const struct action *paction)
91 fc__attribute((nonnull(3)));
92
93/* Make sure that an action distance can target the whole map. */
94 FC_STATIC_ASSERT(MAP_DISTANCE_MAX <= ACTION_DISTANCE_LAST_NON_SIGNAL,
95 action_range_can_not_cover_the_whole_map);
96
97 static struct action_list *actlist_by_result[ACTRES_LAST];
98 static struct action_list *actlist_by_activity[ACTIVITY_LAST];
99
100
101/**********************************************************************/
104 static void hard_code_actions(void)
105{
106 actions[ACTION_SPY_POISON] =
107 unit_action_new(ACTION_SPY_POISON, ACTRES_SPY_POISON,
108 FALSE, TRUE,
109 MAK_ESCAPE, 0, 1, TRUE);
110 actions[ACTION_SPY_POISON_ESC] =
111 unit_action_new(ACTION_SPY_POISON_ESC, ACTRES_SPY_POISON,
112 FALSE, TRUE,
113 MAK_ESCAPE, 0, 1, FALSE);
114 actions[ACTION_SPY_SABOTAGE_UNIT] =
115 unit_action_new(ACTION_SPY_SABOTAGE_UNIT, ACTRES_SPY_SABOTAGE_UNIT,
116 FALSE, TRUE,
117 MAK_ESCAPE, 0, 1, TRUE);
118 actions[ACTION_SPY_SABOTAGE_UNIT_ESC] =
119 unit_action_new(ACTION_SPY_SABOTAGE_UNIT_ESC, ACTRES_SPY_SABOTAGE_UNIT,
120 FALSE, TRUE,
121 MAK_ESCAPE, 0, 1, FALSE);
122 actions[ACTION_SPY_BRIBE_UNIT] =
123 unit_action_new(ACTION_SPY_BRIBE_UNIT, ACTRES_SPY_BRIBE_UNIT,
124 FALSE, TRUE,
125 /* Tries a forced move if the target unit is alone at
126 * its tile and not in a city. Takes all movement if
127 * the forced move fails. */
128 MAK_FORCED,
129 0, 1, FALSE);
130 actions[ACTION_SPY_SABOTAGE_CITY] =
131 unit_action_new(ACTION_SPY_SABOTAGE_CITY, ACTRES_SPY_SABOTAGE_CITY,
132 FALSE, TRUE,
133 MAK_ESCAPE, 0, 1, TRUE);
134 actions[ACTION_SPY_SABOTAGE_CITY_ESC] =
135 unit_action_new(ACTION_SPY_SABOTAGE_CITY_ESC, ACTRES_SPY_SABOTAGE_CITY,
136 FALSE, TRUE,
137 MAK_ESCAPE, 0, 1, FALSE);
138 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY] =
139 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY,
140 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
141 FALSE, TRUE,
142 MAK_ESCAPE, 0, 1, TRUE);
143 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION] =
144 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION,
145 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
146 FALSE, TRUE,
147 MAK_ESCAPE, 0, 1, TRUE);
148 actions[ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
149 unit_action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC,
150 ACTRES_SPY_TARGETED_SABOTAGE_CITY,
151 FALSE, TRUE,
152 MAK_ESCAPE, 0, 1, FALSE);
153 actions[ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC] =
154 unit_action_new(ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC,
155 ACTRES_SPY_SABOTAGE_CITY_PRODUCTION,
156 FALSE, TRUE,
157 MAK_ESCAPE, 0, 1, FALSE);
158 actions[ACTION_SPY_INCITE_CITY] =
159 unit_action_new(ACTION_SPY_INCITE_CITY, ACTRES_SPY_INCITE_CITY,
160 FALSE, TRUE,
161 MAK_ESCAPE, 0, 1, TRUE);
162 actions[ACTION_SPY_INCITE_CITY_ESC] =
163 unit_action_new(ACTION_SPY_INCITE_CITY_ESC, ACTRES_SPY_INCITE_CITY,
164 FALSE, TRUE,
165 MAK_ESCAPE, 0, 1, FALSE);
166 actions[ACTION_ESTABLISH_EMBASSY] =
167 unit_action_new(ACTION_ESTABLISH_EMBASSY,
168 ACTRES_ESTABLISH_EMBASSY,
169 FALSE, TRUE,
170 MAK_STAYS, 0, 1, FALSE);
171 actions[ACTION_ESTABLISH_EMBASSY_STAY] =
172 unit_action_new(ACTION_ESTABLISH_EMBASSY_STAY,
173 ACTRES_ESTABLISH_EMBASSY,
174 FALSE, TRUE,
175 MAK_STAYS, 0, 1, TRUE);
176 actions[ACTION_SPY_STEAL_TECH] =
177 unit_action_new(ACTION_SPY_STEAL_TECH,
178 ACTRES_SPY_STEAL_TECH,
179 FALSE, TRUE,
180 MAK_ESCAPE, 0, 1, TRUE);
181 actions[ACTION_SPY_STEAL_TECH_ESC] =
182 unit_action_new(ACTION_SPY_STEAL_TECH_ESC,
183 ACTRES_SPY_STEAL_TECH,
184 FALSE, TRUE,
185 MAK_ESCAPE, 0, 1, FALSE);
186 actions[ACTION_SPY_TARGETED_STEAL_TECH] =
187 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH,
188 ACTRES_SPY_TARGETED_STEAL_TECH,
189 FALSE, TRUE,
190 MAK_ESCAPE, 0, 1, TRUE);
191 actions[ACTION_SPY_TARGETED_STEAL_TECH_ESC] =
192 unit_action_new(ACTION_SPY_TARGETED_STEAL_TECH_ESC,
193 ACTRES_SPY_TARGETED_STEAL_TECH,
194 FALSE, TRUE,
195 MAK_ESCAPE, 0, 1, FALSE);
196 actions[ACTION_SPY_INVESTIGATE_CITY] =
197 unit_action_new(ACTION_SPY_INVESTIGATE_CITY,
198 ACTRES_SPY_INVESTIGATE_CITY,
199 FALSE, TRUE,
200 MAK_STAYS, 0, 1, FALSE);
201 actions[ACTION_INV_CITY_SPEND] =
202 unit_action_new(ACTION_INV_CITY_SPEND,
203 ACTRES_SPY_INVESTIGATE_CITY,
204 FALSE, TRUE,
205 MAK_STAYS, 0, 1, TRUE);
206 actions[ACTION_SPY_STEAL_GOLD] =
207 unit_action_new(ACTION_SPY_STEAL_GOLD,
208 ACTRES_SPY_STEAL_GOLD,
209 FALSE, TRUE,
210 MAK_ESCAPE, 0, 1, TRUE);
211 actions[ACTION_SPY_STEAL_GOLD_ESC] =
212 unit_action_new(ACTION_SPY_STEAL_GOLD_ESC,
213 ACTRES_SPY_STEAL_GOLD,
214 FALSE, TRUE,
215 MAK_ESCAPE, 0, 1, FALSE);
216 actions[ACTION_SPY_SPREAD_PLAGUE] =
217 unit_action_new(ACTION_SPY_SPREAD_PLAGUE,
218 ACTRES_SPY_SPREAD_PLAGUE,
219 FALSE, TRUE,
220 MAK_ESCAPE, 0, 1, FALSE);
221 actions[ACTION_SPY_ESCAPE] =
222 unit_action_new(ACTION_SPY_ESCAPE,
223 ACTRES_SPY_ESCAPE,
224 FALSE, TRUE,
225 MAK_ESCAPE, 0, 1, FALSE);
226 actions[ACTION_TRADE_ROUTE] =
227 unit_action_new(ACTION_TRADE_ROUTE, ACTRES_TRADE_ROUTE,
228 FALSE, TRUE,
229 MAK_STAYS, 0, 1, TRUE);
230 actions[ACTION_MARKETPLACE] =
231 unit_action_new(ACTION_MARKETPLACE, ACTRES_MARKETPLACE,
232 FALSE, TRUE,
233 MAK_STAYS, 0, 1, TRUE);
234 actions[ACTION_HELP_WONDER] =
235 unit_action_new(ACTION_HELP_WONDER, ACTRES_HELP_WONDER,
236 FALSE, TRUE,
237 MAK_STAYS, 0, 1, TRUE);
238 actions[ACTION_CAPTURE_UNITS] =
239 unit_action_new(ACTION_CAPTURE_UNITS, ACTRES_CAPTURE_UNITS,
240 FALSE, TRUE, MAK_STAYS,
241 /* A single domestic unit at the target tile will make
242 * the action illegal. It must therefore be performed
243 * from another tile. */
244 1, 1,
245 FALSE);
246 actions[ACTION_FOUND_CITY] =
247 unit_action_new(ACTION_FOUND_CITY, ACTRES_FOUND_CITY,
248 TRUE, TRUE, MAK_STAYS,
249 /* Illegal to perform to a target on another tile.
250 * Reason: The Freeciv code assumes that the city
251 * founding unit is located at the tile were the new
252 * city is founded. */
253 0, 0,
254 TRUE);
255 actions[ACTION_JOIN_CITY] =
256 unit_action_new(ACTION_JOIN_CITY, ACTRES_JOIN_CITY,
257 TRUE, TRUE,
258 MAK_STAYS, 0, 1, TRUE);
259 actions[ACTION_STEAL_MAPS] =
260 unit_action_new(ACTION_STEAL_MAPS, ACTRES_STEAL_MAPS,
261 FALSE, TRUE,
262 MAK_ESCAPE, 0, 1, TRUE);
263 actions[ACTION_STEAL_MAPS_ESC] =
264 unit_action_new(ACTION_STEAL_MAPS_ESC, ACTRES_STEAL_MAPS,
265 FALSE, TRUE,
266 MAK_ESCAPE, 0, 1, FALSE);
267 actions[ACTION_BOMBARD] =
268 unit_action_new(ACTION_BOMBARD, ACTRES_BOMBARD,
269 FALSE, TRUE, MAK_STAYS,
270 /* A single domestic unit at the target tile will make
271 * the action illegal. It must therefore be performed
272 * from another tile. */
273 1,
274 /* Overwritten by the ruleset's bombard_max_range */
275 1,
276 FALSE);
277 actions[ACTION_BOMBARD2] =
278 unit_action_new(ACTION_BOMBARD2, ACTRES_BOMBARD,
279 FALSE, TRUE,
280 MAK_STAYS,
281 /* A single domestic unit at the target tile will make
282 * the action illegal. It must therefore be performed
283 * from another tile. */
284 1,
285 /* Overwritten by the ruleset's bombard_2_max_range */
286 1,
287 FALSE);
288 actions[ACTION_BOMBARD3] =
289 unit_action_new(ACTION_BOMBARD3, ACTRES_BOMBARD,
290 FALSE, TRUE, MAK_STAYS,
291 /* A single domestic unit at the target tile will make
292 * the action illegal. It must therefore be performed
293 * from another tile. */
294 1,
295 /* Overwritten by the ruleset's bombard_3_max_range */
296 1,
297 FALSE);
298 actions[ACTION_BOMBARD4] =
299 unit_action_new(ACTION_BOMBARD4, ACTRES_BOMBARD,
300 FALSE, TRUE, MAK_STAYS,
301 /* A single domestic unit at the target tile will make
302 * the action illegal. It must therefore be performed
303 * from another tile. */
304 1,
305 /* Overwritten by the ruleset's bombard_4_max_range */
306 1,
307 FALSE);
308 actions[ACTION_BOMBARD_LETHAL] =
309 unit_action_new(ACTION_BOMBARD_LETHAL, ACTRES_BOMBARD,
310 FALSE, TRUE, MAK_STAYS,
311 /* A single domestic unit at the target tile will make
312 * the action illegal. It must therefore be performed
313 * from another tile. */
314 1,
315 /* Overwritten by the ruleset's bombard_lethal_max_range */
316 1,
317 FALSE);
318 actions[ACTION_BOMBARD_LETHAL2] =
319 unit_action_new(ACTION_BOMBARD_LETHAL2, ACTRES_BOMBARD,
320 FALSE, TRUE, MAK_STAYS,
321 /* A single domestic unit at the target tile will make
322 * the action illegal. It must therefore be performed
323 * from another tile. */
324 1,
325 /* Overwritten by the ruleset's bombard_lethal_2_max_range */
326 1,
327 FALSE);
328 actions[ACTION_SPY_NUKE] =
329 unit_action_new(ACTION_SPY_NUKE, ACTRES_SPY_NUKE,
330 FALSE, TRUE,
331 MAK_ESCAPE, 0, 1, TRUE);
332 actions[ACTION_SPY_NUKE_ESC] =
333 unit_action_new(ACTION_SPY_NUKE_ESC, ACTRES_SPY_NUKE,
334 FALSE, TRUE,
335 MAK_ESCAPE, 0, 1, FALSE);
336 actions[ACTION_NUKE] =
337 unit_action_new(ACTION_NUKE, ACTRES_NUKE,
338 TRUE, TRUE,
339 MAK_STAYS, 0,
340 /* Overwritten by the ruleset's
341 * explode_nuclear_max_range */
342 0,
343 TRUE);
344 actions[ACTION_NUKE_CITY] =
345 unit_action_new(ACTION_NUKE_CITY, ACTRES_NUKE,
346 TRUE, TRUE,
347 MAK_STAYS, 1, 1, TRUE);
348 actions[ACTION_NUKE_UNITS] =
349 unit_action_new(ACTION_NUKE_UNITS, ACTRES_NUKE_UNITS,
350 TRUE, TRUE,
351 MAK_STAYS, 1, 1, TRUE);
352 actions[ACTION_DESTROY_CITY] =
353 unit_action_new(ACTION_DESTROY_CITY, ACTRES_DESTROY_CITY,
354 TRUE, TRUE,
355 MAK_STAYS, 0, 1, FALSE);
356 actions[ACTION_EXPEL_UNIT] =
357 unit_action_new(ACTION_EXPEL_UNIT, ACTRES_EXPEL_UNIT,
358 FALSE, TRUE,
359 MAK_STAYS, 0, 1, FALSE);
360 actions[ACTION_DISBAND_UNIT_RECOVER] =
361 unit_action_new(ACTION_DISBAND_UNIT_RECOVER, ACTRES_DISBAND_UNIT_RECOVER,
362 TRUE, TRUE, MAK_STAYS,
363 /* Illegal to perform to a target on another tile to
364 * keep the rules exactly as they were for now. */
365 0, 1,
366 TRUE);
367 actions[ACTION_DISBAND_UNIT] =
368 unit_action_new(ACTION_DISBAND_UNIT,
369 /* Can't be ACTRES_NONE because
370 * action_success_actor_consume() sets unit lost
371 * reason based on action result. */
372 ACTRES_DISBAND_UNIT,
373 TRUE, TRUE,
374 MAK_STAYS, 0, 0, TRUE);
375 actions[ACTION_HOME_CITY] =
376 unit_action_new(ACTION_HOME_CITY, ACTRES_HOME_CITY,
377 TRUE, FALSE,
378 /* Illegal to perform to a target on another tile to
379 * keep the rules exactly as they were for now. */
380 MAK_STAYS, 0, 0, FALSE);
381 actions[ACTION_HOMELESS] =
382 unit_action_new(ACTION_HOMELESS, ACTRES_HOMELESS,
383 TRUE, FALSE,
384 MAK_STAYS, 0, 0, FALSE);
385 actions[ACTION_UPGRADE_UNIT] =
386 unit_action_new(ACTION_UPGRADE_UNIT, ACTRES_UPGRADE_UNIT,
387 TRUE, TRUE, MAK_STAYS,
388 /* Illegal to perform to a target on another tile to
389 * keep the rules exactly as they were for now. */
390 0, 0,
391 FALSE);
392 actions[ACTION_PARADROP] =
393 unit_action_new(ACTION_PARADROP, ACTRES_PARADROP,
394 TRUE, TRUE,
395 MAK_TELEPORT,
396 1,
397 /* Still limited by each unit type's
398 * paratroopers_range field. */
399 ACTION_DISTANCE_MAX,
400 FALSE);
401 actions[ACTION_PARADROP_CONQUER] =
402 unit_action_new(ACTION_PARADROP_CONQUER, ACTRES_PARADROP_CONQUER,
403 TRUE, TRUE,
404 MAK_TELEPORT,
405 1,
406 /* Still limited by each unit type's
407 * paratroopers_range field. */
408 ACTION_DISTANCE_MAX,
409 FALSE);
410 actions[ACTION_PARADROP_FRIGHTEN] =
411 unit_action_new(ACTION_PARADROP_FRIGHTEN, ACTRES_PARADROP,
412 TRUE, TRUE,
413 MAK_TELEPORT,
414 1,
415 /* Still limited by each unit type's
416 * paratroopers_range field. */
417 ACTION_DISTANCE_MAX,
418 FALSE);
419 actions[ACTION_PARADROP_FRIGHTEN_CONQUER] =
420 unit_action_new(ACTION_PARADROP_FRIGHTEN_CONQUER,
421 ACTRES_PARADROP_CONQUER,
422 TRUE, TRUE,
423 MAK_TELEPORT,
424 1,
425 /* Still limited by each unit type's
426 * paratroopers_range field. */
427 ACTION_DISTANCE_MAX,
428 FALSE);
429 actions[ACTION_PARADROP_ENTER] =
430 unit_action_new(ACTION_PARADROP_ENTER, ACTRES_PARADROP,
431 TRUE, TRUE,
432 MAK_TELEPORT,
433 1,
434 /* Still limited by each unit type's
435 * paratroopers_range field. */
436 ACTION_DISTANCE_MAX,
437 FALSE);
438 actions[ACTION_PARADROP_ENTER_CONQUER] =
439 unit_action_new(ACTION_PARADROP_ENTER_CONQUER,
440 ACTRES_PARADROP_CONQUER,
441 TRUE, TRUE,
442 MAK_TELEPORT,
443 1,
444 /* Still limited by each unit type's
445 * paratroopers_range field. */
446 ACTION_DISTANCE_MAX,
447 FALSE);
448 actions[ACTION_AIRLIFT] =
449 unit_action_new(ACTION_AIRLIFT, ACTRES_AIRLIFT,
450 TRUE, TRUE,
451 MAK_TELEPORT,
452 1,
453 /* Overwritten by the ruleset's airlift_max_range. */
454 ACTION_DISTANCE_UNLIMITED,
455 FALSE);
456 actions[ACTION_ATTACK] =
457 unit_action_new(ACTION_ATTACK, ACTRES_ATTACK,
458 FALSE, TRUE,
459 /* Tries a forced move if the target unit's tile has
460 * no non-allied units and the occupychance dice roll
461 * tells it to move. */
462 MAK_FORCED,
463 1, 1, FALSE);
464 actions[ACTION_ATTACK2] =
465 unit_action_new(ACTION_ATTACK2, ACTRES_ATTACK,
466 FALSE, TRUE,
467 /* Tries a forced move if the target unit's tile has
468 * no non-allied units and the occupychance dice roll
469 * tells it to move. */
470 MAK_FORCED,
471 1, 1, FALSE);
472 actions[ACTION_SUICIDE_ATTACK] =
473 unit_action_new(ACTION_SUICIDE_ATTACK, ACTRES_ATTACK,
474 FALSE, TRUE,
475 MAK_FORCED, 1, 1, TRUE);
476 actions[ACTION_SUICIDE_ATTACK2] =
477 unit_action_new(ACTION_SUICIDE_ATTACK2, ACTRES_ATTACK,
478 FALSE, TRUE,
479 MAK_FORCED, 1, 1, TRUE);
480 actions[ACTION_WIPE_UNITS] =
481 unit_action_new(ACTION_WIPE_UNITS, ACTRES_WIPE_UNITS,
482 FALSE, TRUE,
483 MAK_FORCED,
484 1, 1, FALSE);
485 actions[ACTION_STRIKE_BUILDING] =
486 unit_action_new(ACTION_STRIKE_BUILDING, ACTRES_STRIKE_BUILDING,
487 FALSE, FALSE,
488 MAK_STAYS, 1, 1, FALSE);
489 actions[ACTION_STRIKE_PRODUCTION] =
490 unit_action_new(ACTION_STRIKE_PRODUCTION, ACTRES_STRIKE_PRODUCTION,
491 FALSE, FALSE,
492 MAK_STAYS, 1, 1, FALSE);
493 actions[ACTION_CONQUER_CITY] =
494 unit_action_new(ACTION_CONQUER_CITY, ACTRES_CONQUER_CITY,
495 FALSE, TRUE,
496 MAK_REGULAR, 1, 1, FALSE);
497 actions[ACTION_CONQUER_CITY2] =
498 unit_action_new(ACTION_CONQUER_CITY2, ACTRES_CONQUER_CITY,
499 FALSE, TRUE,
500 MAK_REGULAR, 1, 1, FALSE);
501 actions[ACTION_CONQUER_CITY3] =
502 unit_action_new(ACTION_CONQUER_CITY3, ACTRES_CONQUER_CITY,
503 FALSE, TRUE,
504 MAK_REGULAR, 1, 1, FALSE);
505 actions[ACTION_CONQUER_CITY4] =
506 unit_action_new(ACTION_CONQUER_CITY4, ACTRES_CONQUER_CITY,
507 FALSE, TRUE,
508 MAK_REGULAR, 1, 1, FALSE);
509 actions[ACTION_CONQUER_EXTRAS] =
510 unit_action_new(ACTION_CONQUER_EXTRAS, ACTRES_CONQUER_EXTRAS,
511 FALSE, TRUE,
512 MAK_REGULAR, 1, 1, FALSE);
513 actions[ACTION_CONQUER_EXTRAS2] =
514 unit_action_new(ACTION_CONQUER_EXTRAS2, ACTRES_CONQUER_EXTRAS,
515 FALSE, TRUE,
516 MAK_REGULAR, 1, 1, FALSE);
517 actions[ACTION_CONQUER_EXTRAS3] =
518 unit_action_new(ACTION_CONQUER_EXTRAS3, ACTRES_CONQUER_EXTRAS,
519 FALSE, TRUE,
520 MAK_REGULAR, 1, 1, FALSE);
521 actions[ACTION_CONQUER_EXTRAS4] =
522 unit_action_new(ACTION_CONQUER_EXTRAS4, ACTRES_CONQUER_EXTRAS,
523 FALSE, TRUE,
524 MAK_REGULAR, 1, 1, FALSE);
525 actions[ACTION_HEAL_UNIT] =
526 unit_action_new(ACTION_HEAL_UNIT, ACTRES_HEAL_UNIT,
527 FALSE, TRUE,
528 MAK_STAYS, 0, 1, FALSE);
529 actions[ACTION_HEAL_UNIT2] =
530 unit_action_new(ACTION_HEAL_UNIT2, ACTRES_HEAL_UNIT,
531 FALSE, TRUE,
532 MAK_STAYS, 0, 1, FALSE);
533 actions[ACTION_TRANSFORM_TERRAIN] =
534 unit_action_new(ACTION_TRANSFORM_TERRAIN, ACTRES_TRANSFORM_TERRAIN,
535 TRUE, FALSE,
536 MAK_STAYS, 0, 0, FALSE);
537 actions[ACTION_TRANSFORM_TERRAIN2] =
538 unit_action_new(ACTION_TRANSFORM_TERRAIN2, ACTRES_TRANSFORM_TERRAIN,
539 TRUE, FALSE,
540 MAK_STAYS, 0, 0, FALSE);
541 actions[ACTION_CULTIVATE] =
542 unit_action_new(ACTION_CULTIVATE, ACTRES_CULTIVATE,
543 TRUE, FALSE,
544 MAK_STAYS, 0, 0, FALSE);
545 actions[ACTION_CULTIVATE2] =
546 unit_action_new(ACTION_CULTIVATE2, ACTRES_CULTIVATE,
547 TRUE, FALSE,
548 MAK_STAYS, 0, 0, FALSE);
549 actions[ACTION_PLANT] =
550 unit_action_new(ACTION_PLANT, ACTRES_PLANT,
551 TRUE, FALSE,
552 MAK_STAYS, 0, 0, FALSE);
553 actions[ACTION_PLANT2] =
554 unit_action_new(ACTION_PLANT2, ACTRES_PLANT,
555 TRUE, FALSE,
556 MAK_STAYS, 0, 0, FALSE);
557 actions[ACTION_PILLAGE] =
558 unit_action_new(ACTION_PILLAGE, ACTRES_PILLAGE,
559 TRUE, FALSE,
560 MAK_STAYS, 0, 0, FALSE);
561 actions[ACTION_PILLAGE2] =
562 unit_action_new(ACTION_PILLAGE2, ACTRES_PILLAGE,
563 TRUE, FALSE,
564 MAK_STAYS, 0, 0, FALSE);
565 actions[ACTION_CLEAN] =
566 unit_action_new(ACTION_CLEAN, ACTRES_CLEAN,
567 TRUE, FALSE,
568 MAK_STAYS, 0, 0, FALSE);
569 actions[ACTION_CLEAN2] =
570 unit_action_new(ACTION_CLEAN2, ACTRES_CLEAN,
571 TRUE, FALSE,
572 MAK_STAYS, 0, 0, FALSE);
573 actions[ACTION_FORTIFY] =
574 unit_action_new(ACTION_FORTIFY, ACTRES_FORTIFY,
575 TRUE, FALSE,
576 MAK_STAYS, 0, 0, FALSE);
577 actions[ACTION_FORTIFY2] =
578 unit_action_new(ACTION_FORTIFY2, ACTRES_FORTIFY,
579 TRUE, FALSE,
580 MAK_STAYS, 0, 0, FALSE);
581 actions[ACTION_ROAD] =
582 unit_action_new(ACTION_ROAD, ACTRES_ROAD,
583 TRUE, FALSE,
584 MAK_STAYS, 0, 0, FALSE);
585 actions[ACTION_ROAD2] =
586 unit_action_new(ACTION_ROAD2, ACTRES_ROAD,
587 TRUE, FALSE,
588 MAK_STAYS, 0, 0, FALSE);
589 actions[ACTION_CONVERT] =
590 unit_action_new(ACTION_CONVERT, ACTRES_CONVERT,
591 TRUE, FALSE,
592 MAK_STAYS, 0, 0, FALSE);
593 actions[ACTION_BASE] =
594 unit_action_new(ACTION_BASE, ACTRES_BASE,
595 TRUE, FALSE,
596 MAK_STAYS, 0, 0, FALSE);
597 actions[ACTION_BASE2] =
598 unit_action_new(ACTION_BASE2, ACTRES_BASE,
599 TRUE, FALSE,
600 MAK_STAYS, 0, 0, FALSE);
601 actions[ACTION_MINE] =
602 unit_action_new(ACTION_MINE, ACTRES_MINE,
603 TRUE, FALSE,
604 MAK_STAYS, 0, 0, FALSE);
605 actions[ACTION_MINE2] =
606 unit_action_new(ACTION_MINE2, ACTRES_MINE,
607 TRUE, FALSE,
608 MAK_STAYS, 0, 0, FALSE);
609 actions[ACTION_IRRIGATE] =
610 unit_action_new(ACTION_IRRIGATE, ACTRES_IRRIGATE,
611 TRUE, FALSE,
612 MAK_STAYS, 0, 0, FALSE);
613 actions[ACTION_IRRIGATE2] =
614 unit_action_new(ACTION_IRRIGATE2, ACTRES_IRRIGATE,
615 TRUE, FALSE,
616 MAK_STAYS, 0, 0, FALSE);
617 actions[ACTION_TRANSPORT_DEBOARD] =
618 unit_action_new(ACTION_TRANSPORT_DEBOARD, ACTRES_TRANSPORT_DEBOARD,
619 TRUE, FALSE,
620 MAK_STAYS, 0, 0, FALSE);
621 actions[ACTION_TRANSPORT_BOARD] =
622 unit_action_new(ACTION_TRANSPORT_BOARD, ACTRES_TRANSPORT_BOARD,
623 TRUE, FALSE,
624 MAK_STAYS, 0, 0, FALSE);
625 actions[ACTION_TRANSPORT_BOARD2] =
626 unit_action_new(ACTION_TRANSPORT_BOARD2, ACTRES_TRANSPORT_BOARD,
627 TRUE, FALSE,
628 MAK_STAYS, 0, 0, FALSE);
629 actions[ACTION_TRANSPORT_BOARD3] =
630 unit_action_new(ACTION_TRANSPORT_BOARD3, ACTRES_TRANSPORT_BOARD,
631 TRUE, FALSE,
632 MAK_STAYS, 0, 0, FALSE);
633 actions[ACTION_TRANSPORT_UNLOAD] =
634 unit_action_new(ACTION_TRANSPORT_UNLOAD, ACTRES_TRANSPORT_UNLOAD,
635 TRUE, FALSE,
636 MAK_STAYS, 0, 0, FALSE);
637 actions[ACTION_TRANSPORT_LOAD] =
638 unit_action_new(ACTION_TRANSPORT_LOAD, ACTRES_TRANSPORT_LOAD,
639 TRUE, FALSE,
640 MAK_STAYS, 0, 0, FALSE);
641 actions[ACTION_TRANSPORT_LOAD2] =
642 unit_action_new(ACTION_TRANSPORT_LOAD2, ACTRES_TRANSPORT_LOAD,
643 TRUE, FALSE,
644 MAK_STAYS, 0, 0, FALSE);
645 actions[ACTION_TRANSPORT_LOAD3] =
646 unit_action_new(ACTION_TRANSPORT_LOAD3, ACTRES_TRANSPORT_LOAD,
647 TRUE, FALSE,
648 MAK_STAYS, 0, 0, FALSE);
649 actions[ACTION_TRANSPORT_DISEMBARK1] =
650 unit_action_new(ACTION_TRANSPORT_DISEMBARK1,
651 ACTRES_TRANSPORT_DISEMBARK,
652 FALSE, TRUE,
653 MAK_REGULAR, 1, 1, FALSE);
654 actions[ACTION_TRANSPORT_DISEMBARK2] =
655 unit_action_new(ACTION_TRANSPORT_DISEMBARK2,
656 ACTRES_TRANSPORT_DISEMBARK,
657 FALSE, TRUE,
658 MAK_REGULAR, 1, 1, FALSE);
659 actions[ACTION_TRANSPORT_DISEMBARK3] =
660 unit_action_new(ACTION_TRANSPORT_DISEMBARK3,
661 ACTRES_TRANSPORT_DISEMBARK,
662 FALSE, TRUE,
663 MAK_REGULAR, 1, 1, FALSE);
664 actions[ACTION_TRANSPORT_DISEMBARK4] =
665 unit_action_new(ACTION_TRANSPORT_DISEMBARK4,
666 ACTRES_TRANSPORT_DISEMBARK,
667 FALSE, TRUE,
668 MAK_REGULAR, 1, 1, FALSE);
669 actions[ACTION_TRANSPORT_EMBARK] =
670 unit_action_new(ACTION_TRANSPORT_EMBARK, ACTRES_TRANSPORT_EMBARK,
671 TRUE, TRUE,
672 MAK_REGULAR, 1, 1, FALSE);
673 actions[ACTION_TRANSPORT_EMBARK2] =
674 unit_action_new(ACTION_TRANSPORT_EMBARK2, ACTRES_TRANSPORT_EMBARK,
675 TRUE, TRUE,
676 MAK_REGULAR, 1, 1, FALSE);
677 actions[ACTION_TRANSPORT_EMBARK3] =
678 unit_action_new(ACTION_TRANSPORT_EMBARK3, ACTRES_TRANSPORT_EMBARK,
679 TRUE, TRUE,
680 MAK_REGULAR, 1, 1, FALSE);
681 actions[ACTION_TRANSPORT_EMBARK4] =
682 unit_action_new(ACTION_TRANSPORT_EMBARK4, ACTRES_TRANSPORT_EMBARK,
683 TRUE, TRUE,
684 MAK_REGULAR, 1, 1, FALSE);
685 actions[ACTION_SPY_ATTACK] =
686 unit_action_new(ACTION_SPY_ATTACK, ACTRES_SPY_ATTACK,
687 FALSE, TRUE,
688 MAK_STAYS, 1, 1, FALSE);
689 actions[ACTION_HUT_ENTER] =
690 unit_action_new(ACTION_HUT_ENTER, ACTRES_HUT_ENTER,
691 FALSE, TRUE,
692 MAK_REGULAR, 1, 1, FALSE);
693 actions[ACTION_HUT_ENTER2] =
694 unit_action_new(ACTION_HUT_ENTER2, ACTRES_HUT_ENTER,
695 FALSE, TRUE,
696 MAK_REGULAR, 1, 1, FALSE);
697 actions[ACTION_HUT_ENTER3] =
698 unit_action_new(ACTION_HUT_ENTER3, ACTRES_HUT_ENTER,
699 FALSE, TRUE,
700 MAK_REGULAR, 1, 1, FALSE);
701 actions[ACTION_HUT_ENTER4] =
702 unit_action_new(ACTION_HUT_ENTER4, ACTRES_HUT_ENTER,
703 FALSE, TRUE,
704 MAK_REGULAR, 1, 1, FALSE);
705 actions[ACTION_HUT_FRIGHTEN] =
706 unit_action_new(ACTION_HUT_FRIGHTEN, ACTRES_HUT_FRIGHTEN,
707 FALSE, TRUE,
708 MAK_REGULAR, 1, 1, FALSE);
709 actions[ACTION_HUT_FRIGHTEN2] =
710 unit_action_new(ACTION_HUT_FRIGHTEN2, ACTRES_HUT_FRIGHTEN,
711 FALSE, TRUE,
712 MAK_REGULAR, 1, 1, FALSE);
713 actions[ACTION_HUT_FRIGHTEN3] =
714 unit_action_new(ACTION_HUT_FRIGHTEN3, ACTRES_HUT_FRIGHTEN,
715 FALSE, TRUE,
716 MAK_REGULAR, 1, 1, FALSE);
717 actions[ACTION_HUT_FRIGHTEN4] =
718 unit_action_new(ACTION_HUT_FRIGHTEN4, ACTRES_HUT_FRIGHTEN,
719 FALSE, TRUE,
720 MAK_REGULAR, 1, 1, FALSE);
721 actions[ACTION_UNIT_MOVE] =
722 unit_action_new(ACTION_UNIT_MOVE, ACTRES_UNIT_MOVE,
723 TRUE, TRUE,
724 MAK_REGULAR, 1, 1, FALSE);
725 actions[ACTION_UNIT_MOVE2] =
726 unit_action_new(ACTION_UNIT_MOVE2, ACTRES_UNIT_MOVE,
727 TRUE, TRUE,
728 MAK_REGULAR, 1, 1, FALSE);
729 actions[ACTION_UNIT_MOVE3] =
730 unit_action_new(ACTION_UNIT_MOVE3, ACTRES_UNIT_MOVE,
731 TRUE, TRUE,
732 MAK_REGULAR, 1, 1, FALSE);
733 actions[ACTION_TELEPORT] =
734 unit_action_new(ACTION_TELEPORT, ACTRES_TELEPORT,
735 TRUE, TRUE,
736 MAK_TELEPORT, 1, 1, FALSE);
737 actions[ACTION_TELEPORT2] =
738 unit_action_new(ACTION_TELEPORT2, ACTRES_TELEPORT,
739 TRUE, TRUE,
740 MAK_TELEPORT, 1, 1, FALSE);
741 actions[ACTION_TELEPORT3] =
742 unit_action_new(ACTION_TELEPORT3, ACTRES_TELEPORT,
743 TRUE, TRUE,
744 MAK_TELEPORT, 1, 1, FALSE);
745 actions[ACTION_TELEPORT_CONQUER] =
746 unit_action_new(ACTION_TELEPORT_CONQUER, ACTRES_TELEPORT_CONQUER,
747 TRUE, TRUE,
748 MAK_TELEPORT, 1,
749 ACTION_DISTANCE_MAX, FALSE);
750 actions[ACTION_TELEPORT_FRIGHTEN] =
751 unit_action_new(ACTION_TELEPORT_FRIGHTEN,
752 ACTRES_TELEPORT,
753 TRUE, TRUE,
754 MAK_TELEPORT, 1,
755 ACTION_DISTANCE_MAX, FALSE);
756 actions[ACTION_TELEPORT_FRIGHTEN_CONQUER] =
757 unit_action_new(ACTION_TELEPORT_FRIGHTEN_CONQUER,
758 ACTRES_TELEPORT_CONQUER,
759 TRUE, TRUE,
760 MAK_TELEPORT, 1,
761 ACTION_DISTANCE_MAX, FALSE);
762 actions[ACTION_TELEPORT_ENTER] =
763 unit_action_new(ACTION_TELEPORT_ENTER,
764 ACTRES_TELEPORT,
765 TRUE, TRUE,
766 MAK_TELEPORT, 1,
767 ACTION_DISTANCE_MAX, FALSE);
768 actions[ACTION_TELEPORT_ENTER_CONQUER] =
769 unit_action_new(ACTION_TELEPORT_ENTER_CONQUER,
770 ACTRES_TELEPORT_CONQUER,
771 TRUE, TRUE,
772 MAK_TELEPORT, 1,
773 ACTION_DISTANCE_MAX, FALSE);
774 actions[ACTION_GAIN_VETERANCY] =
775 unit_action_new(ACTION_GAIN_VETERANCY, ACTRES_ENABLER_CHECK,
776 TRUE, FALSE,
777 MAK_STAYS, 0, 0, FALSE);
778 actions[ACTION_ESCAPE] =
779 unit_action_new(ACTION_ESCAPE, ACTRES_ENABLER_CHECK,
780 TRUE, FALSE,
781 MAK_STAYS, 0, 0, FALSE);
782 actions[ACTION_USER_ACTION1] =
783 unit_action_new(ACTION_USER_ACTION1, ACTRES_NONE,
784 FALSE, TRUE,
785 MAK_UNREPRESENTABLE,
786 /* Overwritten by the ruleset */
787 0, 1, FALSE);
788 actions[ACTION_USER_ACTION2] =
789 unit_action_new(ACTION_USER_ACTION2, ACTRES_NONE,
790 FALSE, TRUE,
791 MAK_UNREPRESENTABLE,
792 /* Overwritten by the ruleset */
793 0, 1, FALSE);
794 actions[ACTION_USER_ACTION3] =
795 unit_action_new(ACTION_USER_ACTION3, ACTRES_NONE,
796 FALSE, TRUE,
797 MAK_UNREPRESENTABLE,
798 /* Overwritten by the ruleset */
799 0, 1, FALSE);
800 actions[ACTION_USER_ACTION4] =
801 unit_action_new(ACTION_USER_ACTION4, ACTRES_NONE,
802 FALSE, TRUE,
803 MAK_UNREPRESENTABLE,
804 /* Overwritten by the ruleset */
805 0, 1, FALSE);
806 actions[ACTION_COLLECT_RANSOM] =
807 unit_action_new(ACTION_COLLECT_RANSOM, ACTRES_COLLECT_RANSOM,
808 FALSE, TRUE,
809 /* Tries a forced move if the target unit's tile has
810 * no non-allied units and the occupychance dice roll
811 * tells it to move. */
812 MAK_FORCED,
813 1, 1, FALSE);
814
815 /* The structure even for these need to be created, for
816 * the action_id_rule_name() to work on iterations. */
817
818 /*
819 actions[ACTION_UNUSED_1]
820 = unit_action_new(ACTION_UNUSED_1, ACTRES_NONE,
821 FALSE, FALSE,
822 MAK_UNREPRESENTABLE,
823 0, 0, FALSE);
824 */
825}
826
827/**********************************************************************/
830 void actions_init(void)
831{
832 int i, j;
833
834 for (i = 0; i < ACTRES_LAST; i++) {
835 actlist_by_result[i] = action_list_new();
836 }
837 for (i = 0; i < ACTIVITY_LAST; i++) {
838 actlist_by_activity[i] = action_list_new();
839 }
840
841 /* Hard code the actions */
842 hard_code_actions();
843
844 /* Initialize the action enabler list */
845 action_iterate_all(act) {
846 action_enablers_by_action[act] = action_enabler_list_new();
847 } action_iterate_all_end;
848
849 /* Initialize action obligatory hard requirements. */
850 oblig_hard_reqs_init();
851
852 /* Obligatory hard requirements are sorted by requirement in the source
853 * code. This makes it easy to read, modify and explain it. */
854 hard_code_oblig_hard_reqs();
855
856 /* Initialize the action auto performers. */
857 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
858 /* Nothing here. Nothing after this point. */
859 auto_perfs[i].cause = AAPC_COUNT;
860
861 /* The criteria to pick *this* auto performer for its cause. */
862 requirement_vector_init(&auto_perfs[i].reqs);
863
864 for (j = 0; j < MAX_NUM_ACTIONS; j++) {
865 /* Nothing here. Nothing after this point. */
866 auto_perfs[i].alternatives[j] = ACTION_NONE;
867 }
868 }
869
870 /* The actions them self are now initialized. */
871 actions_initialized = TRUE;
872}
873
874/**********************************************************************/
879 void actions_rs_pre_san_gen(void)
880{
881 /* Some obligatory hard requirements needs access to the rest of the
882 * ruleset. */
883 hard_code_oblig_hard_reqs_ruleset();
884}
885
886/**********************************************************************/
889 void actions_free(void)
890{
891 int i;
892
893 /* Don't consider the actions to be initialized any longer. */
894 actions_initialized = FALSE;
895
896 action_iterate_all(act) {
897 action_enabler_list_iterate(action_enablers_by_action[act], enabler) {
898 action_enabler_free(enabler);
899 } action_enabler_list_iterate_end;
900
901 action_enabler_list_destroy(action_enablers_by_action[act]);
902
903 FC_FREE(actions[act]);
904 } action_iterate_all_end;
905
906 /* Free the obligatory hard action requirements. */
907 oblig_hard_reqs_free();
908
909 /* Free the action auto performers. */
910 for (i = 0; i < MAX_NUM_ACTION_AUTO_PERFORMERS; i++) {
911 requirement_vector_free(&auto_perfs[i].reqs);
912 }
913
914 astr_free(&ui_name_str);
915
916 for (i = 0; i < ACTRES_LAST; i++) {
917 action_list_destroy(actlist_by_result[i]);
918 actlist_by_result[i] = NULL;
919 }
920 for (i = 0; i < ACTIVITY_LAST; i++) {
921 action_list_destroy(actlist_by_activity[i]);
922 actlist_by_activity[i] = NULL;
923 }
924}
925
926/**********************************************************************/
931 bool actions_are_ready(void)
932{
933 if (!actions_initialized) {
934 /* The actions them self aren't initialized yet. */
935 return FALSE;
936 }
937
938 action_noninternal_iterate(act) {
939 if (actions[act]->ui_name[0] == '\0') {
940 /* A noninternal action without a UI name exists means that
941 * the ruleset haven't loaded yet. The ruleset loading will assign
942 * a default name to any actions not named by the ruleset.
943 * The client will get this name from the server. */
944 return FALSE;
945 }
946 } action_noninternal_iterate_end;
947
948 /* The actions should be ready for use. */
949 return TRUE;
950}
951
952/**********************************************************************/
955 static struct action *action_new(action_id id,
956 enum action_result result,
957 const int min_distance,
958 const int max_distance,
959 bool actor_consuming_always)
960{
961 struct action *action;
962
963 action = fc_malloc(sizeof(*action));
964
965 action->id = id;
966
967 action->result = result;
968
969 if (result != ACTRES_LAST) {
970 enum unit_activity act = actres_activity_result(result);
971
972 action_list_append(actlist_by_result[result], action);
973
974 if (act != ACTIVITY_LAST) {
975 action_list_append(actlist_by_activity[act], action);
976 }
977 }
978
979 /* Not set here */
980 BV_CLR_ALL(action->sub_results);
981
982 action->actor_kind = AAK_UNIT;
983 action->target_kind = actres_target_kind_default(result);
984 action->sub_target_kind = actres_sub_target_kind_default(result);
985 action->target_complexity = actres_target_compl_calc(result);
986
987 /* ASTK_NONE implies ACT_TGT_COMPL_SIMPLE and
988 * !ASTK_NONE implies !ACT_TGT_COMPL_SIMPLE */
989 fc_assert_msg(((action->sub_target_kind == ASTK_NONE
990 && action->target_complexity == ACT_TGT_COMPL_SIMPLE)
991 || (action->sub_target_kind != ASTK_NONE
992 && action->target_complexity != ACT_TGT_COMPL_SIMPLE)),
993 "%s contradicts itself regarding sub targets.",
994 action_rule_name(action));
995
996 /* The distance between the actor and itself is always 0. */
997 fc_assert(action->target_kind != ATK_SELF
998 || (min_distance == 0 && max_distance == 0));
999
1000 action->min_distance = min_distance;
1001 action->max_distance = max_distance;
1002
1003 action->actor_consuming_always = actor_consuming_always;
1004
1005 /* Loaded from the ruleset. Until generalized actions are ready it has to
1006 * be defined separately from other action data. */
1007 action->ui_name[0] = '\0';
1008 action->quiet = FALSE;
1009 BV_CLR_ALL(action->blocked_by);
1010
1011 return action;
1012}
1013
1014/**********************************************************************/
1017static struct action *
1018unit_action_new(action_id id,
1019 enum action_result result,
1020 bool rare_pop_up,
1021 bool unitwaittime_controlled,
1022 enum moves_actor_kind moves_actor,
1023 const int min_distance,
1024 const int max_distance,
1025 bool actor_consuming_always)
1026{
1027 struct action *act = action_new(id, result,
1028 min_distance, max_distance,
1029 actor_consuming_always);
1030
1031 act->actor.is_unit.rare_pop_up = rare_pop_up;
1032
1033 act->actor.is_unit.unitwaittime_controlled = unitwaittime_controlled;
1034
1035 act->actor.is_unit.moves_actor = moves_actor;
1036
1037 return act;
1038}
1039
1040/**********************************************************************/
1043 bool action_id_exists(const action_id act_id)
1044{
1045 /* Actions are still hard coded. */
1046 return gen_action_is_valid(act_id) && actions[act_id];
1047}
1048
1049/**********************************************************************/
1054 struct action *action_by_rule_name(const char *name)
1055{
1056 /* Actions are still hard coded in the gen_action enum. */
1057 action_id act_id = gen_action_by_name(name, fc_strcasecmp);
1058
1059 if (!action_id_exists(act_id)) {
1060 /* Nothing to return. */
1061
1062 log_verbose("Asked for non existing action named %s", name);
1063
1064 return NULL;
1065 }
1066
1067 return action_by_number(act_id);
1068}
1069
1070/**********************************************************************/
1073 enum action_actor_kind action_get_actor_kind(const struct action *paction)
1074{
1075 fc_assert_ret_val_msg(paction, AAK_COUNT, "Action doesn't exist.");
1076
1077 return paction->actor_kind;
1078}
1079
1080/**********************************************************************/
1083 enum action_target_kind action_get_target_kind(
1084 const struct action *paction)
1085{
1086 fc_assert_ret_val_msg(paction, ATK_COUNT, "Action doesn't exist.");
1087
1088 return paction->target_kind;
1089}
1090
1091/**********************************************************************/
1094 enum action_sub_target_kind action_get_sub_target_kind(
1095 const struct action *paction)
1096{
1097 fc_assert_ret_val_msg(paction, ASTK_COUNT, "Action doesn't exist.");
1098
1099 return paction->sub_target_kind;
1100}
1101
1102/**********************************************************************/
1107 bool action_has_complex_target(const struct action *paction)
1108{
1109 fc_assert_ret_val(paction != NULL, FALSE);
1110
1111 return paction->target_complexity >= ACT_TGT_COMPL_FLEXIBLE;
1112}
1113
1114/**********************************************************************/
1120 bool action_requires_details(const struct action *paction)
1121{
1122 fc_assert_ret_val(paction != NULL, FALSE);
1123
1124 return paction->target_complexity >= ACT_TGT_COMPL_MANDATORY;
1125}
1126
1127/**********************************************************************/
1135 bool action_id_is_rare_pop_up(action_id act_id)
1136{
1137 fc_assert_ret_val_msg((action_id_exists(act_id)),
1138 FALSE, "Action %d don't exist.", act_id);
1139 fc_assert_ret_val(action_id_get_actor_kind(act_id) == AAK_UNIT, FALSE);
1140
1141 return actions[act_id]->actor.is_unit.rare_pop_up;
1142}
1143
1144/**********************************************************************/
1148 bool action_distance_inside_max(const struct action *action,
1149 const int distance)
1150{
1151 return (distance <= action-> max_distance
1152 || action->max_distance == ACTION_DISTANCE_UNLIMITED);
1153}
1154
1155/**********************************************************************/
1159 bool action_distance_accepted(const struct action *action,
1160 const int distance)
1161{
1162 fc_assert_ret_val(action, FALSE);
1163
1164 return (distance >= action->min_distance
1165 && action_distance_inside_max(action, distance));
1166}
1167
1168/**********************************************************************/
1171 bool action_would_be_blocked_by(const struct action *blocked,
1172 const struct action *blocker)
1173{
1174 fc_assert_ret_val(blocked, FALSE);
1175 fc_assert_ret_val(blocker, FALSE);
1176
1177 return BV_ISSET(blocked->blocked_by, action_number(blocker));
1178}
1179
1180/**********************************************************************/
1183 int action_number(const struct action *action)
1184{
1185 return action->id;
1186}
1187
1188/**********************************************************************/
1191 const char *action_rule_name(const struct action *action)
1192{
1193 /* Rule name is still hard coded. */
1194 return action_id_rule_name(action->id);
1195}
1196
1197/**********************************************************************/
1205 const char *action_name_translation(const struct action *paction)
1206{
1207 /* Use action_id_name_translation() to format the UI name. */
1208 return action_id_name_translation(paction->id);
1209}
1210
1211/**********************************************************************/
1214 const char *action_id_rule_name(action_id act_id)
1215{
1216 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
1217
1218 return gen_action_name(act_id);
1219}
1220
1221/**********************************************************************/
1225 const char *action_id_name_translation(action_id act_id)
1226{
1227 return action_prepare_ui_name(act_id, "", ACTPROB_NA, NULL);
1228}
1229
1230/**********************************************************************/
1233 const char *action_get_ui_name_mnemonic(action_id act_id,
1234 const char *mnemonic)
1235{
1236 return action_prepare_ui_name(act_id, mnemonic, ACTPROB_NA, NULL);
1237}
1238
1239/**********************************************************************/
1246 static const char *action_prob_to_text(const struct act_prob prob)
1247{
1248 static struct astring chance = ASTRING_INIT;
1249
1250 /* How to interpret action probabilities like prob is documented in
1251 * fc_types.h */
1252 if (action_prob_is_signal(prob)) {
1253 fc_assert(action_prob_not_impl(prob)
1254 || action_prob_not_relevant(prob));
1255
1256 /* Unknown because of missing server support or should not exits. */
1257 return NULL;
1258 }
1259
1260 if (prob.min == prob.max) {
1261 /* Only one probability in range. */
1262
1263 /* TRANS: the probability that an action will succeed. Given in
1264 * percentage. Resolution is 0.5%. */
1265 astr_set(&chance, _("%.1f%%"), (double)prob.max / ACTPROB_VAL_1_PCT);
1266 } else {
1267 /* TRANS: the interval (end points included) where the probability of
1268 * the action's success is. Given in percentage. Resolution is 0.5%. */
1269 astr_set(&chance, _("[%.1f%%, %.1f%%]"),
1270 (double)prob.min / ACTPROB_VAL_1_PCT,
1271 (double)prob.max / ACTPROB_VAL_1_PCT);
1272 }
1273
1274 return astr_str(&chance);
1275}
1276
1277/**********************************************************************/
1287 const char *action_prepare_ui_name(action_id act_id, const char *mnemonic,
1288 const struct act_prob prob,
1289 const char *custom)
1290{
1291 struct astring chance = ASTRING_INIT;
1292
1293 /* Text representation of the probability. */
1294 const char *probtxt;
1295
1296 if (!actions_are_ready()) {
1297 /* Could be a client who haven't gotten the ruleset yet */
1298
1299 /* so there shouldn't be any action probability to show */
1300 fc_assert(action_prob_not_relevant(prob));
1301
1302 /* but the action should be valid */
1303 fc_assert_ret_val_msg(action_id_exists(act_id),
1304 "Invalid action",
1305 "Invalid action %d", act_id);
1306
1307 /* and no custom text will be inserted */
1308 fc_assert(custom == NULL || custom[0] == '\0');
1309
1310 /* Make the best of what is known */
1311 astr_set(&ui_name_str, _("%s%s (name may be wrong)"),
1312 mnemonic, action_id_rule_name(act_id));
1313
1314 /* Return the guess. */
1315 return astr_str(&ui_name_str);
1316 }
1317
1318 probtxt = action_prob_to_text(prob);
1319
1320 /* Format the info part of the action's UI name. */
1321 if (probtxt != NULL && custom != NULL) {
1322 /* TRANS: action UI name's info part with custom info and probability.
1323 * Hint: you can move the paren handling from this sting to the action
1324 * names if you need to add extra information (like a mnemonic letter
1325 * that doesn't appear in the action UI name) to it. In that case you
1326 * must do so for all strings with this comment and for every action
1327 * name. To avoid a `()` when no UI name info part is added you have
1328 * to add the extra information to every action name or remove the
1329 * surrounding parens. */
1330 astr_set(&chance, _(" (%s; %s)"), custom, probtxt);
1331 } else if (probtxt != NULL) {
1332 /* TRANS: action UI name's info part with probability.
1333 * Hint: you can move the paren handling from this sting to the action
1334 * names if you need to add extra information (like a mnemonic letter
1335 * that doesn't appear in the action UI name) to it. In that case you
1336 * must do so for all strings with this comment and for every action
1337 * name. To avoid a `()` when no UI name info part is added you have
1338 * to add the extra information to every action name or remove the
1339 * surrounding parens. */
1340 astr_set(&chance, _(" (%s)"), probtxt);
1341 } else if (custom != NULL) {
1342 /* TRANS: action UI name's info part with custom info.
1343 * Hint: you can move the paren handling from this sting to the action
1344 * names if you need to add extra information (like a mnemonic letter
1345 * that doesn't appear in the action UI name) to it. In that case you
1346 * must do so for all strings with this comment and for every action
1347 * name. To avoid a `()` when no UI name info part is added you have
1348 * to add the extra information to every action name or remove the
1349 * surrounding parens. */
1350 astr_set(&chance, _(" (%s)"), custom);
1351 } else {
1352 /* No info part to display. */
1353 astr_clear(&chance);
1354 }
1355
1356 fc_assert_msg(actions[act_id], "Action %d don't exist.", act_id);
1357
1358 /* Escape any instances of the mnemonic in the action's UI format string.
1359 * (Assumes any mnemonic can be escaped by doubling, and that they are
1360 * unlikely to appear in a format specifier. True for clients seen so
1361 * far: Gtk's _ and Qt's &) */
1362 {
1363 struct astring fmtstr = ASTRING_INIT;
1364 const char *ui_name = _(actions[act_id]->ui_name);
1365
1366 if (mnemonic[0] != '\0') {
1367 const char *hit;
1368
1369 fc_assert(!strchr(mnemonic, '%'));
1370 while ((hit = strstr(ui_name, mnemonic))) {
1371 astr_add(&fmtstr, "%.*s%s%s", (int)(hit - ui_name), ui_name,
1372 mnemonic, mnemonic);
1373 ui_name = hit + strlen(mnemonic);
1374 }
1375 }
1376 astr_add(&fmtstr, "%s", ui_name);
1377
1378 /* Use the modified format string */
1379 astr_set(&ui_name_str, astr_str(&fmtstr), mnemonic,
1380 astr_str(&chance));
1381
1382 astr_free(&fmtstr);
1383 }
1384
1385 astr_free(&chance);
1386
1387 return astr_str(&ui_name_str);
1388}
1389
1390/**********************************************************************/
1398 const char *action_prob_explain(const struct act_prob prob)
1399{
1400 static struct astring tool_tip = ASTRING_INIT;
1401
1402 if (action_prob_is_signal(prob)) {
1403 fc_assert(action_prob_not_impl(prob));
1404
1405 /* Missing server support. No in game action will change this. */
1406 astr_clear(&tool_tip);
1407 } else if (prob.min == prob.max) {
1408 /* TRANS: action probability of success. Given in percentage.
1409 * Resolution is 0.5%. */
1410 astr_set(&tool_tip, _("The probability of success is %.1f%%."),
1411 (double)prob.max / ACTPROB_VAL_1_PCT);
1412 } else {
1413 astr_set(&tool_tip,
1414 /* TRANS: action probability interval (min to max). Given in
1415 * percentage. Resolution is 0.5%. The string at the end is
1416 * shown when the interval is wide enough to not be caused by
1417 * rounding. It explains that the interval is imprecise because
1418 * the player doesn't have enough information. */
1419 _("The probability of success is %.1f%%, %.1f%% or somewhere"
1420 " in between.%s"),
1421 (double)prob.min / ACTPROB_VAL_1_PCT,
1422 (double)prob.max / ACTPROB_VAL_1_PCT,
1423 prob.max - prob.min > 1 ?
1424 /* TRANS: explanation used in the action probability tooltip
1425 * above. Preserve leading space. */
1426 _(" (This is the most precise interval I can calculate "
1427 "given the information our nation has access to.)") :
1428 "");
1429 }
1430
1431 return astr_str(&tool_tip);
1432}
1433
1434/**********************************************************************/
1438 int action_get_role(const struct action *paction)
1439{
1440 fc_assert_msg(AAK_UNIT == action_get_actor_kind(paction),
1441 "Action %s isn't performed by a unit",
1442 action_rule_name(paction));
1443
1444 return paction->id + L_LAST;
1445}
1446
1447/**********************************************************************/
1450 struct action_enabler *action_enabler_new(void)
1451{
1452 struct action_enabler *enabler;
1453
1454 enabler = fc_malloc(sizeof(*enabler));
1455 enabler->ruledit_disabled = FALSE;
1456 requirement_vector_init(&enabler->actor_reqs);
1457 requirement_vector_init(&enabler->target_reqs);
1458
1459 /* Make sure that action doesn't end up as a random value that happens to
1460 * be a valid action id. */
1461 enabler->action = ACTION_NONE;
1462
1463 return enabler;
1464}
1465
1466/**********************************************************************/
1469 void action_enabler_free(struct action_enabler *enabler)
1470{
1471 requirement_vector_free(&enabler->actor_reqs);
1472 requirement_vector_free(&enabler->target_reqs);
1473
1474 free(enabler);
1475}
1476
1477/**********************************************************************/
1480struct action_enabler *
1481action_enabler_copy(const struct action_enabler *original)
1482{
1483 struct action_enabler *enabler = action_enabler_new();
1484
1485 enabler->action = original->action;
1486
1487 requirement_vector_copy(&enabler->actor_reqs, &original->actor_reqs);
1488 requirement_vector_copy(&enabler->target_reqs, &original->target_reqs);
1489
1490 return enabler;
1491}
1492
1493/**********************************************************************/
1496 void action_enabler_add(struct action_enabler *enabler)
1497{
1498 /* Sanity check: a non existing action enabler can't be added. */
1499 fc_assert_ret(enabler);
1500 /* Sanity check: a non existing action doesn't have enablers. */
1501 fc_assert_ret(action_id_exists(enabler_get_action_id(enabler)));
1502
1503 action_enabler_list_append(
1504 action_enablers_for_action(enabler_get_action_id(enabler)),
1505 enabler);
1506}
1507
1508/**********************************************************************/
1513 bool action_enabler_remove(struct action_enabler *enabler)
1514{
1515 /* Sanity check: a non existing action enabler can't be removed. */
1516 fc_assert_ret_val(enabler, FALSE);
1517 /* Sanity check: a non existing action doesn't have enablers. */
1518 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), FALSE);
1519
1520 return action_enabler_list_remove(
1521 action_enablers_for_action(enabler_get_action_id(enabler)),
1522 enabler);
1523}
1524
1525/**********************************************************************/
1528struct action_enabler_list *
1529action_enablers_for_action(action_id action)
1530{
1531 /* Sanity check: a non existing action doesn't have enablers. */
1532 fc_assert_ret_val(action_id_exists(action), NULL);
1533
1534 return action_enablers_by_action[action];
1535}
1536
1537/**********************************************************************/
1548static struct req_vec_problem *
1549ae_suggest_repair_if_no_oblig(const struct action_enabler *enabler,
1550 const struct obligatory_req_vector *oblig)
1551{
1552 struct action *paction;
1553
1554 /* Sanity check: a non existing action enabler is missing but it doesn't
1555 * miss any obligatory hard requirements. */
1556 fc_assert_ret_val(enabler, NULL);
1557
1558 /* Sanity check: a non existing action doesn't have any obligatory hard
1559 * requirements. */
1560 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), NULL);
1561 paction = enabler_get_action(enabler);
1562
1563 /* No obligatory hard requirements. */
1564 fc_assert_ret_val(oblig, NULL);
1565
1566 obligatory_req_vector_iterate(oblig, obreq) {
1567 struct req_vec_problem *out;
1568 int i;
1569 bool fulfilled = FALSE;
1570
1571 /* Check each alternative. */
1572 for (i = 0; i < obreq->contras->alternatives; i++) {
1573 const struct requirement_vector *ae_vec;
1574
1575 /* Select action enabler requirement vector. */
1576 ae_vec = (obreq->contras->alternative[i].is_target
1577 ? &enabler->target_reqs
1578 : &enabler->actor_reqs);
1579
1580 if (does_req_contradicts_reqs(&obreq->contras->alternative[i].req,
1581 ae_vec)
1582 /* Consider the hard requirement fulfilled since a universal that
1583 * never is there always will be absent in this ruleset. */
1584 || (obreq->contras->alternative[i].req.present
1585 && universal_never_there(
1586 &obreq->contras->alternative[i].req.source))) {
1587 /* It is enough that one alternative accepts the enabler. */
1588 fulfilled = TRUE;
1589 break;
1590 }
1591
1592 /* Fall back to the next alternative */
1593 }
1594
1595 if (fulfilled) {
1596 /* This obligatory hard requirement isn't a problem. */
1597 continue;
1598 }
1599
1600 /* Missing hard obligatory requirement detected */
1601
1602 out = req_vec_problem_new(obreq->contras->alternatives,
1603 obreq->error_msg,
1604 action_rule_name(paction));
1605
1606 for (i = 0; i < obreq->contras->alternatives; i++) {
1607 const struct requirement_vector *ae_vec;
1608
1609 /* Select action enabler requirement vector. */
1610 ae_vec = (obreq->contras->alternative[i].is_target
1611 ? &enabler->target_reqs
1612 : &enabler->actor_reqs);
1613
1614 /* The suggested fix is to append a requirement that makes the enabler
1615 * contradict the missing hard obligatory requirement detector. */
1616 out->suggested_solutions[i].operation = RVCO_APPEND;
1617 out->suggested_solutions[i].vector_number
1618 = action_enabler_vector_number(enabler, ae_vec);
1619
1620 /* Change the requirement from what should conflict to what is
1621 * wanted. */
1622 out->suggested_solutions[i].req.present
1623 = !obreq->contras->alternative[i].req.present;
1624 out->suggested_solutions[i].req.source
1625 = obreq->contras->alternative[i].req.source;
1626 out->suggested_solutions[i].req.range
1627 = obreq->contras->alternative[i].req.range;
1628 out->suggested_solutions[i].req.survives
1629 = obreq->contras->alternative[i].req.survives;
1630 out->suggested_solutions[i].req.quiet
1631 = obreq->contras->alternative[i].req.quiet;
1632 }
1633
1634 /* Return the first problem found. The next problem will be detected
1635 * during the next call. */
1636 return out;
1637 } obligatory_req_vector_iterate_end;
1638
1639 /* No obligatory req problems found. */
1640 return NULL;
1641}
1642
1643/**********************************************************************/
1652struct req_vec_problem *
1653action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
1654{
1655 struct action *paction;
1656 enum action_sub_result sub_res;
1657 struct req_vec_problem *out;
1658
1659 /* Sanity check: a non existing action enabler is missing but it doesn't
1660 * miss any obligatory hard requirements. */
1661 fc_assert_ret_val(enabler, NULL);
1662
1663 /* Sanity check: a non existing action doesn't have any obligatory hard
1664 * requirements. */
1665 fc_assert_ret_val(action_id_exists(enabler_get_action_id(enabler)), NULL);
1666 paction = enabler_get_action(enabler);
1667
1668 if (paction->result != ACTRES_NONE) {
1669 /* A hard coded action result may mean obligatory requirements. */
1670 out = ae_suggest_repair_if_no_oblig(enabler, oblig_hard_reqs_get(paction->result));
1671 if (out != NULL) {
1672 return out;
1673 }
1674 }
1675
1676 for (sub_res = action_sub_result_begin();
1677 sub_res != action_sub_result_end();
1678 sub_res = action_sub_result_next(sub_res)) {
1679 if (!BV_ISSET(paction->sub_results, sub_res)) {
1680 /* Not relevant */
1681 continue;
1682 }
1683
1684 /* The action has this sub result. Check its hard requirements. */
1685 out = ae_suggest_repair_if_no_oblig(enabler,
1686 oblig_hard_reqs_get_sub(sub_res));
1687 if (out != NULL) {
1688 return out;
1689 }
1690 }
1691
1692 /* No obligatory req problems found. */
1693 return NULL;
1694}
1695
1696/**********************************************************************/
1702static struct requirement *
1703req_vec_first_local_diplrel(const struct requirement_vector *vec)
1704{
1705 requirement_vector_iterate(vec, preq) {
1706 if (preq->source.kind == VUT_DIPLREL
1707 && preq->range == REQ_RANGE_LOCAL) {
1708 return preq;
1709 }
1710 } requirement_vector_iterate_end;
1711
1712 return NULL;
1713}
1714
1715/**********************************************************************/
1723static struct requirement *
1724req_vec_first_contradiction_in_vec(const struct requirement *req,
1725 const struct requirement_vector *vec)
1726{
1727 /* If the requirement is contradicted by any requirement in the vector it
1728 * contradicts the entire requirement vector. */
1729 requirement_vector_iterate(vec, preq) {
1730 if (are_requirements_contradictions(req, preq)) {
1731 return preq;
1732 }
1733 } requirement_vector_iterate_end;
1734
1735 /* Not a singe requirement in the requirement vector is contradicted be
1736 * the specified requirement. */
1737 return NULL;
1738}
1739
1740/**********************************************************************/
1746static struct req_vec_problem *
1747enabler_tile_tgt_local_diplrel_implies_claimed(
1748 const struct action_enabler *enabler)
1749{
1750 struct req_vec_problem *out;
1751 struct requirement *local_diplrel;
1752 struct requirement *claimed_req;
1753 struct requirement tile_is_claimed;
1754 struct requirement tile_is_unclaimed;
1755 struct action *paction = enabler_get_action(enabler);
1756 struct astring astr;
1757
1758 if (action_get_target_kind(paction) != ATK_TILE) {
1759 /* Not tile targeted */
1760 return NULL;
1761 }
1762
1763 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
1764 if (local_diplrel == NULL) {
1765 /* No local diplrel */
1766 return NULL;
1767 }
1768
1769 /* Tile is unclaimed as a requirement. */
1770 tile_is_unclaimed.range = REQ_RANGE_TILE;
1771 tile_is_unclaimed.survives = FALSE;
1772 tile_is_unclaimed.source.kind = VUT_CITYTILE;
1773 tile_is_unclaimed.present = FALSE;
1774 tile_is_unclaimed.source.value.citytile = CITYT_CLAIMED;
1775
1776 claimed_req = req_vec_first_contradiction_in_vec(&tile_is_unclaimed,
1777 &enabler->target_reqs);
1778
1779 if (claimed_req) {
1780 /* Already clear */
1781 return NULL;
1782 }
1783
1784 /* Tile is claimed as a requirement. */
1785 tile_is_claimed.range = REQ_RANGE_TILE;
1786 tile_is_claimed.survives = FALSE;
1787 tile_is_claimed.source.kind = VUT_CITYTILE;
1788 tile_is_claimed.present = TRUE;
1789 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
1790
1791 out = req_vec_problem_new(
1792 1,
1793 /* TRANS: ruledit shows this when an enabler for a tile targeted
1794 * action requires that the actor has a diplomatic relationship to
1795 * the target but doesn't require that the target tile is claimed.
1796 * (DiplRel requirements to an unclaimed tile are never fulfilled
1797 * so this is implicit.) */
1798 N_("Requirement {%s} of action \"%s\" implies a claimed "
1799 "tile. No diplomatic relation to Nature."),
1800 req_to_fstring(local_diplrel, &astr), action_rule_name(paction));
1801
1802 astr_free(&astr);
1803
1804 /* The solution is to add the requirement that the tile is claimed */
1805 out->suggested_solutions[0].req = tile_is_claimed;
1806 out->suggested_solutions[0].vector_number
1807 = action_enabler_vector_number(enabler, &enabler->target_reqs);
1808 out->suggested_solutions[0].operation = RVCO_APPEND;
1809
1810 return out;
1811}
1812
1813/**********************************************************************/
1819static struct req_vec_problem *
1820enabler_first_self_contradiction(const struct action_enabler *enabler)
1821{
1822 struct req_vec_problem *out;
1823 struct requirement *local_diplrel;
1824 struct requirement *unclaimed_req;
1825 struct requirement tile_is_claimed;
1826 struct action *paction = enabler_get_action(enabler);
1827 struct astring astr1;
1828 struct astring astr2;
1829
1830 if (action_get_target_kind(paction) != ATK_TILE) {
1831 /* Not tile targeted */
1832 return NULL;
1833 }
1834
1835 local_diplrel = req_vec_first_local_diplrel(&enabler->actor_reqs);
1836 if (local_diplrel == NULL) {
1837 /* No local diplrel */
1838 return NULL;
1839 }
1840
1841 /* Tile is claimed as a requirement. */
1842 tile_is_claimed.range = REQ_RANGE_TILE;
1843 tile_is_claimed.survives = FALSE;
1844 tile_is_claimed.source.kind = VUT_CITYTILE;
1845 tile_is_claimed.present = TRUE;
1846 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
1847
1848 unclaimed_req = req_vec_first_contradiction_in_vec(&tile_is_claimed,
1849 &enabler->target_reqs);
1850
1851 if (unclaimed_req == NULL) {
1852 /* No unclaimed req */
1853 return NULL;
1854 }
1855
1856 out = req_vec_problem_new(
1857 2,
1858 /* TRANS: ruledit shows this when an enabler for a tile targeted
1859 * action requires that the target tile is unclaimed and that the
1860 * actor has a diplomatic relationship to the target. (DiplRel
1861 * requirements to an unclaimed tile are never fulfilled.) */
1862 N_("In enabler for \"%s\": No diplomatic relation to Nature."
1863 " Requirements {%s} and {%s} contradict each other."),
1864 action_rule_name(paction),
1865 req_to_fstring(local_diplrel, &astr1),
1866 req_to_fstring(unclaimed_req, &astr2));
1867
1868 astr_free(&astr1);
1869 astr_free(&astr2);
1870
1871 /* The first suggestion is to remove the diplrel */
1872 out->suggested_solutions[0].req = *local_diplrel;
1873 out->suggested_solutions[0].vector_number
1874 = action_enabler_vector_number(enabler, &enabler->actor_reqs);
1875 out->suggested_solutions[0].operation = RVCO_REMOVE;
1876
1877 /* The 2nd is to remove the requirement that the tile is unclaimed */
1878 out->suggested_solutions[1].req = *unclaimed_req;
1879 out->suggested_solutions[1].vector_number
1880 = action_enabler_vector_number(enabler, &enabler->target_reqs);
1881 out->suggested_solutions[1].operation = RVCO_REMOVE;
1882
1883 return out;
1884}
1885
1886/**********************************************************************/
1891struct req_vec_problem *
1892action_enabler_suggest_repair(const struct action_enabler *enabler)
1893{
1894 struct req_vec_problem *out;
1895
1896 out = action_enabler_suggest_repair_oblig(enabler);
1897 if (out != NULL) {
1898 return out;
1899 }
1900
1901 /* Look for errors in the requirement vectors. */
1902 out = req_vec_suggest_repair(&enabler->actor_reqs,
1903 action_enabler_vector_number,
1904 enabler);
1905 if (out != NULL) {
1906 return out;
1907 }
1908
1909 out = req_vec_suggest_repair(&enabler->target_reqs,
1910 action_enabler_vector_number,
1911 enabler);
1912 if (out != NULL) {
1913 return out;
1914 }
1915
1916 /* Enabler specific contradictions. */
1917 out = enabler_first_self_contradiction(enabler);
1918 if (out != NULL) {
1919 return out;
1920 }
1921
1922 /* Needed in action not enabled explanation finding. */
1923 out = enabler_tile_tgt_local_diplrel_implies_claimed(enabler);
1924 if (out != NULL) {
1925 return out;
1926 }
1927
1928 /* No problems found. */
1929 return NULL;
1930}
1931
1932/**********************************************************************/
1939static struct req_vec_problem *
1940enabler_first_clarification(const struct action_enabler *enabler)
1941{
1942 struct req_vec_problem *out;
1943
1944 out = NULL;
1945
1946 return out;
1947}
1948
1949/**********************************************************************/
1957struct req_vec_problem *
1958action_enabler_suggest_improvement(const struct action_enabler *enabler)
1959{
1960 struct action *paction;
1961 struct req_vec_problem *out;
1962
1963 out = action_enabler_suggest_repair(enabler);
1964 if (out) {
1965 /* A bug, not just a potential improvement */
1966 return out;
1967 }
1968
1969 paction = enabler_get_action(enabler);
1970
1971 /* Look for improvement suggestions to the requirement vectors. */
1972 out = req_vec_suggest_improvement(&enabler->actor_reqs,
1973 action_enabler_vector_number,
1974 enabler);
1975 if (out) {
1976 return out;
1977 }
1978 out = req_vec_suggest_improvement(&enabler->target_reqs,
1979 action_enabler_vector_number,
1980 enabler);
1981 if (out) {
1982 return out;
1983 }
1984
1985 /* Detect unused action enablers. */
1986 if (action_get_actor_kind(paction) == AAK_UNIT) {
1987 bool has_user = FALSE;
1988
1989 unit_type_iterate(pactor) {
1990 if (action_actor_utype_hard_reqs_ok(paction, pactor)
1991 && requirement_fulfilled_by_unit_type(pactor,
1992 &(enabler->actor_reqs))) {
1993 has_user = TRUE;
1994 break;
1995 }
1996 } unit_type_iterate_end;
1997
1998 if (!has_user) {
1999 /* TRANS: ruledit warns a user about an unused action enabler */
2000 out = req_vec_problem_new(0, N_("Action enabler for \"%s\" is never"
2001 " used by any unit."),
2002 action_rule_name(paction));
2003 }
2004 }
2005 if (out != NULL) {
2006 return out;
2007 }
2008
2009 out = enabler_first_clarification(enabler);
2010
2011 return out;
2012}
2013
2014/**********************************************************************/
2021 req_vec_num_in_item
2022action_enabler_vector_number(const void *enabler,
2023 const struct requirement_vector *vec)
2024{
2025 struct action_enabler *ae = (struct action_enabler *)enabler;
2026
2027 if (vec == &ae->actor_reqs) {
2028 return 0;
2029 } else if (vec == &ae->target_reqs) {
2030 return 1;
2031 } else {
2032 return -1;
2033 }
2034}
2035
2036/********************************************************************/
2044struct requirement_vector *
2045action_enabler_vector_by_number(const void *enabler,
2046 req_vec_num_in_item number)
2047{
2048 struct action_enabler *ae = (struct action_enabler *)enabler;
2049
2050 fc_assert_ret_val(number >= 0, NULL);
2051
2052 switch (number) {
2053 case 0:
2054 return &ae->actor_reqs;
2055 case 1:
2056 return &ae->target_reqs;
2057 default:
2058 return NULL;
2059 }
2060}
2061
2062/*********************************************************************/
2069 const char *action_enabler_vector_by_number_name(req_vec_num_in_item vec)
2070{
2071 switch (vec) {
2072 case 0:
2073 /* TRANS: requirement vector in an action enabler (ruledit) */
2074 return _("actor_reqs");
2075 case 1:
2076 /* TRANS: requirement vector in an action enabler (ruledit) */
2077 return _("target_reqs");
2078 default:
2079 return NULL;
2080 }
2081}
2082
2083/**********************************************************************/
2088static const struct impr_type *
2089tgt_city_local_building(const struct city *target_city)
2090{
2091 /* Only used with city targets */
2092 fc_assert_ret_val(target_city, NULL);
2093
2094 if (target_city->production.kind == VUT_IMPROVEMENT) {
2095 /* The local building is what the target city currently is building. */
2096 return target_city->production.value.building;
2097 } else {
2098 /* In the current semantic the local building is always the building
2099 * being built. */
2100 /* TODO: Consider making the local building the target building for
2101 * actions that allows specifying a building target. */
2102 return NULL;
2103 }
2104}
2105
2106/**********************************************************************/
2111static const struct unit_type *
2112tgt_city_local_utype(const struct city *target_city)
2113{
2114 /* Only used with city targets */
2115 fc_assert_ret_val(target_city, NULL);
2116
2117 if (target_city->production.kind == VUT_UTYPE) {
2118 /* The local unit type is what the target city currently is
2119 * building. */
2120 return target_city->production.value.utype;
2121 } else {
2122 /* In the current semantic the local utype is always the type of the
2123 * unit being built. */
2124 return NULL;
2125 }
2126}
2127
2128/**********************************************************************/
2136static const struct tile *
2137blocked_find_target_tile(const struct action *act,
2138 const struct unit *actor_unit,
2139 const struct tile *target_tile_arg,
2140 const struct city *target_city,
2141 const struct unit *target_unit)
2142{
2143 if (target_tile_arg != NULL) {
2144 /* Trust the caller. */
2145 return target_tile_arg;
2146 }
2147
2148 /* Action should always be set */
2149 fc_assert_ret_val(act, NULL);
2150
2151 switch (action_get_target_kind(act)) {
2152 case ATK_CITY:
2153 fc_assert_ret_val(target_city, NULL);
2154 return city_tile(target_city);
2155 case ATK_UNIT:
2156 if (target_unit == NULL) {
2157 fc_assert(target_unit != NULL);
2158 return NULL;
2159 }
2160 return unit_tile(target_unit);
2161 case ATK_UNITS:
2162 fc_assert_ret_val(target_unit || target_tile_arg, NULL);
2163 if (target_unit) {
2164 return unit_tile(target_unit);
2165 }
2166
2167 fc__fallthrough;
2168 case ATK_TILE:
2169 case ATK_EXTRAS:
2170 fc_assert_ret_val(target_tile_arg, NULL);
2171 return target_tile_arg;
2172 case ATK_SELF:
2173 fc_assert_ret_val(actor_unit, NULL);
2174 return unit_tile(actor_unit);
2175 case ATK_COUNT:
2176 /* Handled below. */
2177 break;
2178 }
2179
2180 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
2181 action_get_target_kind(act), action_rule_name(act));
2182 return NULL;
2183}
2184
2185/**********************************************************************/
2194static const struct city *
2195blocked_find_target_city(const struct action *act,
2196 const struct unit *actor_unit,
2197 const struct tile *target_tile,
2198 const struct city *target_city_arg,
2199 const struct unit *target_unit)
2200{
2201 if (target_city_arg != NULL) {
2202 /* Trust the caller. */
2203 return target_city_arg;
2204 }
2205
2206 /* action should always be set */
2207 fc_assert_ret_val(act, NULL);
2208
2209 switch (action_get_target_kind(act)) {
2210 case ATK_CITY:
2211 fc_assert_ret_val(target_city_arg, NULL);
2212 return target_city_arg;
2213 case ATK_UNIT:
2214 fc_assert_ret_val(target_unit, NULL);
2215 fc_assert_ret_val(unit_tile(target_unit), NULL);
2216 return tile_city(unit_tile(target_unit));
2217 case ATK_UNITS:
2218 fc_assert_ret_val(target_unit || target_tile, NULL);
2219 if (target_unit) {
2220 fc_assert_ret_val(unit_tile(target_unit), NULL);
2221 return tile_city(unit_tile(target_unit));
2222 }
2223
2224 fc__fallthrough;
2225 case ATK_TILE:
2226 case ATK_EXTRAS:
2227 fc_assert_ret_val(target_tile, NULL);
2228 return tile_city(target_tile);
2229 case ATK_SELF:
2230 fc_assert_ret_val(actor_unit, NULL);
2231 fc_assert_ret_val(unit_tile(actor_unit), NULL);
2232 return tile_city(unit_tile(actor_unit));
2233 case ATK_COUNT:
2234 /* Handled below. */
2235 break;
2236 }
2237
2238 fc_assert_msg(FALSE, "Bad action target kind %d for action %s",
2239 action_get_target_kind(act), action_rule_name(act));
2240 return NULL;
2241}
2242
2243/**********************************************************************/
2249 struct action *action_is_blocked_by(const struct action *act,
2250 const struct unit *actor_unit,
2251 const struct tile *target_tile_arg,
2252 const struct city *target_city_arg,
2253 const struct unit *target_unit)
2254{
2255 const struct tile *target_tile
2256 = blocked_find_target_tile(act, actor_unit, target_tile_arg,
2257 target_city_arg, target_unit);
2258 const struct city *target_city
2259 = blocked_find_target_city(act, actor_unit, target_tile,
2260 target_city_arg, target_unit);
2261 const struct civ_map *nmap = &(wld.map);
2262
2263 action_iterate(blocker_id) {
2264 struct action *blocker = action_by_number(blocker_id);
2265
2266 fc_assert_action(action_get_actor_kind(blocker) == AAK_UNIT,
2267 continue);
2268
2269 if (!action_would_be_blocked_by(act, blocker)) {
2270 /* It doesn't matter if it is legal. It won't block the action. */
2271 continue;
2272 }
2273
2274 switch (action_get_target_kind(blocker)) {
2275 case ATK_CITY:
2276 if (!target_city) {
2277 /* Can't be enabled. No target. */
2278 continue;
2279 }
2280 if (is_action_enabled_unit_on_city(nmap, blocker->id,
2281 actor_unit, target_city)) {
2282 return blocker;
2283 }
2284 break;
2285 case ATK_UNIT:
2286 if (!target_unit) {
2287 /* Can't be enabled. No target. */
2288 continue;
2289 }
2290 if (is_action_enabled_unit_on_unit(nmap, blocker->id,
2291 actor_unit, target_unit)) {
2292 return blocker;
2293 }
2294 break;
2295 case ATK_UNITS:
2296 if (!target_tile) {
2297 /* Can't be enabled. No target. */
2298 continue;
2299 }
2300 if (is_action_enabled_unit_on_stack(nmap, blocker->id,
2301 actor_unit, target_tile)) {
2302 return blocker;
2303 }
2304 break;
2305 case ATK_TILE:
2306 if (!target_tile) {
2307 /* Can't be enabled. No target. */
2308 continue;
2309 }
2310 if (is_action_enabled_unit_on_tile(nmap, blocker->id,
2311 actor_unit, target_tile, NULL)) {
2312 return blocker;
2313 }
2314 break;
2315 case ATK_EXTRAS:
2316 if (!target_tile) {
2317 /* Can't be enabled. No target. */
2318 continue;
2319 }
2320 if (is_action_enabled_unit_on_extras(nmap, blocker->id,
2321 actor_unit, target_tile, NULL)) {
2322 return blocker;
2323 }
2324 break;
2325 case ATK_SELF:
2326 if (is_action_enabled_unit_on_self(nmap, blocker->id, actor_unit)) {
2327 return blocker;
2328 }
2329 break;
2330 case ATK_COUNT:
2331 fc_assert_action(action_id_get_target_kind(blocker->id) != ATK_COUNT,
2332 continue);
2333 break;
2334 }
2335 } action_iterate_end;
2336
2337 /* Not blocked. */
2338 return NULL;
2339}
2340
2341/**********************************************************************/
2361static bool
2362action_actor_utype_hard_reqs_ok_full(const struct action *paction,
2363 const struct unit_type *actor_unittype,
2364 bool ignore_third_party)
2365{
2366 switch (paction->result) {
2367 case ACTRES_JOIN_CITY:
2368 if (actor_unittype->pop_cost <= 0) {
2369 /* Reason: Must have population to add. */
2370 return FALSE;
2371 }
2372 break;
2373
2374 case ACTRES_BOMBARD:
2375 if (actor_unittype->bombard_rate <= 0) {
2376 /* Reason: Can't bombard if it never fires. */
2377 return FALSE;
2378 }
2379
2380 if (actor_unittype->attack_strength <= 0) {
2381 /* Reason: Can't bombard without attack strength. */
2382 return FALSE;
2383 }
2384
2385 break;
2386
2387 case ACTRES_UPGRADE_UNIT:
2388 if (actor_unittype->obsoleted_by == U_NOT_OBSOLETED) {
2389 /* Reason: Nothing to upgrade to. */
2390 return FALSE;
2391 }
2392 break;
2393
2394 case ACTRES_ATTACK:
2395 case ACTRES_WIPE_UNITS:
2396 case ACTRES_COLLECT_RANSOM:
2397 if (actor_unittype->attack_strength <= 0) {
2398 /* Reason: Can't attack without strength. */
2399 return FALSE;
2400 }
2401 break;
2402
2403 case ACTRES_CONVERT:
2404 if (!actor_unittype->converted_to) {
2405 /* Reason: must be able to convert to something. */
2406 return FALSE;
2407 }
2408 break;
2409
2410 case ACTRES_TRANSPORT_UNLOAD:
2411 if (actor_unittype->transport_capacity < 1) {
2412 /* Reason: can't transport anything to unload. */
2413 return FALSE;
2414 }
2415 break;
2416
2417 case ACTRES_TRANSPORT_LOAD:
2418 if (actor_unittype->transport_capacity < 1) {
2419 /* Reason: can't transport anything to load. */
2420 return FALSE;
2421 }
2422 break;
2423
2424 case ACTRES_TRANSPORT_BOARD:
2425 case ACTRES_TRANSPORT_EMBARK:
2426 case ACTRES_TRANSPORT_DEBOARD:
2427 case ACTRES_TRANSPORT_DISEMBARK:
2428 if (!ignore_third_party) {
2429 bool has_transporter = FALSE;
2430
2431 unit_type_iterate(utrans) {
2432 if (can_unit_type_transport(utrans, utype_class(actor_unittype))) {
2433 has_transporter = TRUE;
2434 break;
2435 }
2436 } unit_type_iterate_end;
2437
2438 if (!has_transporter) {
2439 /* Reason: no other unit can transport this unit. */
2440 return FALSE;
2441 }
2442 }
2443 break;
2444
2445 case ACTRES_CONQUER_EXTRAS:
2446 if (!ignore_third_party) {
2447 bool has_target = FALSE;
2448 struct unit_class *pclass = utype_class(actor_unittype);
2449
2450 /* Use cache when it has been initialized */
2451 if (pclass->cache.native_bases != NULL) {
2452 /* Extra being native one is a hard requirement */
2453 extra_type_list_iterate(pclass->cache.native_bases, pextra) {
2454 if (!territory_claiming_base(pextra->data.base)) {
2455 /* Hard requirement */
2456 continue;
2457 }
2458
2459 has_target = TRUE;
2460 break;
2461 } extra_type_list_iterate_end;
2462 } else {
2463 struct extra_type_list *terr_claimers = extra_type_list_of_terr_claimers();
2464
2465 extra_type_list_iterate(terr_claimers, pextra) {
2466 if (!is_native_extra_to_uclass(pextra, pclass)) {
2467 /* Hard requirement */
2468 continue;
2469 }
2470
2471 has_target = TRUE;
2472 break;
2473 } extra_type_list_iterate_end;
2474 }
2475
2476 if (!has_target) {
2477 /* Reason: no extras can be conquered by this unit. */
2478 return FALSE;
2479 }
2480 }
2481 break;
2482
2483 case ACTRES_PARADROP:
2484 case ACTRES_PARADROP_CONQUER:
2485 if (actor_unittype->paratroopers_range <= 0) {
2486 /* Reason: Can't paradrop 0 tiles. */
2487 return FALSE;
2488 }
2489 break;
2490
2491 case ACTRES_HUT_ENTER:
2492 case ACTRES_HUT_FRIGHTEN:
2493 case ACTRES_ESTABLISH_EMBASSY:
2494 case ACTRES_SPY_INVESTIGATE_CITY:
2495 case ACTRES_SPY_POISON:
2496 case ACTRES_SPY_STEAL_GOLD:
2497 case ACTRES_SPY_SPREAD_PLAGUE:
2498 case ACTRES_SPY_SABOTAGE_CITY:
2499 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2500 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2501 case ACTRES_SPY_STEAL_TECH:
2502 case ACTRES_SPY_TARGETED_STEAL_TECH:
2503 case ACTRES_SPY_INCITE_CITY:
2504 case ACTRES_SPY_ESCAPE:
2505 case ACTRES_TRADE_ROUTE:
2506 case ACTRES_MARKETPLACE:
2507 case ACTRES_HELP_WONDER:
2508 case ACTRES_SPY_BRIBE_UNIT:
2509 case ACTRES_SPY_SABOTAGE_UNIT:
2510 case ACTRES_CAPTURE_UNITS:
2511 case ACTRES_FOUND_CITY:
2512 case ACTRES_STEAL_MAPS:
2513 case ACTRES_SPY_NUKE:
2514 case ACTRES_NUKE:
2515 case ACTRES_NUKE_UNITS:
2516 case ACTRES_DESTROY_CITY:
2517 case ACTRES_EXPEL_UNIT:
2518 case ACTRES_DISBAND_UNIT_RECOVER:
2519 case ACTRES_DISBAND_UNIT:
2520 case ACTRES_HOME_CITY:
2521 case ACTRES_HOMELESS:
2522 case ACTRES_AIRLIFT:
2523 case ACTRES_STRIKE_BUILDING:
2524 case ACTRES_STRIKE_PRODUCTION:
2525 case ACTRES_CONQUER_CITY:
2526 case ACTRES_HEAL_UNIT:
2527 case ACTRES_PILLAGE:
2528 case ACTRES_CLEAN:
2529 case ACTRES_FORTIFY:
2530 case ACTRES_TRANSFORM_TERRAIN:
2531 case ACTRES_CULTIVATE:
2532 case ACTRES_PLANT:
2533 case ACTRES_ROAD:
2534 case ACTRES_BASE:
2535 case ACTRES_MINE:
2536 case ACTRES_IRRIGATE:
2537 case ACTRES_SPY_ATTACK:
2538 case ACTRES_UNIT_MOVE:
2539 case ACTRES_TELEPORT:
2540 case ACTRES_TELEPORT_CONQUER:
2541 case ACTRES_ENABLER_CHECK:
2542 case ACTRES_NONE:
2543 /* No hard unit type requirements. */
2544 break;
2545
2546 ASSERT_UNUSED_ACTRES_CASES;
2547 }
2548
2549 return TRUE;
2550}
2551
2552/**********************************************************************/
2568bool
2569action_actor_utype_hard_reqs_ok(const struct action *paction,
2570 const struct unit_type *actor_unittype)
2571{
2572 return action_actor_utype_hard_reqs_ok_full(paction,
2573 actor_unittype, FALSE);
2574}
2575
2576/**********************************************************************/
2588static enum fc_tristate
2589action_hard_reqs_actor(const struct civ_map *nmap,
2590 const struct action *paction,
2591 const struct req_context *actor,
2592 const bool omniscient,
2593 const struct city *homecity)
2594{
2595 enum action_result result = paction->result;
2596
2597 if (actor == NULL) {
2598 actor = req_context_empty();
2599 }
2600
2601 if (!action_actor_utype_hard_reqs_ok_full(paction, actor->unittype,
2602 TRUE)) {
2603 /* Info leak: The actor player knows the type of their unit. */
2604 /* The actor unit type can't perform the action because of hard
2605 * unit type requirements. */
2606 return TRI_NO;
2607 }
2608
2609 switch (result) {
2610 case ACTRES_PARADROP:
2611 case ACTRES_PARADROP_CONQUER:
2612 /* Reason: Keep the old rules. */
2613 /* Info leak: The player knows if their unit already has paradropped this
2614 * turn. */
2615 if (actor->unit->paradropped) {
2616 return TRI_NO;
2617 }
2618
2619 break;
2620
2621 case ACTRES_AIRLIFT:
2622 {
2623 /* Obligatory hard requirement. Checked here too since
2624 * action_hard_reqs_actor() may be called before any
2625 * action enablers are checked. */
2626 if (actor->city == NULL) {
2627 /* No city to airlift from. */
2628 return TRI_NO;
2629 }
2630
2631 if (actor->player != city_owner(actor->city)
2632 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_SRC
2633 && pplayers_allied(actor->player,
2634 city_owner(actor->city)))) {
2635 /* Not allowed to airlift from this source. */
2636 return TRI_NO;
2637 }
2638
2639 if (!(omniscient || city_owner(actor->city) == actor->player)) {
2640 /* Can't check for airlifting capacity. */
2641 return TRI_MAYBE;
2642 }
2643
2644 if (0 >= actor->city->airlift
2645 && (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)
2646 || !game.info.airlift_from_always_enabled)) {
2647 /* The source cannot airlift for this turn (maybe already airlifted
2648 * or no airport).
2649 *
2650 * See also do_airline() in server/unittools.h. */
2651 return TRI_NO;
2652 }
2653 }
2654 break;
2655
2656 case ACTRES_CONVERT:
2657 /* Reason: Keep the old rules. */
2658 /* Info leak: The player knows their unit's cargo and location. */
2659 if (!unit_can_convert(nmap, actor->unit)) {
2660 return TRI_NO;
2661 }
2662 break;
2663
2664 case ACTRES_TRANSPORT_BOARD:
2665 case ACTRES_TRANSPORT_EMBARK:
2666 if (unit_transported(actor->unit)) {
2667 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
2668 /* Can't leave current transport. */
2669 return TRI_NO;
2670 }
2671 }
2672 break;
2673
2674 case ACTRES_TRANSPORT_DISEMBARK:
2675 if (!can_unit_unload(actor->unit, unit_transport_get(actor->unit))) {
2676 /* Keep the old rules about Unreachable and disembarks. */
2677 return TRI_NO;
2678 }
2679 break;
2680
2681 case ACTRES_HOMELESS:
2682 case ACTRES_UNIT_MOVE:
2683 case ACTRES_TELEPORT:
2684 case ACTRES_TELEPORT_CONQUER:
2685 case ACTRES_ESTABLISH_EMBASSY:
2686 case ACTRES_SPY_INVESTIGATE_CITY:
2687 case ACTRES_SPY_POISON:
2688 case ACTRES_SPY_STEAL_GOLD:
2689 case ACTRES_SPY_SPREAD_PLAGUE:
2690 case ACTRES_SPY_SABOTAGE_CITY:
2691 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2692 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2693 case ACTRES_SPY_STEAL_TECH:
2694 case ACTRES_SPY_TARGETED_STEAL_TECH:
2695 case ACTRES_SPY_INCITE_CITY:
2696 case ACTRES_SPY_ESCAPE:
2697 case ACTRES_TRADE_ROUTE:
2698 case ACTRES_MARKETPLACE:
2699 case ACTRES_HELP_WONDER:
2700 case ACTRES_SPY_BRIBE_UNIT:
2701 case ACTRES_SPY_SABOTAGE_UNIT:
2702 case ACTRES_CAPTURE_UNITS:
2703 case ACTRES_FOUND_CITY:
2704 case ACTRES_JOIN_CITY:
2705 case ACTRES_STEAL_MAPS:
2706 case ACTRES_BOMBARD:
2707 case ACTRES_SPY_NUKE:
2708 case ACTRES_NUKE:
2709 case ACTRES_NUKE_UNITS:
2710 case ACTRES_DESTROY_CITY:
2711 case ACTRES_EXPEL_UNIT:
2712 case ACTRES_DISBAND_UNIT_RECOVER:
2713 case ACTRES_DISBAND_UNIT:
2714 case ACTRES_HOME_CITY:
2715 case ACTRES_UPGRADE_UNIT:
2716 case ACTRES_ATTACK:
2717 case ACTRES_WIPE_UNITS:
2718 case ACTRES_COLLECT_RANSOM:
2719 case ACTRES_STRIKE_BUILDING:
2720 case ACTRES_STRIKE_PRODUCTION:
2721 case ACTRES_CONQUER_CITY:
2722 case ACTRES_CONQUER_EXTRAS:
2723 case ACTRES_HEAL_UNIT:
2724 case ACTRES_TRANSFORM_TERRAIN:
2725 case ACTRES_CULTIVATE:
2726 case ACTRES_PLANT:
2727 case ACTRES_PILLAGE:
2728 case ACTRES_CLEAN:
2729 case ACTRES_FORTIFY:
2730 case ACTRES_ROAD:
2731 case ACTRES_BASE:
2732 case ACTRES_MINE:
2733 case ACTRES_IRRIGATE:
2734 case ACTRES_TRANSPORT_DEBOARD:
2735 case ACTRES_TRANSPORT_UNLOAD:
2736 case ACTRES_TRANSPORT_LOAD:
2737 case ACTRES_SPY_ATTACK:
2738 case ACTRES_HUT_ENTER:
2739 case ACTRES_HUT_FRIGHTEN:
2740 case ACTRES_ENABLER_CHECK:
2741 case ACTRES_NONE:
2742 /* No hard unit requirements. */
2743 break;
2744
2745 ASSERT_UNUSED_ACTRES_CASES;
2746 }
2747
2748 return TRI_YES;
2749}
2750
2751/**********************************************************************/
2774static enum fc_tristate
2775is_action_possible(const struct civ_map *nmap,
2776 const action_id wanted_action,
2777 const struct req_context *actor,
2778 const struct req_context *target,
2779 const struct extra_type *target_extra,
2780 const bool omniscient,
2781 const struct city *homecity)
2782{
2783 enum fc_tristate out;
2784 struct action *paction = action_by_number(wanted_action);
2785 enum action_target_kind tkind = action_get_target_kind(paction);
2786
2787 if (actor == NULL) {
2788 actor = req_context_empty();
2789 }
2790 if (target == NULL) {
2791 target = req_context_empty();
2792 }
2793
2794 fc_assert_msg((tkind == ATK_CITY && target->city != NULL)
2795 || (tkind == ATK_TILE && target->tile != NULL)
2796 || (tkind == ATK_EXTRAS && target->tile != NULL)
2797 || (tkind == ATK_UNIT && target->unit != NULL)
2798 /* At this level each individual unit is tested. */
2799 || (tkind == ATK_UNITS && target->unit != NULL)
2800 || (tkind == ATK_SELF),
2801 "Missing target!");
2802
2803 /* Info leak: The player knows where their unit is. */
2804 if (tkind != ATK_SELF
2805 && !action_distance_accepted(paction,
2806 real_map_distance(actor->tile,
2807 target->tile))) {
2808 /* The distance between the actor and the target isn't inside the
2809 * action's accepted range. */
2810 return TRI_NO;
2811 }
2812
2813 switch (tkind) {
2814 case ATK_UNIT:
2815 /* The Freeciv code for all actions that is controlled by action
2816 * enablers and targets a unit assumes that the acting
2817 * player can see the target unit.
2818 * Examples:
2819 * - action_prob_vs_unit()'s quick check that the distance between actor
2820 * and target is acceptable would leak distance to target unit if the
2821 * target unit can't be seen.
2822 */
2823 if (!can_player_see_unit(actor->player, target->unit)) {
2824 return TRI_NO;
2825 }
2826 break;
2827 case ATK_CITY:
2828 /* The Freeciv code assumes that the player is aware of the target
2829 * city's existence. (How can you order an airlift to a city when you
2830 * don't know its city ID?) */
2831 if (fc_funcs->player_tile_city_id_get(city_tile(target->city),
2832 actor->player)
2833 != target->city->id) {
2834 return TRI_NO;
2835 }
2836 break;
2837 case ATK_UNITS:
2838 case ATK_TILE:
2839 case ATK_EXTRAS:
2840 case ATK_SELF:
2841 /* No special player knowledge checks. */
2842 break;
2843 case ATK_COUNT:
2844 fc_assert(tkind != ATK_COUNT);
2845 break;
2846 }
2847
2848 if (action_is_blocked_by(paction, actor->unit,
2849 target->tile, target->city, target->unit)) {
2850 /* Allows an action to block an other action. If a blocking action is
2851 * legal the actions it blocks becomes illegal. */
2852 return TRI_NO;
2853 }
2854
2855 /* Actor specific hard requirements. */
2856 out = action_hard_reqs_actor(nmap, paction, actor, omniscient, homecity);
2857
2858 if (out == TRI_NO) {
2859 /* Illegal because of a hard actor requirement. */
2860 return TRI_NO;
2861 }
2862
2863 /* Quick checks for action itself */
2864 if (paction->result == ACTRES_ATTACK
2865 || paction->result == ACTRES_WIPE_UNITS
2866 || paction->result == ACTRES_COLLECT_RANSOM) {
2867 /* Reason: Keep the old rules. */
2868 if (!can_unit_attack_tile(actor->unit, paction, target->tile)) {
2869 return TRI_NO;
2870 }
2871 }
2872
2873 /* Hard requirements for results. */
2874 out = actres_possible(nmap,
2875 paction->result, actor,
2876 target, target_extra, out, omniscient,
2877 homecity);
2878
2879 if (out == TRI_NO) {
2880 /* Illegal because of a hard actor requirement. */
2881 return TRI_NO;
2882 }
2883
2884 if (paction->result == ACTRES_NUKE_UNITS) {
2885 if (unit_attack_units_at_tile_result(actor->unit, paction,
2886 target->tile)
2887 != ATT_OK) {
2888 /* Unreachable. */
2889 return TRI_NO;
2890 }
2891 } else if (paction->result == ACTRES_PARADROP
2892 || paction->result == ACTRES_PARADROP_CONQUER) {
2893 if (can_player_see_tile(actor->player, target->tile)) {
2894 /* Check for seen stuff that may kill the actor unit. */
2895
2896 /* Reason: Keep the old rules. Be merciful. */
2897 /* Info leak: The player sees the target tile. */
2898 if (!can_unit_exist_at_tile(nmap, actor->unit, target->tile)
2899 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
2900 || !unit_could_load_at(actor->unit, target->tile))) {
2901 return TRI_NO;
2902 }
2903
2904 /* Reason: Keep the old rules. Be merciful. */
2905 /* Info leak: The player sees the target tile. */
2906 if (is_non_attack_city_tile(target->tile, actor->player)) {
2907 return TRI_NO;
2908 }
2909
2910 /* Reason: Be merciful. */
2911 /* Info leak: The player sees all units checked. Invisible units are
2912 * ignored. */
2913 unit_list_iterate(target->tile->units, pother) {
2914 if (can_player_see_unit(actor->player, pother)
2915 && !pplayers_allied(actor->player, unit_owner(pother))) {
2916 return TRI_NO;
2917 }
2918 } unit_list_iterate_end;
2919 }
2920 }
2921
2922 return out;
2923}
2924
2925/**********************************************************************/
2931 static bool is_enabler_active(const struct action_enabler *enabler,
2932 const struct req_context *actor,
2933 const struct req_context *target)
2934{
2935 return are_reqs_active(actor, target, &enabler->actor_reqs, RPT_CERTAIN)
2936 && are_reqs_active(target, actor, &enabler->target_reqs, RPT_CERTAIN);
2937}
2938
2939/**********************************************************************/
2948 static bool is_action_enabled(const struct civ_map *nmap,
2949 const action_id wanted_action,
2950 const struct req_context *actor,
2951 const struct req_context *target,
2952 const struct extra_type *target_extra,
2953 const struct city *actor_home)
2954{
2955 enum fc_tristate possible;
2956
2957 possible = is_action_possible(nmap, wanted_action, actor, target, target_extra,
2958 TRUE, actor_home);
2959
2960 if (possible != TRI_YES) {
2961 /* This context is omniscient. Should be yes or no. */
2962 fc_assert_msg(possible != TRI_MAYBE,
2963 "Is omniscient, should get yes or no.");
2964
2965 /* The action enablers are irrelevant since the action it self is
2966 * impossible. */
2967 return FALSE;
2968 }
2969
2970 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
2971 enabler) {
2972 if (is_enabler_active(enabler, actor, target)) {
2973 return TRUE;
2974 }
2975 } action_enabler_list_iterate_end;
2976
2977 return FALSE;
2978}
2979
2980/**********************************************************************/
2986static bool
2987is_action_enabled_unit_on_city_full(const struct civ_map *nmap,
2988 const action_id wanted_action,
2989 const struct unit *actor_unit,
2990 const struct city *actor_home,
2991 const struct tile *actor_tile,
2992 const struct city *target_city)
2993{
2994 const struct impr_type *target_building;
2995 const struct unit_type *target_utype;
2996
2997 if (actor_unit == NULL || target_city == NULL) {
2998 /* Can't do an action when actor or target are missing. */
2999 return FALSE;
3000 }
3001
3002 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3003 FALSE, "Action %s is performed by %s not %s",
3004 action_id_rule_name(wanted_action),
3005 action_actor_kind_name(
3006 action_id_get_actor_kind(wanted_action)),
3007 action_actor_kind_name(AAK_UNIT));
3008
3009 fc_assert_ret_val_msg(ATK_CITY
3010 == action_id_get_target_kind(wanted_action),
3011 FALSE, "Action %s is against %s not %s",
3012 action_id_rule_name(wanted_action),
3013 action_target_kind_name(
3014 action_id_get_target_kind(wanted_action)),
3015 action_target_kind_name(ATK_CITY));
3016
3017 fc_assert_ret_val(actor_tile, FALSE);
3018
3019 if (!unit_can_do_action(actor_unit, wanted_action)) {
3020 /* No point in continuing. */
3021 return FALSE;
3022 }
3023
3024 target_building = tgt_city_local_building(target_city);
3025 target_utype = tgt_city_local_utype(target_city);
3026
3027 return is_action_enabled(nmap, wanted_action,
3028 &(const struct req_context) {
3029 .player = unit_owner(actor_unit),
3030 .city = tile_city(actor_tile),
3031 .tile = actor_tile,
3032 .unit = actor_unit,
3033 .unittype = unit_type_get(actor_unit),
3034 },
3035 &(const struct req_context) {
3036 .player = city_owner(target_city),
3037 .city = target_city,
3038 .building = target_building,
3039 .tile = city_tile(target_city),
3040 .unittype = target_utype,
3041 },
3042 NULL,
3043 actor_home);
3044}
3045
3046/**********************************************************************/
3052 bool is_action_enabled_unit_on_city(const struct civ_map *nmap,
3053 const action_id wanted_action,
3054 const struct unit *actor_unit,
3055 const struct city *target_city)
3056{
3057 return is_action_enabled_unit_on_city_full(nmap, wanted_action, actor_unit,
3058 unit_home(actor_unit),
3059 unit_tile(actor_unit),
3060 target_city);
3061}
3062
3063/**********************************************************************/
3069static bool
3070is_action_enabled_unit_on_unit_full(const struct civ_map *nmap,
3071 const action_id wanted_action,
3072 const struct unit *actor_unit,
3073 const struct city *actor_home,
3074 const struct tile *actor_tile,
3075 const struct unit *target_unit)
3076{
3077 if (actor_unit == NULL || target_unit == NULL) {
3078 /* Can't do an action when actor or target are missing. */
3079 return FALSE;
3080 }
3081
3082 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3083 FALSE, "Action %s is performed by %s not %s",
3084 action_id_rule_name(wanted_action),
3085 action_actor_kind_name(
3086 action_id_get_actor_kind(wanted_action)),
3087 action_actor_kind_name(AAK_UNIT));
3088
3089 fc_assert_ret_val_msg(ATK_UNIT
3090 == action_id_get_target_kind(wanted_action),
3091 FALSE, "Action %s is against %s not %s",
3092 action_id_rule_name(wanted_action),
3093 action_target_kind_name(
3094 action_id_get_target_kind(wanted_action)),
3095 action_target_kind_name(ATK_UNIT));
3096
3097 fc_assert_ret_val(actor_tile, FALSE);
3098
3099 if (!unit_can_do_action(actor_unit, wanted_action)) {
3100 /* No point in continuing. */
3101 return FALSE;
3102 }
3103
3104 return is_action_enabled(nmap, wanted_action,
3105 &(const struct req_context) {
3106 .player = unit_owner(actor_unit),
3107 .city = tile_city(actor_tile),
3108 .tile = actor_tile,
3109 .unit = actor_unit,
3110 .unittype = unit_type_get(actor_unit),
3111 },
3112 &(const struct req_context) {
3113 .player = unit_owner(target_unit),
3114 .city = tile_city(unit_tile(target_unit)),
3115 .tile = unit_tile(target_unit),
3116 .unit = target_unit,
3117 .unittype = unit_type_get(target_unit),
3118 },
3119 NULL,
3120 actor_home);
3121}
3122
3123/**********************************************************************/
3129 bool is_action_enabled_unit_on_unit(const struct civ_map *nmap,
3130 const action_id wanted_action,
3131 const struct unit *actor_unit,
3132 const struct unit *target_unit)
3133{
3134 return is_action_enabled_unit_on_unit_full(nmap, wanted_action, actor_unit,
3135 unit_home(actor_unit),
3136 unit_tile(actor_unit),
3137 target_unit);
3138}
3139
3140/**********************************************************************/
3146static bool
3147is_action_enabled_unit_on_stack_full(const struct civ_map *nmap,
3148 const action_id wanted_action,
3149 const struct unit *actor_unit,
3150 const struct city *actor_home,
3151 const struct tile *actor_tile,
3152 const struct tile *target_tile)
3153{
3154 const struct req_context *actor_ctxt;
3155
3156 if (actor_unit == NULL || target_tile == NULL
3157 || unit_list_size(target_tile->units) == 0) {
3158 /* Can't do an action when actor or target are missing. */
3159 return FALSE;
3160 }
3161
3162 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3163 FALSE, "Action %s is performed by %s not %s",
3164 action_id_rule_name(wanted_action),
3165 action_actor_kind_name(
3166 action_id_get_actor_kind(wanted_action)),
3167 action_actor_kind_name(AAK_UNIT));
3168
3169 fc_assert_ret_val_msg(ATK_UNITS
3170 == action_id_get_target_kind(wanted_action),
3171 FALSE, "Action %s is against %s not %s",
3172 action_id_rule_name(wanted_action),
3173 action_target_kind_name(
3174 action_id_get_target_kind(wanted_action)),
3175 action_target_kind_name(ATK_UNITS));
3176
3177 fc_assert_ret_val(actor_tile, FALSE);
3178
3179 if (!unit_can_do_action(actor_unit, wanted_action)) {
3180 /* No point in continuing. */
3181 return FALSE;
3182 }
3183
3184 actor_ctxt = &(const struct req_context) {
3185 .player = unit_owner(actor_unit),
3186 .city = tile_city(actor_tile),
3187 .tile = actor_tile,
3188 .unit = actor_unit,
3189 .unittype = unit_type_get(actor_unit),
3190 };
3191
3192 unit_list_iterate(target_tile->units, target_unit) {
3193 if (!is_action_enabled(nmap, wanted_action, actor_ctxt,
3194 &(const struct req_context) {
3195 .player = unit_owner(target_unit),
3196 .city = tile_city(unit_tile(target_unit)),
3197 .tile = unit_tile(target_unit),
3198 .unit = target_unit,
3199 .unittype = unit_type_get(target_unit),
3200 },
3201 NULL, actor_home)) {
3202 /* One unit makes it impossible for all units. */
3203 return FALSE;
3204 }
3205 } unit_list_iterate_end;
3206
3207 /* Not impossible for any of the units at the tile. */
3208 return TRUE;
3209}
3210
3211/**********************************************************************/
3217 bool is_action_enabled_unit_on_stack(const struct civ_map *nmap,
3218 const action_id wanted_action,
3219 const struct unit *actor_unit,
3220 const struct tile *target_tile)
3221{
3222 return is_action_enabled_unit_on_stack_full(nmap, wanted_action, actor_unit,
3223 unit_home(actor_unit),
3224 unit_tile(actor_unit),
3225 target_tile);
3226}
3227
3228/**********************************************************************/
3234static bool
3235is_action_enabled_unit_on_tile_full(const struct civ_map *nmap,
3236 const action_id wanted_action,
3237 const struct unit *actor_unit,
3238 const struct city *actor_home,
3239 const struct tile *actor_tile,
3240 const struct tile *target_tile,
3241 const struct extra_type *target_extra)
3242{
3243 if (actor_unit == NULL || target_tile == NULL) {
3244 /* Can't do an action when actor or target are missing. */
3245 return FALSE;
3246 }
3247
3248 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3249 FALSE, "Action %s is performed by %s not %s",
3250 action_id_rule_name(wanted_action),
3251 action_actor_kind_name(
3252 action_id_get_actor_kind(wanted_action)),
3253 action_actor_kind_name(AAK_UNIT));
3254
3255 fc_assert_ret_val_msg(ATK_TILE
3256 == action_id_get_target_kind(wanted_action),
3257 FALSE, "Action %s is against %s not %s",
3258 action_id_rule_name(wanted_action),
3259 action_target_kind_name(
3260 action_id_get_target_kind(wanted_action)),
3261 action_target_kind_name(ATK_TILE));
3262
3263 fc_assert_ret_val(actor_tile, FALSE);
3264
3265 if (!unit_can_do_action(actor_unit, wanted_action)) {
3266 /* No point in continuing. */
3267 return FALSE;
3268 }
3269
3270 return is_action_enabled(nmap, wanted_action,
3271 &(const struct req_context) {
3272 .player = unit_owner(actor_unit),
3273 .city = tile_city(actor_tile),
3274 .tile = actor_tile,
3275 .unit = actor_unit,
3276 .unittype = unit_type_get(actor_unit),
3277 },
3278 &(const struct req_context) {
3279 .player = tile_owner(target_tile),
3280 .city = tile_city(target_tile),
3281 .tile = target_tile,
3282 },
3283 target_extra,
3284 actor_home);
3285}
3286
3287/**********************************************************************/
3293 bool is_action_enabled_unit_on_tile(const struct civ_map *nmap,
3294 const action_id wanted_action,
3295 const struct unit *actor_unit,
3296 const struct tile *target_tile,
3297 const struct extra_type *target_extra)
3298{
3299 return is_action_enabled_unit_on_tile_full(nmap, wanted_action, actor_unit,
3300 unit_home(actor_unit),
3301 unit_tile(actor_unit),
3302 target_tile, target_extra);
3303}
3304
3305/**********************************************************************/
3311static bool
3312is_action_enabled_unit_on_extras_full(const struct civ_map *nmap,
3313 const action_id wanted_action,
3314 const struct unit *actor_unit,
3315 const struct city *actor_home,
3316 const struct tile *actor_tile,
3317 const struct tile *target_tile,
3318 const struct extra_type *target_extra)
3319{
3320 if (actor_unit == NULL || target_tile == NULL) {
3321 /* Can't do an action when actor or target are missing. */
3322 return FALSE;
3323 }
3324
3325 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3326 FALSE, "Action %s is performed by %s not %s",
3327 action_id_rule_name(wanted_action),
3328 action_actor_kind_name(
3329 action_id_get_actor_kind(wanted_action)),
3330 action_actor_kind_name(AAK_UNIT));
3331
3332 fc_assert_ret_val_msg(ATK_EXTRAS
3333 == action_id_get_target_kind(wanted_action),
3334 FALSE, "Action %s is against %s not %s",
3335 action_id_rule_name(wanted_action),
3336 action_target_kind_name(
3337 action_id_get_target_kind(wanted_action)),
3338 action_target_kind_name(ATK_EXTRAS));
3339
3340 fc_assert_ret_val(actor_tile, FALSE);
3341
3342 if (!unit_can_do_action(actor_unit, wanted_action)) {
3343 /* No point in continuing. */
3344 return FALSE;
3345 }
3346
3347 return is_action_enabled(nmap, wanted_action,
3348 &(const struct req_context) {
3349 .player = unit_owner(actor_unit),
3350 .city = tile_city(actor_tile),
3351 .tile = actor_tile,
3352 .unit = actor_unit,
3353 .unittype = unit_type_get(actor_unit),
3354 },
3355 &(const struct req_context) {
3356 .player = target_tile->extras_owner,
3357 .city = tile_city(target_tile),
3358 .tile = target_tile,
3359 },
3360 target_extra,
3361 actor_home);
3362}
3363
3364/**********************************************************************/
3370 bool is_action_enabled_unit_on_extras(const struct civ_map *nmap,
3371 const action_id wanted_action,
3372 const struct unit *actor_unit,
3373 const struct tile *target_tile,
3374 const struct extra_type *target_extra)
3375{
3376 return is_action_enabled_unit_on_extras_full(nmap, wanted_action, actor_unit,
3377 unit_home(actor_unit),
3378 unit_tile(actor_unit),
3379 target_tile, target_extra);
3380}
3381
3382/**********************************************************************/
3389static bool
3390is_action_enabled_unit_on_self_full(const struct civ_map *nmap,
3391 const action_id wanted_action,
3392 const struct unit *actor_unit,
3393 const struct city *actor_home,
3394 const struct tile *actor_tile)
3395{
3396 if (actor_unit == NULL) {
3397 /* Can't do an action when the actor is missing. */
3398 return FALSE;
3399 }
3400
3401 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
3402 FALSE, "Action %s is performed by %s not %s",
3403 action_id_rule_name(wanted_action),
3404 action_actor_kind_name(
3405 action_id_get_actor_kind(wanted_action)),
3406 action_actor_kind_name(AAK_UNIT));
3407
3408 fc_assert_ret_val_msg(ATK_SELF
3409 == action_id_get_target_kind(wanted_action),
3410 FALSE, "Action %s is against %s not %s",
3411 action_id_rule_name(wanted_action),
3412 action_target_kind_name(
3413 action_id_get_target_kind(wanted_action)),
3414 action_target_kind_name(ATK_SELF));
3415
3416 fc_assert_ret_val(actor_tile, FALSE);
3417
3418 if (!unit_can_do_action(actor_unit, wanted_action)) {
3419 /* No point in continuing. */
3420 return FALSE;
3421 }
3422
3423 return is_action_enabled(nmap, wanted_action,
3424 &(const struct req_context) {
3425 .player = unit_owner(actor_unit),
3426 .city = tile_city(actor_tile),
3427 .tile = actor_tile,
3428 .unit = actor_unit,
3429 .unittype = unit_type_get(actor_unit),
3430 },
3431 NULL, NULL,
3432 actor_home);
3433}
3434
3435/**********************************************************************/
3442 bool is_action_enabled_unit_on_self(const struct civ_map *nmap,
3443 const action_id wanted_action,
3444 const struct unit *actor_unit)
3445{
3446 return is_action_enabled_unit_on_self_full(nmap, wanted_action, actor_unit,
3447 unit_home(actor_unit),
3448 unit_tile(actor_unit));
3449}
3450
3451/**********************************************************************/
3469static enum fc_tristate
3470action_enabled_local(const action_id wanted_action,
3471 const struct req_context *actor,
3472 const struct req_context *target)
3473{
3474 enum fc_tristate current;
3475 enum fc_tristate result;
3476
3477 if (actor == NULL || actor->player == NULL) {
3478 /* Need actor->player for point of view */
3479 return TRI_MAYBE;
3480 }
3481
3482 if (target == NULL) {
3483 target = req_context_empty();
3484 }
3485
3486 result = TRI_NO;
3487 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
3488 enabler) {
3489 current = fc_tristate_and(mke_eval_reqs(actor->player,
3490 actor, target,
3491 &enabler->actor_reqs,
3492 RPT_CERTAIN),
3493 mke_eval_reqs(actor->player,
3494 target, actor,
3495 &enabler->target_reqs,
3496 RPT_CERTAIN));
3497 if (current == TRI_YES) {
3498 return TRI_YES;
3499 } else if (current == TRI_MAYBE) {
3500 result = TRI_MAYBE;
3501 }
3502 } action_enabler_list_iterate_end;
3503
3504 return result;
3505}
3506
3507/**********************************************************************/
3517 static bool is_effect_val_known(enum effect_type effect_type,
3518 const struct player *pov_player,
3519 const struct req_context *context,
3520 const struct req_context *other_context)
3521{
3522 effect_list_iterate(get_effects(effect_type), peffect) {
3523 if (TRI_MAYBE == mke_eval_reqs(pov_player, context, other_context,
3524 &(peffect->reqs), RPT_CERTAIN)) {
3525 return FALSE;
3526 }
3527 } effect_list_iterate_end;
3528
3529 return TRUE;
3530}
3531
3532/**********************************************************************/
3535static enum fc_tristate
3536tech_can_be_stolen(const struct player *actor_player,
3537 const struct player *target_player)
3538{
3539 const struct research *actor_research = research_get(actor_player);
3540 const struct research *target_research = research_get(target_player);
3541
3542 if (actor_research != target_research) {
3543 if (can_see_techs_of_target(actor_player, target_player)) {
3544 advance_iterate(padvance) {
3545 Tech_type_id i = advance_number(padvance);
3546
3547 if (research_invention_state(target_research, i) == TECH_KNOWN
3548 && research_invention_gettable(actor_research, i,
3549 game.info.tech_steal_allow_holes)
3550 && (research_invention_state(actor_research, i) == TECH_UNKNOWN
3551 || (research_invention_state(actor_research, i)
3552 == TECH_PREREQS_KNOWN))) {
3553 return TRI_YES;
3554 }
3555 } advance_iterate_end;
3556 } else {
3557 return TRI_MAYBE;
3558 }
3559 }
3560
3561 return TRI_NO;
3562}
3563
3564/**********************************************************************/
3572 static struct act_prob ap_dipl_battle_win(const struct unit *pattacker,
3573 const struct unit *pdefender)
3574{
3575 /* Keep unconverted until the end to avoid scaling each step */
3576 int chance;
3577 struct act_prob out;
3578
3579 /* Superspy always win */
3580 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
3581 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
3582 return ACTPROB_IMPOSSIBLE;
3583 }
3584 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
3585 /* An attacking UTYF_SUPERSPY will defeat every possible defender
3586 * except another UTYF_SUPERSPY. */
3587 return ACTPROB_CERTAIN;
3588 }
3589
3590 /* Base chance is 50% */
3591 chance = 50;
3592
3593 /* Spy attack bonus */
3594 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
3595 chance += 25;
3596 }
3597
3598 /* Spy defense bonus */
3599 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
3600 chance -= 25;
3601 }
3602
3603 /* Veteran attack and defense bonus */
3604 {
3605 const struct veteran_level *vatt =
3606 utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
3607 const struct veteran_level *vdef =
3608 utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
3609
3610 chance += vatt->power_fact - vdef->power_fact;
3611 }
3612
3613 /* Defense bonus. */
3614 {
3615 const struct req_context defender_ctxt = {
3616 .player = tile_owner(pdefender->tile),
3617 .city = tile_city(pdefender->tile),
3618 .tile = pdefender->tile,
3619 };
3620 if (!is_effect_val_known(EFT_SPY_RESISTANT, unit_owner(pattacker),
3621 &defender_ctxt,
3622 NULL)) {
3623 return ACTPROB_NOT_KNOWN;
3624 }
3625
3626 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
3627 chance -= chance * get_target_bonus_effects(
3628 NULL,
3629 &defender_ctxt,
3630 NULL,
3631 EFT_SPY_RESISTANT
3632 ) / 100;
3633 }
3634
3635 chance = CLIP(0, chance, 100);
3636
3637 /* Convert to action probability */
3638 out.min = chance * ACTPROB_VAL_1_PCT;
3639 out.max = chance * ACTPROB_VAL_1_PCT;
3640
3641 return out;
3642}
3643
3644/**********************************************************************/
3649 static struct act_prob ap_diplomat_battle(const struct unit *pattacker,
3650 const struct unit *pvictim,
3651 const struct tile *tgt_tile,
3652 const struct action *paction)
3653{
3654 struct unit *pdefender;
3655
3656 if (!can_player_see_hypotetic_units_at(unit_owner(pattacker),
3657 tgt_tile)) {
3658 /* Don't leak information about unseen defenders. */
3659 return ACTPROB_NOT_KNOWN;
3660 }
3661
3662 pdefender = get_diplomatic_defender(pattacker, pvictim, tgt_tile,
3663 paction);
3664
3665 if (pdefender) {
3666 /* There will be a diplomatic battle instead of an action. */
3667 return ap_dipl_battle_win(pattacker, pdefender);
3668 };
3669
3670 /* No diplomatic battle will occur. */
3671 return ACTPROB_CERTAIN;
3672}
3673
3674/**********************************************************************/
3677 static struct act_prob act_prob_unseen_target(const struct civ_map *nmap,
3678 action_id act_id,
3679 const struct unit *actor_unit)
3680{
3681 if (action_maybe_possible_actor_unit(nmap, act_id, actor_unit)) {
3682 /* Unknown because the target is unseen. */
3683 return ACTPROB_NOT_KNOWN;
3684 } else {
3685 /* The actor it self can't do this. */
3686 return ACTPROB_IMPOSSIBLE;
3687 }
3688}
3689
3690/**********************************************************************/
3694static struct act_prob
3695action_prob_pre_action_dice_roll(const struct player *act_player,
3696 const struct unit *act_unit,
3697 const struct city *tgt_city,
3698 const struct player *tgt_player,
3699 const struct action *paction)
3700{
3701 if (is_effect_val_known(EFT_ACTION_ODDS_PCT, act_player,
3702 &(const struct req_context) {
3703 .player = act_player,
3704 .city = tgt_city,
3705 .unit = act_unit,
3706 .unittype = unit_type_get(act_unit),
3707 },
3708 &(const struct req_context) {
3709 .player = tgt_player,
3710 })
3711 && is_effect_val_known(EFT_ACTION_RESIST_PCT, act_player,
3712 &(const struct req_context) {
3713 .player = tgt_player,
3714 .city = tgt_city,
3715 .unit = act_unit,
3716 },
3717 &(const struct req_context) {
3718 .player = act_player,
3719 })) {
3720 int unconverted = action_dice_roll_odds(act_player, act_unit, tgt_city,
3721 tgt_player, paction);
3722 struct act_prob result = { .min = unconverted * ACTPROB_VAL_1_PCT,
3723 .max = unconverted * ACTPROB_VAL_1_PCT };
3724
3725 return result;
3726 } else {
3727 /* Could be improved to return a more exact probability in some cases.
3728 * Example: The player has enough information to know that the
3729 * probability always will be above 25% and always under 75% because
3730 * the only effect with unknown requirements that may apply adds (or
3731 * subtracts) 50% while all the requirements of the other effects that
3732 * may apply are known. */
3733 return ACTPROB_NOT_KNOWN;
3734 }
3735}
3736
3737/**********************************************************************/
3742static struct act_prob
3743action_prob_battle_then_dice_roll(const struct player *act_player,
3744 const struct unit *act_unit,
3745 const struct city *tgt_city,
3746 const struct unit *tgt_unit,
3747 const struct tile *tgt_tile,
3748 const struct player *tgt_player,
3749 const struct action *paction)
3750{
3751 struct act_prob battle;
3752 struct act_prob dice_roll;
3753
3754 battle = ACTPROB_CERTAIN;
3755 switch (actres_get_battle_kind(paction->result)) {
3756 case ABK_NONE:
3757 /* No pre action battle. */
3758 break;
3759 case ABK_DIPLOMATIC:
3760 battle = ap_diplomat_battle(act_unit, tgt_unit, tgt_tile,
3761 paction);
3762 break;
3763 case ABK_STANDARD:
3764 /* Not supported here yet. Implement when users appear. */
3765 fc_assert(actres_get_battle_kind(paction->result) != ABK_STANDARD);
3766 break;
3767 case ABK_COUNT:
3768 fc_assert(actres_get_battle_kind(paction->result) != ABK_COUNT);
3769 break;
3770 }
3771
3772 dice_roll = action_prob_pre_action_dice_roll(act_player, act_unit,
3773 tgt_city, tgt_player,
3774 paction);
3775
3776 return action_prob_and(&battle, &dice_roll);
3777}
3778
3779/**********************************************************************/
3790static struct act_prob
3791action_prob(const struct civ_map *nmap,
3792 const action_id wanted_action,
3793 const struct req_context *actor,
3794 const struct city *actor_home,
3795 const struct req_context *target,
3796 const struct extra_type *target_extra)
3797{
3798 int known;
3799 struct act_prob chance;
3800 const struct action *paction = action_by_number(wanted_action);
3801
3802 if (actor == NULL) {
3803 actor = req_context_empty();
3804 }
3805 if (target == NULL) {
3806 target = req_context_empty();
3807 }
3808
3809 known = is_action_possible(nmap, wanted_action, actor, target,
3810 target_extra,
3811 FALSE, actor_home);
3812
3813 if (known == TRI_NO) {
3814 /* The action enablers are irrelevant since the action it self is
3815 * impossible. */
3816 return ACTPROB_IMPOSSIBLE;
3817 }
3818
3819 chance = ACTPROB_NOT_IMPLEMENTED;
3820
3821 known = fc_tristate_and(known,
3822 action_enabled_local(wanted_action,
3823 actor, target));
3824
3825 switch (paction->result) {
3826 case ACTRES_SPY_POISON:
3827 /* All uncertainty comes from potential diplomatic battles and the
3828 * (diplchance server setting and the) Action_Odds_Pct effect controlled
3829 * dice roll before the action. */
3830 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
3831 target->city, target->unit,
3832 target->tile, target->player,
3833 paction);
3834 break;
3835 case ACTRES_SPY_STEAL_GOLD:
3836 /* TODO */
3837 break;
3838 case ACTRES_SPY_SPREAD_PLAGUE:
3839 /* TODO */
3840 break;
3841 case ACTRES_STEAL_MAPS:
3842 /* TODO */
3843 break;
3844 case ACTRES_SPY_SABOTAGE_UNIT:
3845 /* All uncertainty comes from potential diplomatic battles. */
3846 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile,
3847 paction);
3848 break;
3849 case ACTRES_SPY_BRIBE_UNIT:
3850 /* All uncertainty comes from potential diplomatic battles. */
3851 chance = ap_diplomat_battle(actor->unit, target->unit, target->tile,
3852 paction);
3853 break;
3854 case ACTRES_SPY_ATTACK:
3855 /* All uncertainty comes from potential diplomatic battles. */
3856 chance = ap_diplomat_battle(actor->unit, NULL, target->tile,
3857 paction);
3858 break;
3859 case ACTRES_SPY_SABOTAGE_CITY:
3860 /* TODO */
3861 break;
3862 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
3863 /* TODO */
3864 break;
3865 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
3866 /* TODO */
3867 break;
3868 case ACTRES_SPY_INCITE_CITY:
3869 /* TODO */
3870 break;
3871 case ACTRES_ESTABLISH_EMBASSY:
3872 chance = ACTPROB_CERTAIN;
3873 break;
3874 case ACTRES_SPY_STEAL_TECH:
3875 /* Do the victim have anything worth taking? */
3876 known = fc_tristate_and(known,
3877 tech_can_be_stolen(actor->player,
3878 target->player));
3879
3880 /* TODO: Calculate actual chance */
3881
3882 break;
3883 case ACTRES_SPY_TARGETED_STEAL_TECH:
3884 /* Do the victim have anything worth taking? */
3885 known = fc_tristate_and(known,
3886 tech_can_be_stolen(actor->player,
3887 target->player));
3888
3889 /* TODO: Calculate actual chance */
3890
3891 break;
3892 case ACTRES_SPY_INVESTIGATE_CITY:
3893 /* There is no risk that the city won't get investigated. */
3894 chance = ACTPROB_CERTAIN;
3895 break;
3896 case ACTRES_SPY_ESCAPE:
3897 /* TODO */
3898 break;
3899 case ACTRES_TRADE_ROUTE:
3900 /* TODO */
3901 break;
3902 case ACTRES_MARKETPLACE:
3903 /* Possible when not blocked by is_action_possible() */
3904 chance = ACTPROB_CERTAIN;
3905 break;
3906 case ACTRES_HELP_WONDER:
3907 /* Possible when not blocked by is_action_possible() */
3908 chance = ACTPROB_CERTAIN;
3909 break;
3910 case ACTRES_CAPTURE_UNITS:
3911 /* No battle is fought first. */
3912 chance = ACTPROB_CERTAIN;
3913 break;
3914 case ACTRES_EXPEL_UNIT:
3915 /* No battle is fought first. */
3916 chance = ACTPROB_CERTAIN;
3917 break;
3918 case ACTRES_BOMBARD:
3919 /* No battle is fought first. */
3920 chance = ACTPROB_CERTAIN;
3921 break;
3922 case ACTRES_FOUND_CITY:
3923 /* Possible when not blocked by is_action_possible() */
3924 chance = ACTPROB_CERTAIN;
3925 break;
3926 case ACTRES_JOIN_CITY:
3927 /* Possible when not blocked by is_action_possible() */
3928 chance = ACTPROB_CERTAIN;
3929 break;
3930 case ACTRES_SPY_NUKE:
3931 /* All uncertainty comes from potential diplomatic battles and the
3932 * (diplchance server setting and the) Action_Odds_Pct effect controlled
3933 * dice roll before the action. */
3934 chance = action_prob_battle_then_dice_roll(actor->player, actor->unit,
3935 target->city, target->unit,
3936 target->tile,
3937 target->player,
3938 paction);
3939 break;
3940 case ACTRES_NUKE:
3941 /* TODO */
3942 break;
3943 case ACTRES_NUKE_UNITS:
3944 /* TODO */
3945 break;
3946 case ACTRES_DESTROY_CITY:
3947 /* No battle is fought first. */
3948 chance = ACTPROB_CERTAIN;
3949 break;
3950 case ACTRES_DISBAND_UNIT_RECOVER:
3951 /* No battle is fought first. */
3952 chance = ACTPROB_CERTAIN;
3953 break;
3954 case ACTRES_DISBAND_UNIT:
3955 /* No battle is fought first. */
3956 chance = ACTPROB_CERTAIN;
3957 break;
3958 case ACTRES_HOME_CITY:
3959 /* No battle is fought first. */
3960 chance = ACTPROB_CERTAIN;
3961 break;
3962 case ACTRES_HOMELESS:
3963 /* No battle is fought first. */
3964 chance = ACTPROB_CERTAIN;
3965 break;
3966 case ACTRES_UPGRADE_UNIT:
3967 /* No battle is fought first. */
3968 chance = ACTPROB_CERTAIN;
3969 break;
3970 case ACTRES_PARADROP:
3971 case ACTRES_PARADROP_CONQUER:
3972 /* TODO */
3973 break;
3974 case ACTRES_AIRLIFT:
3975 /* Possible when not blocked by is_action_possible() */
3976 chance = ACTPROB_CERTAIN;
3977 break;
3978 case ACTRES_ATTACK:
3979 case ACTRES_COLLECT_RANSOM:
3980 {
3981 struct unit *defender_unit = get_defender(nmap, actor->unit,
3982 target->tile, paction);
3983
3984 if (can_player_see_unit(actor->player, defender_unit)) {
3985 double unconverted = unit_win_chance(nmap, actor->unit,
3986 defender_unit, paction);
3987
3988 chance.min = MAX(ACTPROB_VAL_MIN,
3989 floor((double)ACTPROB_VAL_MAX * unconverted));
3990 chance.max = MIN(ACTPROB_VAL_MAX,
3991 ceil((double)ACTPROB_VAL_MAX * unconverted));
3992 } else if (known == TRI_YES) {
3993 known = TRI_MAYBE;
3994 }
3995 }
3996 break;
3997 case ACTRES_WIPE_UNITS:
3998 chance = ACTPROB_CERTAIN;
3999 break;
4000 case ACTRES_STRIKE_BUILDING:
4001 /* TODO: not implemented yet because:
4002 * - dice roll 100% * Action_Odds_Pct could be handled with
4003 * action_prob_pre_action_dice_roll().
4004 * - sub target building may be missing. May be missing without player
4005 * knowledge if it isn't visible. See is_improvement_visible() and
4006 * can_player_see_city_internals(). */
4007 break;
4008 case ACTRES_STRIKE_PRODUCTION:
4009 /* All uncertainty comes from the (diplchance server setting and the)
4010 * Action_Odds_Pct effect controlled dice roll before the action. */
4011 chance = action_prob_pre_action_dice_roll(actor->player, actor->unit,
4012 target->city, target->player,
4013 paction);
4014 break;
4015 case ACTRES_CONQUER_CITY:
4016 /* No battle is fought first. */
4017 chance = ACTPROB_CERTAIN;
4018 break;
4019 case ACTRES_CONQUER_EXTRAS:
4020 /* No battle is fought first. */
4021 chance = ACTPROB_CERTAIN;
4022 break;
4023 case ACTRES_HEAL_UNIT:
4024 /* No battle is fought first. */
4025 chance = ACTPROB_CERTAIN;
4026 break;
4027 case ACTRES_TRANSFORM_TERRAIN:
4028 case ACTRES_CULTIVATE:
4029 case ACTRES_PLANT:
4030 case ACTRES_PILLAGE:
4031 case ACTRES_CLEAN:
4032 case ACTRES_FORTIFY:
4033 case ACTRES_ROAD:
4034 case ACTRES_CONVERT:
4035 case ACTRES_BASE:
4036 case ACTRES_MINE:
4037 case ACTRES_IRRIGATE:
4038 chance = ACTPROB_CERTAIN;
4039 break;
4040 case ACTRES_TRANSPORT_DEBOARD:
4041 chance = ACTPROB_CERTAIN;
4042 break;
4043 case ACTRES_TRANSPORT_BOARD:
4044 chance = ACTPROB_CERTAIN;
4045 break;
4046 case ACTRES_TRANSPORT_EMBARK:
4047 chance = ACTPROB_CERTAIN;
4048 break;
4049 case ACTRES_TRANSPORT_UNLOAD:
4050 chance = ACTPROB_CERTAIN;
4051 break;
4052 case ACTRES_TRANSPORT_LOAD:
4053 chance = ACTPROB_CERTAIN;
4054 break;
4055 case ACTRES_TRANSPORT_DISEMBARK:
4056 chance = ACTPROB_CERTAIN;
4057 break;
4058 case ACTRES_HUT_ENTER:
4059 case ACTRES_HUT_FRIGHTEN:
4060 /* Entering the hut happens with a probability of 100%. What happens
4061 * next is probably up to dice rolls in Lua. */
4062 chance = ACTPROB_NOT_IMPLEMENTED;
4063 break;
4064 case ACTRES_UNIT_MOVE:
4065 case ACTRES_TELEPORT:
4066 case ACTRES_TELEPORT_CONQUER:
4067 chance = ACTPROB_CERTAIN;
4068 break;
4069 /* Not UI action, so chance is meaningless */
4070 case ACTRES_ENABLER_CHECK:
4071 chance = ACTPROB_CERTAIN;
4072 break;
4073 case ACTRES_NONE:
4074 /* Accommodate ruleset authors that wishes to roll the dice in Lua.
4075 * Would be ACTPROB_CERTAIN if not for that. */
4076 /* TODO: maybe allow the ruleset author to give a probability from
4077 * Lua? */
4078 chance = ACTPROB_NOT_IMPLEMENTED;
4079 break;
4080
4081 case ACTRES_UNUSED_1:
4082 chance = ACTPROB_NOT_IMPLEMENTED;
4083 break;
4084 }
4085
4086 /* Non signal action probabilities should be in range. */
4087 fc_assert_action((action_prob_is_signal(chance)
4088 || chance.max <= ACTPROB_VAL_MAX),
4089 chance.max = ACTPROB_VAL_MAX);
4090 fc_assert_action((action_prob_is_signal(chance)
4091 || chance.min >= ACTPROB_VAL_MIN),
4092 chance.min = ACTPROB_VAL_MIN);
4093
4094 switch (known) {
4095 case TRI_NO:
4096 return ACTPROB_IMPOSSIBLE;
4097 break;
4098 case TRI_MAYBE:
4099 return ACTPROB_NOT_KNOWN;
4100 break;
4101 case TRI_YES:
4102 return chance;
4103 break;
4104 };
4105
4106 fc_assert_msg(FALSE, "Should be yes, maybe or no");
4107
4108 return ACTPROB_NOT_IMPLEMENTED;
4109}
4110
4111/**********************************************************************/
4115static struct act_prob
4116action_prob_vs_city_full(const struct civ_map *nmap,
4117 const struct unit *actor_unit,
4118 const struct city *actor_home,
4119 const struct tile *actor_tile,
4120 const action_id act_id,
4121 const struct city *target_city)
4122{
4123 const struct impr_type *target_building;
4124 const struct unit_type *target_utype;
4125 const struct action *act = action_by_number(act_id);
4126
4127 if (actor_unit == NULL || target_city == NULL) {
4128 /* Can't do an action when actor or target are missing. */
4129 return ACTPROB_IMPOSSIBLE;
4130 }
4131
4132 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4133 ACTPROB_IMPOSSIBLE,
4134 "Action %s is performed by %s not %s",
4135 action_id_rule_name(act_id),
4136 action_actor_kind_name(
4137 action_id_get_actor_kind(act_id)),
4138 action_actor_kind_name(AAK_UNIT));
4139
4140 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
4141 ACTPROB_IMPOSSIBLE,
4142 "Action %s is against %s not %s",
4143 action_id_rule_name(act_id),
4144 action_target_kind_name(
4145 action_id_get_target_kind(act_id)),
4146 action_target_kind_name(ATK_CITY));
4147
4148 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4149
4150 if (!unit_can_do_action(actor_unit, act_id)) {
4151 /* No point in continuing. */
4152 return ACTPROB_IMPOSSIBLE;
4153 }
4154
4155 /* Doesn't leak information about city position since an unknown city
4156 * can't be targeted and a city can't move. */
4157 if (!action_id_distance_accepted(act_id,
4158 real_map_distance(actor_tile,
4159 city_tile(target_city)))) {
4160 /* No point in continuing. */
4161 return ACTPROB_IMPOSSIBLE;
4162 }
4163
4164 /* Doesn't leak information since it must be 100% certain from the
4165 * player's perspective that the blocking action is legal. */
4166 if (action_is_blocked_by(act, actor_unit,
4167 city_tile(target_city), target_city, NULL)) {
4168 /* Don't offer to perform an action known to be blocked. */
4169 return ACTPROB_IMPOSSIBLE;
4170 }
4171
4172 if (!player_can_see_city_externals(unit_owner(actor_unit), target_city)) {
4173 /* The invisible city at this tile may, as far as the player knows, not
4174 * exist anymore. */
4175 return act_prob_unseen_target(nmap, act_id, actor_unit);
4176 }
4177
4178 target_building = tgt_city_local_building(target_city);
4179 target_utype = tgt_city_local_utype(target_city);
4180
4181 return action_prob(nmap, act_id,
4182 &(const struct req_context) {
4183 .player = unit_owner(actor_unit),
4184 .city = tile_city(actor_tile),
4185 .tile = actor_tile,
4186 .unit = actor_unit,
4187 .unittype = unit_type_get(actor_unit),
4188 },
4189 actor_home,
4190 &(const struct req_context) {
4191 .player = city_owner(target_city),
4192 .city = target_city,
4193 .building = target_building,
4194 .tile = city_tile(target_city),
4195 .unittype = target_utype,
4196 }, NULL);
4197}
4198
4199/**********************************************************************/
4203 struct act_prob action_prob_vs_city(const struct civ_map *nmap,
4204 const struct unit *actor_unit,
4205 const action_id act_id,
4206 const struct city *target_city)
4207{
4208 return action_prob_vs_city_full(nmap, actor_unit,
4209 unit_home(actor_unit),
4210 unit_tile(actor_unit),
4211 act_id, target_city);
4212}
4213
4214/**********************************************************************/
4218static struct act_prob
4219action_prob_vs_unit_full(const struct civ_map *nmap,
4220 const struct unit *actor_unit,
4221 const struct city *actor_home,
4222 const struct tile *actor_tile,
4223 const action_id act_id,
4224 const struct unit *target_unit)
4225{
4226 if (actor_unit == NULL || target_unit == NULL) {
4227 /* Can't do an action when actor or target are missing. */
4228 return ACTPROB_IMPOSSIBLE;
4229 }
4230
4231 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4232 ACTPROB_IMPOSSIBLE,
4233 "Action %s is performed by %s not %s",
4234 action_id_rule_name(act_id),
4235 action_actor_kind_name(
4236 action_id_get_actor_kind(act_id)),
4237 action_actor_kind_name(AAK_UNIT));
4238
4239 fc_assert_ret_val_msg(ATK_UNIT == action_id_get_target_kind(act_id),
4240 ACTPROB_IMPOSSIBLE,
4241 "Action %s is against %s not %s",
4242 action_id_rule_name(act_id),
4243 action_target_kind_name(
4244 action_id_get_target_kind(act_id)),
4245 action_target_kind_name(ATK_UNIT));
4246
4247 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4248
4249 if (!unit_can_do_action(actor_unit, act_id)) {
4250 /* No point in continuing. */
4251 return ACTPROB_IMPOSSIBLE;
4252 }
4253
4254 /* Doesn't leak information about unit position since an unseen unit can't
4255 * be targeted. */
4256 if (!action_id_distance_accepted(act_id,
4257 real_map_distance(actor_tile,
4258 unit_tile(target_unit)))) {
4259 /* No point in continuing. */
4260 return ACTPROB_IMPOSSIBLE;
4261 }
4262
4263 return action_prob(nmap, act_id,
4264 &(const struct req_context) {
4265 .player = unit_owner(actor_unit),
4266 .city = tile_city(actor_tile),
4267 .tile = actor_tile,
4268 .unit = actor_unit,
4269 .unittype = unit_type_get(actor_unit),
4270 },
4271 actor_home,
4272 &(const struct req_context) {
4273 .player = unit_owner(target_unit),
4274 .city = tile_city(unit_tile(target_unit)),
4275 .tile = unit_tile(target_unit),
4276 .unit = target_unit,
4277 .unittype = unit_type_get(target_unit),
4278 },
4279 NULL);
4280}
4281
4282/**********************************************************************/
4286 struct act_prob action_prob_vs_unit(const struct civ_map *nmap,
4287 const struct unit *actor_unit,
4288 const action_id act_id,
4289 const struct unit *target_unit)
4290{
4291 return action_prob_vs_unit_full(nmap, actor_unit,
4292 unit_home(actor_unit),
4293 unit_tile(actor_unit),
4294 act_id,
4295 target_unit);
4296}
4297
4298/**********************************************************************/
4302static struct act_prob
4303action_prob_vs_stack_full(const struct civ_map *nmap,
4304 const struct unit *actor_unit,
4305 const struct city *actor_home,
4306 const struct tile *actor_tile,
4307 const action_id act_id,
4308 const struct tile *target_tile)
4309{
4310 struct act_prob prob_all;
4311 const struct req_context *actor_ctxt;
4312 const struct action *act = action_by_number(act_id);
4313
4314 if (actor_unit == NULL || target_tile == NULL) {
4315 /* Can't do an action when actor or target are missing. */
4316 return ACTPROB_IMPOSSIBLE;
4317 }
4318
4319 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4320 ACTPROB_IMPOSSIBLE,
4321 "Action %s is performed by %s not %s",
4322 action_id_rule_name(act_id),
4323 action_actor_kind_name(
4324 action_id_get_actor_kind(act_id)),
4325 action_actor_kind_name(AAK_UNIT));
4326
4327 fc_assert_ret_val_msg(ATK_UNITS == action_id_get_target_kind(act_id),
4328 ACTPROB_IMPOSSIBLE,
4329 "Action %s is against %s not %s",
4330 action_id_rule_name(act_id),
4331 action_target_kind_name(
4332 action_id_get_target_kind(act_id)),
4333 action_target_kind_name(ATK_UNITS));
4334
4335 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4336
4337 if (!unit_can_do_action(actor_unit, act_id)) {
4338 /* No point in continuing. */
4339 return ACTPROB_IMPOSSIBLE;
4340 }
4341
4342 /* Doesn't leak information about unit stack position since it is
4343 * specified as a tile and an unknown tile's position is known. */
4344 if (!action_id_distance_accepted(act_id,
4345 real_map_distance(actor_tile,
4346 target_tile))) {
4347 /* No point in continuing. */
4348 return ACTPROB_IMPOSSIBLE;
4349 }
4350
4351 /* Doesn't leak information since the actor player can see the target
4352 * tile. */
4353 if (tile_is_seen(target_tile, unit_owner(actor_unit))
4354 && tile_city(target_tile) != NULL
4355 && !utype_can_do_act_if_tgt_citytile(unit_type_get(actor_unit),
4356 act_id,
4357 CITYT_CENTER, TRUE)) {
4358 /* Don't offer to perform actions that never can target a unit stack in
4359 * a city. */
4360 return ACTPROB_IMPOSSIBLE;
4361 }
4362
4363 /* Doesn't leak information since it must be 100% certain from the
4364 * player's perspective that the blocking action is legal. */
4365 unit_list_iterate(target_tile->units, target_unit) {
4366 if (action_is_blocked_by(act, actor_unit,
4367 target_tile, tile_city(target_tile),
4368 target_unit)) {
4369 /* Don't offer to perform an action known to be blocked. */
4370 return ACTPROB_IMPOSSIBLE;
4371 }
4372 } unit_list_iterate_end;
4373
4374 /* Must be done here since an empty unseen tile will result in
4375 * ACTPROB_IMPOSSIBLE. */
4376 if (unit_list_size(target_tile->units) == 0) {
4377 /* Can't act against an empty tile. */
4378
4379 if (player_can_trust_tile_has_no_units(unit_owner(actor_unit),
4380 target_tile)) {
4381 /* Known empty tile. */
4382 return ACTPROB_IMPOSSIBLE;
4383 } else {
4384 /* The player doesn't know that the tile is empty. */
4385 return act_prob_unseen_target(nmap, act_id, actor_unit);
4386 }
4387 }
4388
4389 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK)
4390 || action_id_has_result_safe(act_id, ACTRES_WIPE_UNITS)
4391 || action_id_has_result_safe(act_id, ACTRES_COLLECT_RANSOM))
4392 && tile_city(target_tile) != NULL
4393 && !pplayers_at_war(city_owner(tile_city(target_tile)),
4394 unit_owner(actor_unit))) {
4395 /* Hard coded rule: can't "Bombard", "Suicide Attack", or "Attack"
4396 * units in non enemy cities. */
4397 return ACTPROB_IMPOSSIBLE;
4398 }
4399
4400 if ((action_id_has_result_safe(act_id, ACTRES_ATTACK)
4401 || action_id_has_result_safe(act_id, ACTRES_WIPE_UNITS)
4402 || action_id_has_result_safe(act_id, ACTRES_NUKE_UNITS)
4403 || action_id_has_result_safe(act_id, ACTRES_COLLECT_RANSOM))
4404 && !is_native_tile(unit_type_get(actor_unit), target_tile)
4405 && !can_attack_non_native(unit_type_get(actor_unit))) {
4406 /* Hard coded rule: can't "Nuke Units", "Wipe Units", "Suicide Attack",
4407 * or "Attack" units on non native tile without "AttackNonNative" and
4408 * not "Only_Native_Attack". */
4409 return ACTPROB_IMPOSSIBLE;
4410 }
4411
4412 /* Invisible units at this tile can make the action legal or illegal.
4413 * Invisible units can be stacked with visible units. The possible
4414 * existence of invisible units therefore makes the result uncertain. */
4415 prob_all = (can_player_see_hypotetic_units_at(unit_owner(actor_unit),
4416 target_tile)
4417 ? ACTPROB_CERTAIN : ACTPROB_NOT_KNOWN);
4418
4419 actor_ctxt = &(const struct req_context) {
4420 .player = unit_owner(actor_unit),
4421 .city = tile_city(actor_tile),
4422 .tile = actor_tile,
4423 .unit = actor_unit,
4424 .unittype = unit_type_get(actor_unit),
4425 };
4426
4427 unit_list_iterate(target_tile->units, target_unit) {
4428 struct act_prob prob_unit;
4429
4430 if (!can_player_see_unit(unit_owner(actor_unit), target_unit)) {
4431 /* Only visible units are considered. The invisible units contributed
4432 * their uncertainty to prob_all above. */
4433 continue;
4434 }
4435
4436 prob_unit = action_prob(nmap, act_id, actor_ctxt, actor_home,
4437 &(const struct req_context) {
4438 .player = unit_owner(target_unit),
4439 .city = tile_city(unit_tile(target_unit)),
4440 .tile = unit_tile(target_unit),
4441 .unit = target_unit,
4442 .unittype = unit_type_get(target_unit),
4443 },
4444 NULL);
4445
4446 if (!action_prob_possible(prob_unit)) {
4447 /* One unit makes it impossible for all units. */
4448 return ACTPROB_IMPOSSIBLE;
4449 } else if (action_prob_not_impl(prob_unit)) {
4450 /* Not implemented dominates all except impossible. */
4451 prob_all = ACTPROB_NOT_IMPLEMENTED;
4452 } else {
4453 fc_assert_msg(!action_prob_is_signal(prob_unit),
4454 "Invalid probability [%d, %d]",
4455 prob_unit.min, prob_unit.max);
4456
4457 if (action_prob_is_signal(prob_all)) {
4458 /* Special values dominate regular values. */
4459 continue;
4460 }
4461
4462 /* Probability against all target units considered until this moment
4463 * and the probability against this target unit. */
4464 prob_all.min = (prob_all.min * prob_unit.min) / ACTPROB_VAL_MAX;
4465 prob_all.max = (prob_all.max * prob_unit.max) / ACTPROB_VAL_MAX;
4466 break;
4467 }
4468 } unit_list_iterate_end;
4469
4470 /* Not impossible for any of the units at the tile. */
4471 return prob_all;
4472}
4473
4474/**********************************************************************/
4478 struct act_prob action_prob_vs_stack(const struct unit *actor_unit,
4479 const action_id act_id,
4480 const struct tile *target_tile)
4481{
4482 const struct civ_map *nmap = &(wld.map);
4483
4484 return action_prob_vs_stack_full(nmap, actor_unit,
4485 unit_home(actor_unit),
4486 unit_tile(actor_unit),
4487 act_id,
4488 target_tile);
4489}
4490
4491/**********************************************************************/
4495static struct act_prob
4496action_prob_vs_tile_full(const struct civ_map *nmap,
4497 const struct unit *actor_unit,
4498 const struct city *actor_home,
4499 const struct tile *actor_tile,
4500 const action_id act_id,
4501 const struct tile *target_tile,
4502 const struct extra_type *target_extra)
4503{
4504 if (actor_unit == NULL || target_tile == NULL) {
4505 /* Can't do an action when actor or target are missing. */
4506 return ACTPROB_IMPOSSIBLE;
4507 }
4508
4509 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4510 ACTPROB_IMPOSSIBLE,
4511 "Action %s is performed by %s not %s",
4512 action_id_rule_name(act_id),
4513 action_actor_kind_name(
4514 action_id_get_actor_kind(act_id)),
4515 action_actor_kind_name(AAK_UNIT));
4516
4517 fc_assert_ret_val_msg(ATK_TILE == action_id_get_target_kind(act_id),
4518 ACTPROB_IMPOSSIBLE,
4519 "Action %s is against %s not %s",
4520 action_id_rule_name(act_id),
4521 action_target_kind_name(
4522 action_id_get_target_kind(act_id)),
4523 action_target_kind_name(ATK_TILE));
4524
4525 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4526
4527 if (!unit_can_do_action(actor_unit, act_id)) {
4528 /* No point in continuing. */
4529 return ACTPROB_IMPOSSIBLE;
4530 }
4531
4532 /* Doesn't leak information about tile position since an unknown tile's
4533 * position is known. */
4534 if (!action_id_distance_accepted(act_id,
4535 real_map_distance(actor_tile,
4536 target_tile))) {
4537 /* No point in continuing. */
4538 return ACTPROB_IMPOSSIBLE;
4539 }
4540
4541 return action_prob(nmap, act_id,
4542 &(const struct req_context) {
4543 .player = unit_owner(actor_unit),
4544 .city = tile_city(actor_tile),
4545 .tile = actor_tile,
4546 .unit = actor_unit,
4547 .unittype = unit_type_get(actor_unit),
4548 },
4549 actor_home,
4550 &(const struct req_context) {
4551 .player = tile_owner(target_tile),
4552 .city = tile_city(target_tile),
4553 .tile = target_tile,
4554 },
4555 target_extra);
4556}
4557
4558/**********************************************************************/
4562 struct act_prob action_prob_vs_tile(const struct unit *actor_unit,
4563 const action_id act_id,
4564 const struct tile *target_tile,
4565 const struct extra_type *target_extra)
4566{
4567 const struct civ_map *nmap = &(wld.map);
4568
4569 return action_prob_vs_tile_full(nmap, actor_unit,
4570 unit_home(actor_unit),
4571 unit_tile(actor_unit),
4572 act_id, target_tile, target_extra);
4573}
4574
4575/**********************************************************************/
4579static struct act_prob
4580action_prob_vs_extras_full(const struct civ_map *nmap,
4581 const struct unit *actor_unit,
4582 const struct city *actor_home,
4583 const struct tile *actor_tile,
4584 const action_id act_id,
4585 const struct tile *target_tile,
4586 const struct extra_type *target_extra)
4587{
4588 if (actor_unit == NULL || target_tile == NULL) {
4589 /* Can't do an action when actor or target are missing. */
4590 return ACTPROB_IMPOSSIBLE;
4591 }
4592
4593 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4594 ACTPROB_IMPOSSIBLE,
4595 "Action %s is performed by %s not %s",
4596 action_id_rule_name(act_id),
4597 action_actor_kind_name(
4598 action_id_get_actor_kind(act_id)),
4599 action_actor_kind_name(AAK_UNIT));
4600
4601 fc_assert_ret_val_msg(ATK_EXTRAS == action_id_get_target_kind(act_id),
4602 ACTPROB_IMPOSSIBLE,
4603 "Action %s is against %s not %s",
4604 action_id_rule_name(act_id),
4605 action_target_kind_name(
4606 action_id_get_target_kind(act_id)),
4607 action_target_kind_name(ATK_EXTRAS));
4608
4609 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4610
4611 if (!unit_can_do_action(actor_unit, act_id)) {
4612 /* No point in continuing. */
4613 return ACTPROB_IMPOSSIBLE;
4614 }
4615
4616 /* Doesn't leak information about tile position since an unknown tile's
4617 * position is known. */
4618 if (!action_id_distance_accepted(act_id,
4619 real_map_distance(actor_tile,
4620 target_tile))) {
4621 /* No point in continuing. */
4622 return ACTPROB_IMPOSSIBLE;
4623 }
4624
4625 return action_prob(nmap, act_id,
4626 &(const struct req_context) {
4627 .player = unit_owner(actor_unit),
4628 .city = tile_city(actor_tile),
4629 .tile = actor_tile,
4630 .unit = actor_unit,
4631 .unittype = unit_type_get(actor_unit),
4632 },
4633 actor_home,
4634 &(const struct req_context) {
4635 .player = target_tile->extras_owner,
4636 .city = tile_city(target_tile),
4637 .tile = target_tile,
4638 },
4639 target_extra);
4640}
4641
4642/**********************************************************************/
4646 struct act_prob action_prob_vs_extras(const struct unit *actor_unit,
4647 const action_id act_id,
4648 const struct tile *target_tile,
4649 const struct extra_type *target_extra)
4650{
4651 const struct civ_map *nmap = &(wld.map);
4652
4653 return action_prob_vs_extras_full(nmap, actor_unit,
4654 unit_home(actor_unit),
4655 unit_tile(actor_unit),
4656 act_id, target_tile, target_extra);
4657}
4658
4659/**********************************************************************/
4663static struct act_prob
4664action_prob_self_full(const struct civ_map *nmap,
4665 const struct unit *actor_unit,
4666 const struct city *actor_home,
4667 const struct tile *actor_tile,
4668 const action_id act_id)
4669{
4670 if (actor_unit == NULL) {
4671 /* Can't do the action when the actor is missing. */
4672 return ACTPROB_IMPOSSIBLE;
4673 }
4674
4675 /* No point in checking distance to target. It is always 0. */
4676
4677 fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
4678 ACTPROB_IMPOSSIBLE,
4679 "Action %s is performed by %s not %s",
4680 action_id_rule_name(act_id),
4681 action_actor_kind_name(
4682 action_id_get_actor_kind(act_id)),
4683 action_actor_kind_name(AAK_UNIT));
4684
4685 fc_assert_ret_val_msg(ATK_SELF == action_id_get_target_kind(act_id),
4686 ACTPROB_IMPOSSIBLE,
4687 "Action %s is against %s not %s",
4688 action_id_rule_name(act_id),
4689 action_target_kind_name(
4690 action_id_get_target_kind(act_id)),
4691 action_target_kind_name(ATK_SELF));
4692
4693 fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
4694
4695 if (!unit_can_do_action(actor_unit, act_id)) {
4696 /* No point in continuing. */
4697 return ACTPROB_IMPOSSIBLE;
4698 }
4699
4700 return action_prob(nmap, act_id,
4701 &(const struct req_context) {
4702 .player = unit_owner(actor_unit),
4703 .city = tile_city(actor_tile),
4704 .tile = actor_tile,
4705 .unit = actor_unit,
4706 .unittype = unit_type_get(actor_unit),
4707 },
4708 actor_home,
4709 NULL,
4710 NULL);
4711}
4712
4713/**********************************************************************/
4717 struct act_prob action_prob_self(const struct unit *actor_unit,
4718 const action_id act_id)
4719{
4720 const struct civ_map *nmap = &(wld.map);
4721
4722 return action_prob_self_full(nmap, actor_unit,
4723 unit_home(actor_unit),
4724 unit_tile(actor_unit),
4725 act_id);
4726}
4727
4728/**********************************************************************/
4739 struct act_prob action_prob_unit_vs_tgt(const struct action *paction,
4740 const struct unit *act_unit,
4741 const struct city *tgt_city,
4742 const struct unit *tgt_unit,
4743 const struct tile *tgt_tile,
4744 const struct extra_type *extra_tgt)
4745{
4746 /* Assume impossible until told otherwise. */
4747 struct act_prob prob = ACTPROB_IMPOSSIBLE;
4748 const struct civ_map *nmap = &(wld.map);
4749
4750 fc_assert_ret_val(paction, ACTPROB_IMPOSSIBLE);
4751 fc_assert_ret_val(act_unit, ACTPROB_IMPOSSIBLE);
4752
4753 switch (action_get_target_kind(paction)) {
4754 case ATK_UNITS:
4755 if (tgt_tile) {
4756 prob = action_prob_vs_stack(act_unit, paction->id, tgt_tile);
4757 }
4758 break;
4759 case ATK_TILE:
4760 if (tgt_tile) {
4761 prob = action_prob_vs_tile(act_unit, paction->id, tgt_tile, extra_tgt);
4762 }
4763 break;
4764 case ATK_EXTRAS:
4765 if (tgt_tile) {
4766 prob = action_prob_vs_extras(act_unit, paction->id,
4767 tgt_tile, extra_tgt);
4768 }
4769 break;
4770 case ATK_CITY:
4771 if (tgt_city) {
4772 prob = action_prob_vs_city(nmap, act_unit, paction->id, tgt_city);
4773 }
4774 break;
4775 case ATK_UNIT:
4776 if (tgt_unit) {
4777 prob = action_prob_vs_unit(nmap, act_unit, paction->id, tgt_unit);
4778 }
4779 break;
4780 case ATK_SELF:
4781 prob = action_prob_self(act_unit, paction->id);
4782 break;
4783 case ATK_COUNT:
4784 log_error("Invalid action target kind");
4785 break;
4786 }
4787
4788 return prob;
4789}
4790
4791/**********************************************************************/
4796 struct act_prob action_speculate_unit_on_city(const action_id act_id,
4797 const struct unit *actor,
4798 const struct city *actor_home,
4799 const struct tile *actor_tile,
4800 const bool omniscient_cheat,
4801 const struct city* target)
4802{
4803 /* FIXME: some unit state requirements still depend on the actor unit's
4804 * current position rather than on actor_tile. Maybe this function should
4805 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4806 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4807 const struct civ_map *nmap = &(wld.map);
4808
4809 if (omniscient_cheat) {
4810 if (is_action_enabled_unit_on_city_full(nmap, act_id,
4811 actor, actor_home, actor_tile,
4812 target)) {
4813 return ACTPROB_CERTAIN;
4814 } else {
4815 return ACTPROB_IMPOSSIBLE;
4816 }
4817 } else {
4818 /* FIXME: this branch result depends _directly_ on actor's position.
4819 * I.e., like, not adjacent, no action. Other branch ignores radius. */
4820 return action_prob_vs_city_full(nmap, actor, actor_home, actor_tile,
4821 act_id, target);
4822 }
4823}
4824
4825/**********************************************************************/
4830struct act_prob
4831action_speculate_unit_on_unit(action_id act_id,
4832 const struct unit *actor,
4833 const struct city *actor_home,
4834 const struct tile *actor_tile,
4835 bool omniscient_cheat,
4836 const struct unit *target)
4837{
4838 /* FIXME: some unit state requirements still depend on the actor unit's
4839 * current position rather than on actor_tile. Maybe this function should
4840 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4841 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4842 const struct civ_map *nmap = &(wld.map);
4843
4844 if (omniscient_cheat) {
4845 if (is_action_enabled_unit_on_unit_full(nmap, act_id,
4846 actor, actor_home, actor_tile,
4847 target)) {
4848 return ACTPROB_CERTAIN;
4849 } else {
4850 return ACTPROB_IMPOSSIBLE;
4851 }
4852 } else {
4853 return action_prob_vs_unit_full(nmap, actor, actor_home, actor_tile,
4854 act_id, target);
4855 }
4856}
4857
4858/**********************************************************************/
4863struct act_prob
4864action_speculate_unit_on_stack(action_id act_id,
4865 const struct unit *actor,
4866 const struct city *actor_home,
4867 const struct tile *actor_tile,
4868 bool omniscient_cheat,
4869 const struct tile *target)
4870{
4871 /* FIXME: some unit state requirements still depend on the actor unit's
4872 * current position rather than on actor_tile. Maybe this function should
4873 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4874 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4875 const struct civ_map *nmap = &(wld.map);
4876
4877 if (omniscient_cheat) {
4878 if (is_action_enabled_unit_on_stack_full(nmap, act_id,
4879 actor, actor_home, actor_tile,
4880 target)) {
4881 return ACTPROB_CERTAIN;
4882 } else {
4883 return ACTPROB_IMPOSSIBLE;
4884 }
4885 } else {
4886 return action_prob_vs_stack_full(nmap, actor, actor_home, actor_tile,
4887 act_id, target);
4888 }
4889}
4890
4891/**********************************************************************/
4896struct act_prob
4897action_speculate_unit_on_tile(action_id act_id,
4898 const struct unit *actor,
4899 const struct city *actor_home,
4900 const struct tile *actor_tile,
4901 bool omniscient_cheat,
4902 const struct tile *target_tile,
4903 const struct extra_type *target_extra)
4904{
4905 /* FIXME: some unit state requirements still depend on the actor unit's
4906 * current position rather than on actor_tile. Maybe this function should
4907 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4908 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4909 const struct civ_map *nmap = &(wld.map);
4910
4911 if (omniscient_cheat) {
4912 if (is_action_enabled_unit_on_tile_full(nmap, act_id,
4913 actor, actor_home, actor_tile,
4914 target_tile, target_extra)) {
4915 return ACTPROB_CERTAIN;
4916 } else {
4917 return ACTPROB_IMPOSSIBLE;
4918 }
4919 } else {
4920 return action_prob_vs_tile_full(nmap, actor, actor_home, actor_tile,
4921 act_id, target_tile, target_extra);
4922 }
4923}
4924
4925/**********************************************************************/
4930struct act_prob
4931action_speculate_unit_on_extras(action_id act_id,
4932 const struct unit *actor,
4933 const struct city *actor_home,
4934 const struct tile *actor_tile,
4935 bool omniscient_cheat,
4936 const struct tile *target_tile,
4937 const struct extra_type *target_extra)
4938{
4939 /* FIXME: some unit state requirements still depend on the actor unit's
4940 * current position rather than on actor_tile. Maybe this function should
4941 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4942 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4943 const struct civ_map *nmap = &(wld.map);
4944
4945 if (omniscient_cheat) {
4946 if (is_action_enabled_unit_on_extras_full(nmap, act_id,
4947 actor, actor_home, actor_tile,
4948 target_tile, target_extra)) {
4949 return ACTPROB_CERTAIN;
4950 } else {
4951 return ACTPROB_IMPOSSIBLE;
4952 }
4953 } else {
4954 return action_prob_vs_extras_full(nmap, actor, actor_home, actor_tile,
4955 act_id, target_tile, target_extra);
4956 }
4957}
4958
4959/**********************************************************************/
4964struct act_prob
4965action_speculate_unit_on_self(action_id act_id,
4966 const struct unit *actor,
4967 const struct city *actor_home,
4968 const struct tile *actor_tile,
4969 bool omniscient_cheat)
4970{
4971 /* FIXME: some unit state requirements still depend on the actor unit's
4972 * current position rather than on actor_tile. Maybe this function should
4973 * return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
4974 * other requirement makes the action ACTPROB_IMPOSSIBLE? */
4975 const struct civ_map *nmap = &(wld.map);
4976
4977 if (omniscient_cheat) {
4978 if (is_action_enabled_unit_on_self_full(nmap, act_id,
4979 actor, actor_home, actor_tile)) {
4980 return ACTPROB_CERTAIN;
4981 } else {
4982 return ACTPROB_IMPOSSIBLE;
4983 }
4984 } else {
4985 return action_prob_self_full(nmap, actor, actor_home, actor_tile,
4986 act_id);
4987 }
4988}
4989
4990/**********************************************************************/
4993 struct act_prob action_prob_new_impossible(void)
4994{
4995 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MIN };
4996
4997 return out;
4998}
4999
5000/**********************************************************************/
5003 struct act_prob action_prob_new_certain(void)
5004{
5005 struct act_prob out = { ACTPROB_VAL_MAX, ACTPROB_VAL_MAX };
5006
5007 return out;
5008}
5009
5010/**********************************************************************/
5013 struct act_prob action_prob_new_not_relevant(void)
5014{
5015 struct act_prob out = { ACTPROB_VAL_NA, ACTPROB_VAL_MIN};
5016
5017 return out;
5018}
5019
5020/**********************************************************************/
5023 struct act_prob action_prob_new_not_impl(void)
5024{
5025 struct act_prob out = { ACTPROB_VAL_NOT_IMPL, ACTPROB_VAL_MIN };
5026
5027 return out;
5028}
5029
5030/**********************************************************************/
5033 struct act_prob action_prob_new_unknown(void)
5034{
5035 struct act_prob out = { ACTPROB_VAL_MIN, ACTPROB_VAL_MAX };
5036
5037 return out;
5038}
5039
5040/**********************************************************************/
5044 bool action_prob_possible(const struct act_prob probability)
5045{
5046 return (ACTPROB_VAL_MIN < probability.max
5047 || action_prob_not_impl(probability));
5048}
5049
5050/**********************************************************************/
5054 bool action_prob_certain(const struct act_prob probability)
5055{
5056 return (ACTPROB_VAL_MAX == probability.min
5057 && ACTPROB_VAL_MAX == probability.max);
5058}
5059
5060/**********************************************************************/
5064static inline bool
5065action_prob_not_relevant(const struct act_prob probability)
5066{
5067 return probability.min == ACTPROB_VAL_NA
5068 && probability.max == ACTPROB_VAL_MIN;
5069}
5070
5071/**********************************************************************/
5075static inline bool
5076action_prob_not_impl(const struct act_prob probability)
5077{
5078 return probability.min == ACTPROB_VAL_NOT_IMPL
5079 && probability.max == ACTPROB_VAL_MIN;
5080}
5081
5082/**********************************************************************/
5086static inline bool
5087action_prob_is_signal(const struct act_prob probability)
5088{
5089 return probability.max < probability.min;
5090}
5091
5092/**********************************************************************/
5095 bool are_action_probabilitys_equal(const struct act_prob *ap1,
5096 const struct act_prob *ap2)
5097{
5098 return ap1->min == ap2->min && ap1->max == ap2->max;
5099}
5100
5101/**********************************************************************/
5104 int action_prob_cmp_pessimist(const struct act_prob ap1,
5105 const struct act_prob ap2)
5106{
5107 struct act_prob my_ap1;
5108 struct act_prob my_ap2;
5109
5110 /* The action probabilities are real. */
5111 fc_assert(!action_prob_not_relevant(ap1));
5112 fc_assert(!action_prob_not_relevant(ap2));
5113
5114 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5115 if (action_prob_is_signal(ap1)) {
5116 /* Assert that it is OK to convert the signal. */
5117 fc_assert(action_prob_not_impl(ap1));
5118
5119 my_ap1 = ACTPROB_NOT_KNOWN;
5120 } else {
5121 my_ap1 = ap1;
5122 }
5123
5124 if (action_prob_is_signal(ap2)) {
5125 /* Assert that it is OK to convert the signal. */
5126 fc_assert(action_prob_not_impl(ap2));
5127
5128 my_ap2 = ACTPROB_NOT_KNOWN;
5129 } else {
5130 my_ap2 = ap2;
5131 }
5132
5133 /* The action probabilities now have a comparison friendly form. */
5134 fc_assert(!action_prob_is_signal(my_ap1));
5135 fc_assert(!action_prob_is_signal(my_ap2));
5136
5137 /* Do the comparison. Start with min. Continue with max. */
5138 if (my_ap1.min < my_ap2.min) {
5139 return -1;
5140 } else if (my_ap1.min > my_ap2.min) {
5141 return 1;
5142 } else if (my_ap1.max < my_ap2.max) {
5143 return -1;
5144 } else if (my_ap1.max > my_ap2.max) {
5145 return 1;
5146 } else {
5147 return 0;
5148 }
5149}
5150
5151/**********************************************************************/
5155 double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
5156{
5157 struct act_prob my_ap;
5158
5159 /* The action probability is real. */
5160 fc_assert(!action_prob_not_relevant(ap));
5161
5162 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5163 if (action_prob_is_signal(ap)) {
5164 /* Assert that it is OK to convert the signal. */
5165 fc_assert(action_prob_not_impl(ap));
5166
5167 my_ap = ACTPROB_NOT_KNOWN;
5168 } else {
5169 my_ap = ap;
5170 }
5171
5172 /* The action probability now has a math friendly form. */
5173 fc_assert(!action_prob_is_signal(my_ap));
5174
5175 return (double)my_ap.min / (double) ACTPROB_VAL_MAX;
5176}
5177
5178/**********************************************************************/
5182 struct act_prob action_prob_and(const struct act_prob *ap1,
5183 const struct act_prob *ap2)
5184{
5185 struct act_prob my_ap1;
5186 struct act_prob my_ap2;
5187 struct act_prob out;
5188
5189 /* The action probabilities are real. */
5190 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
5191 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
5192
5193 if (action_prob_is_signal(*ap1)
5194 && are_action_probabilitys_equal(ap1, ap2)) {
5195 /* Keep the information rather than converting the signal to
5196 * ACTPROB_NOT_KNOWN. */
5197
5198 /* Assert that it is OK to convert the signal. */
5199 fc_assert(action_prob_not_impl(*ap1));
5200
5201 out.min = ap1->min;
5202 out.max = ap2->max;
5203
5204 return out;
5205 }
5206
5207 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5208 if (action_prob_is_signal(*ap1)) {
5209 /* Assert that it is OK to convert the signal. */
5210 fc_assert(action_prob_not_impl(*ap1));
5211
5212 my_ap1.min = ACTPROB_VAL_MIN;
5213 my_ap1.max = ACTPROB_VAL_MAX;
5214 } else {
5215 my_ap1.min = ap1->min;
5216 my_ap1.max = ap1->max;
5217 }
5218
5219 if (action_prob_is_signal(*ap2)) {
5220 /* Assert that it is OK to convert the signal. */
5221 fc_assert(action_prob_not_impl(*ap2));
5222
5223 my_ap2.min = ACTPROB_VAL_MIN;
5224 my_ap2.max = ACTPROB_VAL_MAX;
5225 } else {
5226 my_ap2.min = ap2->min;
5227 my_ap2.max = ap2->max;
5228 }
5229
5230 /* The action probabilities now have a math friendly form. */
5231 fc_assert(!action_prob_is_signal(my_ap1));
5232 fc_assert(!action_prob_is_signal(my_ap2));
5233
5234 /* Do the math. */
5235 out.min = (my_ap1.min * my_ap2.min) / ACTPROB_VAL_MAX;
5236 out.max = (my_ap1.max * my_ap2.max) / ACTPROB_VAL_MAX;
5237
5238 /* Cap at 100%. */
5239 out.min = MIN(out.min, ACTPROB_VAL_MAX);
5240 out.max = MIN(out.max, ACTPROB_VAL_MAX);
5241
5242 return out;
5243}
5244
5245/**********************************************************************/
5252 struct act_prob action_prob_fall_back(const struct act_prob *ap1,
5253 const struct act_prob *ap2)
5254{
5255 struct act_prob my_ap1;
5256 struct act_prob my_ap2;
5257 struct act_prob out;
5258
5259 /* The action probabilities are real. */
5260 fc_assert(ap1 && !action_prob_not_relevant(*ap1));
5261 fc_assert(ap2 && !action_prob_not_relevant(*ap2));
5262
5263 if (action_prob_is_signal(*ap1)
5264 && are_action_probabilitys_equal(ap1, ap2)) {
5265 /* Keep the information rather than converting the signal to
5266 * ACTPROB_NOT_KNOWN. */
5267
5268 /* Assert that it is OK to convert the signal. */
5269 fc_assert(action_prob_not_impl(*ap1));
5270
5271 out.min = ap1->min;
5272 out.max = ap2->max;
5273
5274 return out;
5275 }
5276
5277 /* Convert any signals to ACTPROB_NOT_KNOWN. */
5278 if (action_prob_is_signal(*ap1)) {
5279 /* Assert that it is OK to convert the signal. */
5280 fc_assert(action_prob_not_impl(*ap1));
5281
5282 my_ap1.min = ACTPROB_VAL_MIN;
5283 my_ap1.max = ACTPROB_VAL_MAX;
5284 } else {
5285 my_ap1.min = ap1->min;
5286 my_ap1.max = ap1->max;
5287 }
5288
5289 if (action_prob_is_signal(*ap2)) {
5290 /* Assert that it is OK to convert the signal. */
5291 fc_assert(action_prob_not_impl(*ap2));
5292
5293 my_ap2.min = ACTPROB_VAL_MIN;
5294 my_ap2.max = ACTPROB_VAL_MAX;
5295 } else {
5296 my_ap2.min = ap2->min;
5297 my_ap2.max = ap2->max;
5298 }
5299
5300 /* The action probabilities now have a math friendly form. */
5301 fc_assert(!action_prob_is_signal(my_ap1));
5302 fc_assert(!action_prob_is_signal(my_ap2));
5303
5304 /* Do the math. */
5305 out.min = my_ap1.min + (((ACTPROB_VAL_MAX - my_ap1.min) * my_ap2.min)
5306 / ACTPROB_VAL_MAX);
5307 out.max = my_ap1.max + (((ACTPROB_VAL_MAX - my_ap1.max) * my_ap2.max)
5308 / ACTPROB_VAL_MAX);
5309
5310 /* Cap at 100%. */
5311 out.min = MIN(out.min, ACTPROB_VAL_MAX);
5312 out.max = MIN(out.max, ACTPROB_VAL_MAX);
5313
5314 return out;
5315}
5316
5317/**********************************************************************/
5320 int action_dice_roll_initial_odds(const struct action *paction)
5321{
5322 switch (actres_dice_type(paction->result)) {
5323 case DRT_DIPLCHANCE:
5324 if (BV_ISSET(game.info.diplchance_initial_odds, paction->id)) {
5325 /* Take the initial odds from the diplchance setting. */
5326 return server_setting_value_int_get(
5327 server_setting_by_name("diplchance"));
5328 }
5329 fc__fallthrough;
5330 case DRT_CERTAIN:
5331 return 100;
5332 case DRT_NONE:
5333 break;
5334 }
5335
5336 /* The odds of the action not being stopped by its dice roll when the dice
5337 * isn't thrown is 100%. ACTION_ODDS_PCT_DICE_ROLL_NA is above 100% */
5338 return ACTION_ODDS_PCT_DICE_ROLL_NA;
5339}
5340
5341/**********************************************************************/
5344 int action_dice_roll_odds(const struct player *act_player,
5345 const struct unit *act_unit,
5346 const struct city *tgt_city,
5347 const struct player *tgt_player,
5348 const struct action *paction)
5349{
5350 int odds = action_dice_roll_initial_odds(paction);
5351 const struct unit_type *actu_type = unit_type_get(act_unit);
5352
5353 fc_assert_action_msg(odds >= 0 && odds <= 100,
5354 odds = 100,
5355 "Bad initial odds for action number %d."
5356 " Does it roll the dice at all?",
5357 paction->id);
5358
5359 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
5360 * it this way instead of rolling twice is that Action_Odds_Pct can
5361 * increase the odds. */
5362 odds = odds
5363 + ((odds
5364 * get_target_bonus_effects(NULL,
5365 &(const struct req_context) {
5366 .player = act_player,
5367 .city = tgt_city,
5368 .unit = act_unit,
5369 .unittype = actu_type,
5370 .action = paction,
5371 },
5372 &(const struct req_context) {
5373 .player = tgt_player,
5374 },
5375 EFT_ACTION_ODDS_PCT))
5376 / 100)
5377 - ((odds
5378 * get_target_bonus_effects(NULL,
5379 &(const struct req_context) {
5380 .player = tgt_player,
5381 .city = tgt_city,
5382 .unit = act_unit,
5383 .unittype = actu_type,
5384 .action = paction,
5385 },
5386 &(const struct req_context) {
5387 .player = act_player,
5388 },
5389 EFT_ACTION_RESIST_PCT))
5390 / 100);
5391
5392
5393 /* Odds are between 0% and 100%. */
5394 return CLIP(0, odds, 100);
5395}
5396
5397/**********************************************************************/
5400 bool action_immune_government(struct government *gov, action_id act)
5401{
5402 struct action *paction = action_by_number(act);
5403
5404 /* Always immune since its not enabled. Doesn't count. */
5405 if (!action_is_in_use(paction)) {
5406 return FALSE;
5407 }
5408
5409 action_enabler_list_iterate(action_enablers_for_action(act), enabler) {
5410 if (requirement_fulfilled_by_government(gov, &(enabler->target_reqs))) {
5411 return FALSE;
5412 }
5413 } action_enabler_list_iterate_end;
5414
5415 return TRUE;
5416}
5417
5418/**********************************************************************/
5423 static bool is_target_possible(const action_id wanted_action,
5424 const struct player *actor_player,
5425 const struct req_context *target)
5426{
5427 action_enabler_list_iterate(action_enablers_for_action(wanted_action),
5428 enabler) {
5429 if (are_reqs_active(target,
5430 &(const struct req_context) {
5431 .player = actor_player,
5432 },
5433 &enabler->target_reqs, RPT_POSSIBLE)) {
5434 return TRUE;
5435 }
5436 } action_enabler_list_iterate_end;
5437
5438 return FALSE;
5439}
5440
5441/**********************************************************************/
5444 bool is_action_possible_on_city(action_id act_id,
5445 const struct player *actor_player,
5446 const struct city* target_city)
5447{
5448 fc_assert_ret_val_msg(ATK_CITY == action_id_get_target_kind(act_id),
5449 FALSE, "Action %s is against %s not cities",
5450 action_id_rule_name(act_id),
5451 action_target_kind_name(
5452 action_id_get_target_kind(act_id)));
5453
5454 return is_target_possible(act_id, actor_player,
5455 &(const struct req_context) {
5456 .player = city_owner(target_city),
5457 .city = target_city,
5458 .tile = city_tile(target_city),
5459 });
5460}
5461
5462/**********************************************************************/
5467 bool action_maybe_possible_actor_unit(const struct civ_map *nmap,
5468 const action_id act_id,
5469 const struct unit *actor_unit)
5470{
5471 const struct player *actor_player = unit_owner(actor_unit);
5472 const struct req_context actor_ctxt = {
5473 .player = actor_player,
5474 .city = tile_city(unit_tile(actor_unit)),
5475 .tile = unit_tile(actor_unit),
5476 .unit = actor_unit,
5477 .unittype = unit_type_get(actor_unit),
5478 };
5479 const struct action *paction = action_by_number(act_id);
5480
5481 enum fc_tristate result;
5482
5483 fc_assert_ret_val(actor_unit, FALSE);
5484
5485 if (!utype_can_do_action(actor_unit->utype, act_id)) {
5486 /* The unit type can't perform the action. */
5487 return FALSE;
5488 }
5489
5490 result = action_hard_reqs_actor(nmap, paction, &actor_ctxt, FALSE,
5491 unit_home(actor_unit));
5492
5493 if (result == TRI_NO) {
5494 /* The hard requirements aren't fulfilled. */
5495 return FALSE;
5496 }
5497
5498 action_enabler_list_iterate(action_enablers_for_action(act_id),
5499 enabler) {
5500 const enum fc_tristate current
5501 = mke_eval_reqs(actor_player, &actor_ctxt, NULL,
5502 &enabler->actor_reqs,
5503 /* Needed since no player to evaluate DiplRel
5504 * requirements against. */
5505 RPT_POSSIBLE);
5506
5507 if (current == TRI_YES
5508 || current == TRI_MAYBE) {
5509 /* The ruleset requirements may be fulfilled. */
5510 return TRUE;
5511 }
5512 } action_enabler_list_iterate_end;
5513
5514 /* No action enabler allows this action. */
5515 return FALSE;
5516}
5517
5518/**********************************************************************/
5522 bool action_mp_full_makes_legal(const struct unit *actor,
5523 const action_id act_id)
5524{
5525 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
5526
5527 /* Check if full movement points may enable the specified action. */
5528 return !utype_may_act_move_frags(unit_type_get(actor),
5529 act_id,
5530 actor->moves_left)
5531 && utype_may_act_move_frags(unit_type_get(actor),
5532 act_id,
5533 unit_move_rate(actor));
5534}
5535
5536/**********************************************************************/
5545 bool action_enabler_utype_possible_actor(const struct action_enabler *ae,
5546 const struct unit_type *act_utype)
5547{
5548 const struct action *paction = enabler_get_action(ae);
5549 struct universal actor_univ = { .kind = VUT_UTYPE,
5550 .value.utype = act_utype };
5551
5552 fc_assert_ret_val(paction != NULL, FALSE);
5553 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
5554 fc_assert_ret_val(act_utype != NULL, FALSE);
5555
5556 return (action_actor_utype_hard_reqs_ok(paction, act_utype)
5557 && !req_vec_is_impossible_to_fulfill(&ae->actor_reqs)
5558 && universal_fulfills_requirements(FALSE, &ae->actor_reqs,
5559 &actor_univ));
5560}
5561
5562/**********************************************************************/
5572 bool action_enabler_possible_actor(const struct action_enabler *ae)
5573{
5574 const struct action *paction = enabler_get_action(ae);
5575
5576 switch (action_get_actor_kind(paction)) {
5577 case AAK_UNIT:
5578 unit_type_iterate(putype) {
5579 if (action_enabler_utype_possible_actor(ae, putype)) {
5580 /* A possible actor unit type has been found. */
5581 return TRUE;
5582 }
5583 } unit_type_iterate_end;
5584
5585 /* No actor detected. */
5586 return FALSE;
5587 case AAK_COUNT:
5588 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
5589 break;
5590 }
5591
5592 /* No actor detected. */
5593 return FALSE;
5594}
5595
5596/**********************************************************************/
5603 static bool action_has_possible_actor_hard_reqs(struct action *paction)
5604{
5605 switch (action_get_actor_kind(paction)) {
5606 case AAK_UNIT:
5607 unit_type_iterate(putype) {
5608 if (action_actor_utype_hard_reqs_ok(paction, putype)) {
5609 return TRUE;
5610 }
5611 } unit_type_iterate_end;
5612 break;
5613 case AAK_COUNT:
5614 fc_assert(action_get_actor_kind(paction) != AAK_COUNT);
5615 break;
5616 }
5617
5618 /* No actor detected. */
5619 return FALSE;
5620}
5621
5622/**********************************************************************/
5629 bool action_is_in_use(struct action *paction)
5630{
5631 struct action_enabler_list *enablers;
5632
5633 if (!action_has_possible_actor_hard_reqs(paction)) {
5634 /* Hard requirements not fulfilled. */
5635 return FALSE;
5636 }
5637
5638 enablers = action_enablers_for_action(paction->id);
5639
5640 action_enabler_list_re_iterate(enablers, ae) {
5641 /* If this iteration finds any entries, action is enabled. */
5642 return TRUE;
5643 } action_enabler_list_re_iterate_end;
5644
5645 /* No non deleted action enabler. */
5646 return FALSE;
5647}
5648
5649/**********************************************************************/
5655 bool action_is_internal(struct action *paction)
5656{
5657 return paction != nullptr
5658 && action_has_result(paction, ACTRES_ENABLER_CHECK);
5659}
5660
5661/**********************************************************************/
5667 bool action_id_is_internal(action_id act)
5668{
5669 return action_is_internal(action_by_number(act));
5670}
5671
5672/**********************************************************************/
5675 struct action_auto_perf *action_auto_perf_slot_number(const int num)
5676{
5677 fc_assert_ret_val(num >= 0, NULL);
5678 fc_assert_ret_val(num < MAX_NUM_ACTION_AUTO_PERFORMERS, NULL);
5679
5680 return &auto_perfs[num];
5681}
5682
5683/**********************************************************************/
5691 const struct action_auto_perf *action_auto_perf_by_number(const int num)
5692{
5693 return action_auto_perf_slot_number(num);
5694}
5695
5696/**********************************************************************/
5699 bool action_univs_not_blocking(const struct action *paction,
5700 struct universal *actor_uni,
5701 struct universal *target_uni)
5702{
5703 action_enabler_list_iterate(action_enablers_for_action(paction->id),
5704 enab) {
5705 if ((actor_uni == NULL
5706 || universal_fulfills_requirements(FALSE, &(enab->actor_reqs),
5707 actor_uni))
5708 && (target_uni == NULL
5709 || universal_fulfills_requirements(FALSE, &(enab->target_reqs),
5710 target_uni))) {
5711 return TRUE;
5712 }
5713 } action_enabler_list_iterate_end;
5714
5715 return FALSE;
5716}
5717
5718/**********************************************************************/
5723 void action_array_end(action_id *act_array, int size)
5724{
5725 fc_assert_ret(size <= MAX_NUM_ACTIONS);
5726
5727 if (size < MAX_NUM_ACTIONS) {
5728 /* An action array is terminated by ACTION_NONE */
5729 act_array[size] = ACTION_NONE;
5730 }
5731}
5732
5733/**********************************************************************/
5740 void action_array_add_all_by_result(action_id *act_array,
5741 int *position,
5742 enum action_result result)
5743{
5744 action_iterate(act) {
5745 struct action *paction = action_by_number(act);
5746 if (paction->result == result) {
5747 /* Assume one result for each action. */
5748 fc_assert_ret(*position < MAX_NUM_ACTIONS);
5749
5750 act_array[(*position)++] = paction->id;
5751 }
5752 } action_iterate_end;
5753}
5754
5755/**********************************************************************/
5760 const char *action_ui_name_ruleset_var_name(int act)
5761{
5762 switch ((enum gen_action)act) {
5763 case ACTION_SPY_POISON:
5764 return "ui_name_poison_city";
5765 case ACTION_SPY_POISON_ESC:
5766 return "ui_name_poison_city_escape";
5767 case ACTION_SPY_SABOTAGE_UNIT:
5768 return "ui_name_sabotage_unit";
5769 case ACTION_SPY_SABOTAGE_UNIT_ESC:
5770 return "ui_name_sabotage_unit_escape";
5771 case ACTION_SPY_BRIBE_UNIT:
5772 return "ui_name_bribe_unit";
5773 case ACTION_SPY_SABOTAGE_CITY:
5774 return "ui_name_sabotage_city";
5775 case ACTION_SPY_SABOTAGE_CITY_ESC:
5776 return "ui_name_sabotage_city_escape";
5777 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
5778 return "ui_name_targeted_sabotage_city";
5779 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
5780 return "ui_name_sabotage_city_production";
5781 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
5782 return "ui_name_targeted_sabotage_city_escape";
5783 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
5784 return "ui_name_sabotage_city_production_escape";
5785 case ACTION_SPY_INCITE_CITY:
5786 return "ui_name_incite_city";
5787 case ACTION_SPY_INCITE_CITY_ESC:
5788 return "ui_name_incite_city_escape";
5789 case ACTION_ESTABLISH_EMBASSY:
5790 return "ui_name_establish_embassy";
5791 case ACTION_ESTABLISH_EMBASSY_STAY:
5792 return "ui_name_establish_embassy_stay";
5793 case ACTION_SPY_STEAL_TECH:
5794 return "ui_name_steal_tech";
5795 case ACTION_SPY_STEAL_TECH_ESC:
5796 return "ui_name_steal_tech_escape";
5797 case ACTION_SPY_TARGETED_STEAL_TECH:
5798 return "ui_name_targeted_steal_tech";
5799 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
5800 return "ui_name_targeted_steal_tech_escape";
5801 case ACTION_SPY_INVESTIGATE_CITY:
5802 return "ui_name_investigate_city";
5803 case ACTION_INV_CITY_SPEND:
5804 return "ui_name_investigate_city_spend_unit";
5805 case ACTION_SPY_STEAL_GOLD:
5806 return "ui_name_steal_gold";
5807 case ACTION_SPY_STEAL_GOLD_ESC:
5808 return "ui_name_steal_gold_escape";
5809 case ACTION_SPY_SPREAD_PLAGUE:
5810 return "ui_name_spread_plague";
5811 case ACTION_STEAL_MAPS:
5812 return "ui_name_steal_maps";
5813 case ACTION_STEAL_MAPS_ESC:
5814 return "ui_name_steal_maps_escape";
5815 case ACTION_TRADE_ROUTE:
5816 return "ui_name_establish_trade_route";
5817 case ACTION_MARKETPLACE:
5818 return "ui_name_enter_marketplace";
5819 case ACTION_HELP_WONDER:
5820 return "ui_name_help_wonder";
5821 case ACTION_CAPTURE_UNITS:
5822 return "ui_name_capture_units";
5823 case ACTION_EXPEL_UNIT:
5824 return "ui_name_expel_unit";
5825 case ACTION_FOUND_CITY:
5826 return "ui_name_found_city";
5827 case ACTION_JOIN_CITY:
5828 return "ui_name_join_city";
5829 case ACTION_BOMBARD:
5830 return "ui_name_bombard";
5831 case ACTION_BOMBARD2:
5832 return "ui_name_bombard_2";
5833 case ACTION_BOMBARD3:
5834 return "ui_name_bombard_3";
5835 case ACTION_BOMBARD4:
5836 return "ui_name_bombard_4";
5837 case ACTION_BOMBARD_LETHAL:
5838 return "ui_name_bombard_lethal";
5839 case ACTION_BOMBARD_LETHAL2:
5840 return "ui_name_bombard_lethal_2";
5841 case ACTION_SPY_NUKE:
5842 return "ui_name_suitcase_nuke";
5843 case ACTION_SPY_NUKE_ESC:
5844 return "ui_name_suitcase_nuke_escape";
5845 case ACTION_NUKE:
5846 return "ui_name_explode_nuclear";
5847 case ACTION_NUKE_CITY:
5848 return "ui_name_nuke_city";
5849 case ACTION_NUKE_UNITS:
5850 return "ui_name_nuke_units";
5851 case ACTION_DESTROY_CITY:
5852 return "ui_name_destroy_city";
5853 case ACTION_DISBAND_UNIT_RECOVER:
5854 return "ui_name_disband_unit_recover";
5855 case ACTION_DISBAND_UNIT:
5856 return "ui_name_disband_unit";
5857 case ACTION_HOME_CITY:
5858 return "ui_name_home_city";
5859 case ACTION_HOMELESS:
5860 return "ui_name_homeless";
5861 case ACTION_UPGRADE_UNIT:
5862 return "ui_name_upgrade_unit";
5863 case ACTION_PARADROP:
5864 return "ui_name_paradrop_unit";
5865 case ACTION_PARADROP_CONQUER:
5866 return "ui_name_paradrop_unit_conquer";
5867 case ACTION_PARADROP_FRIGHTEN:
5868 return "ui_name_paradrop_unit_frighten";
5869 case ACTION_PARADROP_FRIGHTEN_CONQUER:
5870 return "ui_name_paradrop_unit_frighten_conquer";
5871 case ACTION_PARADROP_ENTER:
5872 return "ui_name_paradrop_unit_enter";
5873 case ACTION_PARADROP_ENTER_CONQUER:
5874 return "ui_name_paradrop_unit_enter_conquer";
5875 case ACTION_AIRLIFT:
5876 return "ui_name_airlift_unit";
5877 case ACTION_ATTACK:
5878 return "ui_name_attack";
5879 case ACTION_ATTACK2:
5880 return "ui_name_attack_2";
5881 case ACTION_SUICIDE_ATTACK:
5882 return "ui_name_suicide_attack";
5883 case ACTION_SUICIDE_ATTACK2:
5884 return "ui_name_suicide_attack_2";
5885 case ACTION_WIPE_UNITS:
5886 return "ui_name_wipe_units";
5887 case ACTION_COLLECT_RANSOM:
5888 return "ui_name_collect_ransom";
5889 case ACTION_STRIKE_BUILDING:
5890 return "ui_name_surgical_strike_building";
5891 case ACTION_STRIKE_PRODUCTION:
5892 return "ui_name_surgical_strike_production";
5893 case ACTION_CONQUER_CITY:
5894 return "ui_name_conquer_city";
5895 case ACTION_CONQUER_CITY2:
5896 return "ui_name_conquer_city_2";
5897 case ACTION_CONQUER_CITY3:
5898 return "ui_name_conquer_city_3";
5899 case ACTION_CONQUER_CITY4:
5900 return "ui_name_conquer_city_4";
5901 case ACTION_CONQUER_EXTRAS:
5902 return "ui_name_conquer_extras";
5903 case ACTION_CONQUER_EXTRAS2:
5904 return "ui_name_conquer_extras_2";
5905 case ACTION_CONQUER_EXTRAS3:
5906 return "ui_name_conquer_extras_3";
5907 case ACTION_CONQUER_EXTRAS4:
5908 return "ui_name_conquer_extras_4";
5909 case ACTION_HEAL_UNIT:
5910 return "ui_name_heal_unit";
5911 case ACTION_HEAL_UNIT2:
5912 return "ui_name_heal_unit_2";
5913 case ACTION_TRANSFORM_TERRAIN:
5914 return "ui_name_transform_terrain";
5915 case ACTION_TRANSFORM_TERRAIN2:
5916 return "ui_name_transform_terrain_2";
5917 case ACTION_CULTIVATE:
5918 return "ui_name_cultivate";
5919 case ACTION_CULTIVATE2:
5920 return "ui_name_cultivate_2";
5921 case ACTION_PLANT:
5922 return "ui_name_plant";
5923 case ACTION_PLANT2:
5924 return "ui_name_plant_2";
5925 case ACTION_PILLAGE:
5926 return "ui_name_pillage";
5927 case ACTION_PILLAGE2:
5928 return "ui_name_pillage_2";
5929 case ACTION_CLEAN:
5930 return "ui_name_clean";
5931 case ACTION_CLEAN2:
5932 return "ui_name_clean_2";
5933 case ACTION_FORTIFY:
5934 return "ui_name_fortify";
5935 case ACTION_FORTIFY2:
5936 return "ui_name_fortify_2";
5937 case ACTION_ROAD:
5938 return "ui_name_build_road";
5939 case ACTION_ROAD2:
5940 return "ui_name_build_road_2";
5941 case ACTION_CONVERT:
5942 return "ui_name_convert_unit";
5943 case ACTION_BASE:
5944 return "ui_name_build_base";
5945 case ACTION_BASE2:
5946 return "ui_name_build_base_2";
5947 case ACTION_MINE:
5948 return "ui_name_build_mine";
5949 case ACTION_MINE2:
5950 return "ui_name_build_mine_2";
5951 case ACTION_IRRIGATE:
5952 return "ui_name_irrigate";
5953 case ACTION_IRRIGATE2:
5954 return "ui_name_irrigate_2";
5955 case ACTION_TRANSPORT_DEBOARD:
5956 return "ui_name_transport_deboard";
5957 case ACTION_TRANSPORT_BOARD:
5958 return "ui_name_transport_board";
5959 case ACTION_TRANSPORT_BOARD2:
5960 return "ui_name_transport_board_2";
5961 case ACTION_TRANSPORT_BOARD3:
5962 return "ui_name_transport_board_3";
5963 case ACTION_TRANSPORT_EMBARK:
5964 return "ui_name_transport_embark";
5965 case ACTION_TRANSPORT_EMBARK2:
5966 return "ui_name_transport_embark_2";
5967 case ACTION_TRANSPORT_EMBARK3:
5968 return "ui_name_transport_embark_3";
5969 case ACTION_TRANSPORT_EMBARK4:
5970 return "ui_name_transport_embark_4";
5971 case ACTION_TRANSPORT_UNLOAD:
5972 return "ui_name_transport_unload";
5973 case ACTION_TRANSPORT_LOAD:
5974 return "ui_name_transport_load";
5975 case ACTION_TRANSPORT_LOAD2:
5976 return "ui_name_transport_load_2";
5977 case ACTION_TRANSPORT_LOAD3:
5978 return "ui_name_transport_load_3";
5979 case ACTION_TRANSPORT_DISEMBARK1:
5980 return "ui_name_transport_disembark";
5981 case ACTION_TRANSPORT_DISEMBARK2:
5982 return "ui_name_transport_disembark_2";
5983 case ACTION_TRANSPORT_DISEMBARK3:
5984 return "ui_name_transport_disembark_3";
5985 case ACTION_TRANSPORT_DISEMBARK4:
5986 return "ui_name_transport_disembark_4";
5987 case ACTION_HUT_ENTER:
5988 return "ui_name_enter_hut";
5989 case ACTION_HUT_ENTER2:
5990 return "ui_name_enter_hut_2";
5991 case ACTION_HUT_ENTER3:
5992 return "ui_name_enter_hut_3";
5993 case ACTION_HUT_ENTER4:
5994 return "ui_name_enter_hut_4";
5995 case ACTION_HUT_FRIGHTEN:
5996 return "ui_name_frighten_hut";
5997 case ACTION_HUT_FRIGHTEN2:
5998 return "ui_name_frighten_hut_2";
5999 case ACTION_HUT_FRIGHTEN3:
6000 return "ui_name_frighten_hut_3";
6001 case ACTION_HUT_FRIGHTEN4:
6002 return "ui_name_frighten_hut_4";
6003 case ACTION_SPY_ATTACK:
6004 return "ui_name_spy_attack";
6005 case ACTION_UNIT_MOVE:
6006 return "ui_name_unit_move";
6007 case ACTION_UNIT_MOVE2:
6008 return "ui_name_unit_move_2";
6009 case ACTION_UNIT_MOVE3:
6010 return "ui_name_unit_move_3";
6011 case ACTION_TELEPORT:
6012 return "ui_name_teleport";
6013 case ACTION_TELEPORT2:
6014 return "ui_name_teleport_2";
6015 case ACTION_TELEPORT3:
6016 return "ui_name_teleport_3";
6017 case ACTION_TELEPORT_CONQUER:
6018 return "ui_name_teleport_conquer";
6019 case ACTION_TELEPORT_FRIGHTEN:
6020 return "ui_name_teleport_frighten";
6021 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6022 return "ui_name_teleport_frighten_conquer";
6023 case ACTION_TELEPORT_ENTER:
6024 return "ui_name_teleport_enter";
6025 case ACTION_TELEPORT_ENTER_CONQUER:
6026 return "ui_name_teleport_enter_conquer";
6027 case ACTION_SPY_ESCAPE:
6028 return "ui_name_escape";
6029 case ACTION_USER_ACTION1:
6030 return "ui_name_user_action_1";
6031 case ACTION_USER_ACTION2:
6032 return "ui_name_user_action_2";
6033 case ACTION_USER_ACTION3:
6034 return "ui_name_user_action_3";
6035 case ACTION_USER_ACTION4:
6036 return "ui_name_user_action_4";
6037 case ACTION_GAIN_VETERANCY:
6038 case ACTION_ESCAPE:
6039 fc_assert(!action_id_is_internal(act)); /* Fail always */
6040 break;
6041 case ACTION_COUNT:
6042 break;
6043
6044 ASSERT_UNUSED_ACTION_CASES;
6045 }
6046
6047 fc_assert(act >= 0 && act < ACTION_COUNT);
6048
6049 return NULL;
6050}
6051
6052/**********************************************************************/
6055 const char *action_ui_name_default(int act)
6056{
6057 switch ((enum gen_action)act) {
6058 case ACTION_SPY_POISON:
6059 /* TRANS: _Poison City (3% chance of success). */
6060 return N_("%sPoison City%s");
6061 case ACTION_SPY_POISON_ESC:
6062 /* TRANS: _Poison City and Escape (3% chance of success). */
6063 return N_("%sPoison City and Escape%s");
6064 case ACTION_SPY_SABOTAGE_UNIT:
6065 /* TRANS: S_abotage Enemy Unit (3% chance of success). */
6066 return N_("S%sabotage Enemy Unit%s");
6067 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6068 /* TRANS: S_abotage Enemy Unit and Escape (3% chance of success). */
6069 return N_("S%sabotage Enemy Unit and Escape%s");
6070 case ACTION_SPY_BRIBE_UNIT:
6071 /* TRANS: Bribe Enemy _Unit (3% chance of success). */
6072 return N_("Bribe Enemy %sUnit%s");
6073 case ACTION_SPY_SABOTAGE_CITY:
6074 /* TRANS: _Sabotage City (3% chance of success). */
6075 return N_("%sSabotage City%s");
6076 case ACTION_SPY_SABOTAGE_CITY_ESC:
6077 /* TRANS: _Sabotage City and Escape (3% chance of success). */
6078 return N_("%sSabotage City and Escape%s");
6079 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6080 /* TRANS: Industria_l Sabotage (3% chance of success). */
6081 return N_("Industria%sl Sabotage%s");
6082 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6083 /* TRANS: Industria_l Sabotage Production (3% chance of success). */
6084 return N_("Industria%sl Sabotage Production%s");
6085 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6086 /* TRANS: Industria_l Sabotage and Escape (3% chance of success). */
6087 return N_("Industria%sl Sabotage and Escape%s");
6088 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6089 /* TRANS: Industria_l Sabotage Production and Escape (3% chance of success). */
6090 return N_("Industria%sl Sabotage Production and Escape%s");
6091 case ACTION_SPY_INCITE_CITY:
6092 /* TRANS: Incite a Re_volt (3% chance of success). */
6093 return N_("Incite a Re%svolt%s");
6094 case ACTION_SPY_INCITE_CITY_ESC:
6095 /* TRANS: Incite a Re_volt and Escape (3% chance of success). */
6096 return N_("Incite a Re%svolt and Escape%s");
6097 case ACTION_ESTABLISH_EMBASSY:
6098 /* TRANS: Establish _Embassy (100% chance of success). */
6099 return N_("Establish %sEmbassy%s");
6100 case ACTION_ESTABLISH_EMBASSY_STAY:
6101 /* TRANS: Becom_e Ambassador (100% chance of success). */
6102 return N_("Becom%se Ambassador%s");
6103 case ACTION_SPY_STEAL_TECH:
6104 /* TRANS: Steal _Technology (3% chance of success). */
6105 return N_("Steal %sTechnology%s");
6106 case ACTION_SPY_STEAL_TECH_ESC:
6107 /* TRANS: Steal _Technology and Escape (3% chance of success). */
6108 return N_("Steal %sTechnology and Escape%s");
6109 case ACTION_SPY_TARGETED_STEAL_TECH:
6110 /* TRANS: In_dustrial Espionage (3% chance of success). */
6111 return N_("In%sdustrial Espionage%s");
6112 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6113 /* TRANS: In_dustrial Espionage and Escape (3% chance of success). */
6114 return N_("In%sdustrial Espionage and Escape%s");
6115 case ACTION_SPY_INVESTIGATE_CITY:
6116 /* TRANS: _Investigate City (100% chance of success). */
6117 return N_("%sInvestigate City%s");
6118 case ACTION_INV_CITY_SPEND:
6119 /* TRANS: _Investigate City (spends the unit) (100% chance of
6120 * success). */
6121 return N_("%sInvestigate City (spends the unit)%s");
6122 case ACTION_SPY_STEAL_GOLD:
6123 /* TRANS: Steal _Gold (100% chance of success). */
6124 return N_("Steal %sGold%s");
6125 case ACTION_SPY_STEAL_GOLD_ESC:
6126 /* TRANS: Steal _Gold and Escape (100% chance of success). */
6127 return N_("Steal %sGold and Escape%s");
6128 case ACTION_SPY_SPREAD_PLAGUE:
6129 /* TRANS: Spread _Plague (100% chance of success). */
6130 return N_("Spread %sPlague%s");
6131 case ACTION_STEAL_MAPS:
6132 /* TRANS: Steal _Maps (100% chance of success). */
6133 return N_("Steal %sMaps%s");
6134 case ACTION_STEAL_MAPS_ESC:
6135 /* TRANS: Steal _Maps and Escape (100% chance of success). */
6136 return N_("Steal %sMaps and Escape%s");
6137 case ACTION_TRADE_ROUTE:
6138 /* TRANS: Establish Trade _Route (100% chance of success). */
6139 return N_("Establish Trade %sRoute%s");
6140 case ACTION_MARKETPLACE:
6141 /* TRANS: Enter _Marketplace (100% chance of success). */
6142 return N_("Enter %sMarketplace%s");
6143 case ACTION_HELP_WONDER:
6144 /* TRANS: Help _build Wonder (100% chance of success). */
6145 return N_("Help %sbuild Wonder%s");
6146 case ACTION_CAPTURE_UNITS:
6147 /* TRANS: _Capture Units (100% chance of success). */
6148 return N_("%sCapture Units%s");
6149 case ACTION_EXPEL_UNIT:
6150 /* TRANS: _Expel Unit (100% chance of success). */
6151 return N_("%sExpel Unit%s");
6152 case ACTION_FOUND_CITY:
6153 /* TRANS: _Found City (100% chance of success). */
6154 return N_("%sFound City%s");
6155 case ACTION_JOIN_CITY:
6156 /* TRANS: _Join City (100% chance of success). */
6157 return N_("%sJoin City%s");
6158 case ACTION_BOMBARD:
6159 /* TRANS: B_ombard (100% chance of success). */
6160 return N_("B%sombard%s");
6161 case ACTION_BOMBARD2:
6162 /* TRANS: B_ombard 2 (100% chance of success). */
6163 return N_("B%sombard 2%s");
6164 case ACTION_BOMBARD3:
6165 /* TRANS: B_ombard 3 (100% chance of success). */
6166 return N_("B%sombard 3%s");
6167 case ACTION_BOMBARD4:
6168 /* TRANS: B_ombard 4 (100% chance of success). */
6169 return N_("B%sombard 4%s");
6170 case ACTION_BOMBARD_LETHAL:
6171 case ACTION_BOMBARD_LETHAL2:
6172 /* TRANS: Lethal B_ombard (100% chance of success). */
6173 return N_("Lethal B%sombard%s");
6174 case ACTION_SPY_NUKE:
6175 /* TRANS: Suitcase _Nuke (100% chance of success). */
6176 return N_("Suitcase %sNuke%s");
6177 case ACTION_SPY_NUKE_ESC:
6178 /* TRANS: Suitcase _Nuke and Escape (100% chance of success). */
6179 return N_("Suitcase %sNuke and Escape%s");
6180 case ACTION_NUKE:
6181 /* TRANS: Explode _Nuclear (100% chance of success). */
6182 return N_("Explode %sNuclear%s");
6183 case ACTION_NUKE_CITY:
6184 /* TRANS: _Nuke City (100% chance of success). */
6185 return N_("%sNuke City%s");
6186 case ACTION_NUKE_UNITS:
6187 /* TRANS: _Nuke Units (100% chance of success). */
6188 return N_("%sNuke Units%s");
6189 case ACTION_DESTROY_CITY:
6190 /* TRANS: Destroy _City (100% chance of success). */
6191 return N_("Destroy %sCity%s");
6192 case ACTION_DISBAND_UNIT_RECOVER:
6193 /* TRANS: Dis_band recovering production (100% chance of success). */
6194 return N_("Dis%sband recovering production%s");
6195 case ACTION_DISBAND_UNIT:
6196 /* TRANS: Dis_band without recovering production (100% chance of success). */
6197 return N_("Dis%sband without recovering production%s");
6198 case ACTION_HOME_CITY:
6199 /* TRANS: Set _Home City (100% chance of success). */
6200 return N_("Set %sHome City%s");
6201 case ACTION_HOMELESS:
6202 /* TRANS: Make _Homeless (100% chance of success). */
6203 return N_("Make %sHomeless%s");
6204 case ACTION_UPGRADE_UNIT:
6205 /* TRANS: _Upgrade Unit (100% chance of success). */
6206 return N_("%sUpgrade Unit%s");
6207 case ACTION_PARADROP:
6208 /* TRANS: Drop _Paratrooper (100% chance of success). */
6209 return N_("Drop %sParatrooper%s");
6210 case ACTION_PARADROP_CONQUER:
6211 /* TRANS: Drop _Paratrooper (100% chance of success). */
6212 return N_("Drop %sParatrooper%s");
6213 case ACTION_PARADROP_FRIGHTEN:
6214 /* TRANS: Drop _Paratrooper (100% chance of success). */
6215 return N_("Drop %sParatrooper%s");
6216 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6217 /* TRANS: Drop _Paratrooper (100% chance of success). */
6218 return N_("Drop %sParatrooper%s");
6219 case ACTION_PARADROP_ENTER:
6220 /* TRANS: Drop _Paratrooper (100% chance of success). */
6221 return N_("Drop %sParatrooper%s");
6222 case ACTION_PARADROP_ENTER_CONQUER:
6223 /* TRANS: Drop _Paratrooper (100% chance of success). */
6224 return N_("Drop %sParatrooper%s");
6225 case ACTION_AIRLIFT:
6226 /* TRANS: _Airlift to City (100% chance of success). */
6227 return N_("%sAirlift to City%s");
6228 case ACTION_ATTACK:
6229 case ACTION_ATTACK2:
6230 /* TRANS: _Attack (100% chance of success). */
6231 return N_("%sAttack%s");
6232 case ACTION_SUICIDE_ATTACK:
6233 case ACTION_SUICIDE_ATTACK2:
6234 /* TRANS: _Suicide Attack (100% chance of success). */
6235 return N_("%sSuicide Attack%s");
6236 case ACTION_WIPE_UNITS:
6237 /* TRANS: _Wipe Units (100% chance of success). */
6238 return N_("%sWipe Units%s");
6239 case ACTION_COLLECT_RANSOM:
6240 /* TRANS: Collect _Ransom (100% chance of success). */
6241 return N_("Collect %sRansom%s");
6242 case ACTION_STRIKE_BUILDING:
6243 /* TRANS: Surgical Str_ike Building (100% chance of success). */
6244 return N_("Surgical Str%sike Building%s");
6245 case ACTION_STRIKE_PRODUCTION:
6246 /* TRANS: Surgical Str_ike Production (100% chance of success). */
6247 return N_("Surgical Str%sike Production%s");
6248 case ACTION_CONQUER_CITY:
6249 case ACTION_CONQUER_CITY3:
6250 case ACTION_CONQUER_CITY4:
6251 /* TRANS: _Conquer City (100% chance of success). */
6252 return N_("%sConquer City%s");
6253 case ACTION_CONQUER_CITY2:
6254 /* TRANS: _Conquer City 2 (100% chance of success). */
6255 return N_("%sConquer City 2%s");
6256 case ACTION_CONQUER_EXTRAS:
6257 case ACTION_CONQUER_EXTRAS3:
6258 case ACTION_CONQUER_EXTRAS4:
6259 /* TRANS: _Conquer Extras (100% chance of success). */
6260 return N_("%sConquer Extras%s");
6261 case ACTION_CONQUER_EXTRAS2:
6262 /* TRANS: _Conquer Extras 2 (100% chance of success). */
6263 return N_("%sConquer Extras 2%s");
6264 case ACTION_HEAL_UNIT:
6265 case ACTION_HEAL_UNIT2:
6266 /* TRANS: Heal _Unit (3% chance of success). */
6267 return N_("Heal %sUnit%s");
6268 case ACTION_TRANSFORM_TERRAIN:
6269 case ACTION_TRANSFORM_TERRAIN2:
6270 /* TRANS: _Transform Terrain (3% chance of success). */
6271 return N_("%sTransform Terrain%s");
6272 case ACTION_CULTIVATE:
6273 case ACTION_CULTIVATE2:
6274 /* TRANS: Transform by _Cultivating (3% chance of success). */
6275 return N_("Transform by %sCultivating%s");
6276 case ACTION_PLANT:
6277 case ACTION_PLANT2:
6278 /* TRANS: Transform by _Planting (3% chance of success). */
6279 return N_("Transform by %sPlanting%s");
6280 case ACTION_PILLAGE:
6281 case ACTION_PILLAGE2:
6282 /* TRANS: Pilla_ge (100% chance of success). */
6283 return N_("Pilla%sge%s");
6284 case ACTION_CLEAN:
6285 case ACTION_CLEAN2:
6286 /* TRANS: Clean (100% chance of success). */
6287 return N_("%sClean%s");
6288 case ACTION_FORTIFY:
6289 case ACTION_FORTIFY2:
6290 /* TRANS: _Fortify (100% chance of success). */
6291 return N_("%sFortify%s");
6292 case ACTION_ROAD:
6293 case ACTION_ROAD2:
6294 /* TRANS: Build _Road (100% chance of success). */
6295 return N_("Build %sRoad%s");
6296 case ACTION_CONVERT:
6297 /* TRANS: _Convert Unit (100% chance of success). */
6298 return N_("%sConvert Unit%s");
6299 case ACTION_BASE:
6300 case ACTION_BASE2:
6301 /* TRANS: _Build Base (100% chance of success). */
6302 return N_("%sBuild Base%s");
6303 case ACTION_MINE:
6304 case ACTION_MINE2:
6305 /* TRANS: Build _Mine (100% chance of success). */
6306 return N_("Build %sMine%s");
6307 case ACTION_IRRIGATE:
6308 case ACTION_IRRIGATE2:
6309 /* TRANS: Build _Irrigation (100% chance of success). */
6310 return N_("Build %sIrrigation%s");
6311 case ACTION_TRANSPORT_DEBOARD:
6312 /* TRANS: _Deboard (100% chance of success). */
6313 return N_("%sDeboard%s");
6314 case ACTION_TRANSPORT_BOARD:
6315 case ACTION_TRANSPORT_BOARD2:
6316 case ACTION_TRANSPORT_BOARD3:
6317 /* TRANS: _Board (100% chance of success). */
6318 return N_("%sBoard%s");
6319 case ACTION_TRANSPORT_EMBARK:
6320 case ACTION_TRANSPORT_EMBARK2:
6321 case ACTION_TRANSPORT_EMBARK3:
6322 case ACTION_TRANSPORT_EMBARK4:
6323 /* TRANS: _Embark (100% chance of success). */
6324 return N_("%sEmbark%s");
6325 case ACTION_TRANSPORT_UNLOAD:
6326 /* TRANS: _Unload (100% chance of success). */
6327 return N_("%sUnload%s");
6328 case ACTION_TRANSPORT_LOAD:
6329 case ACTION_TRANSPORT_LOAD2:
6330 case ACTION_TRANSPORT_LOAD3:
6331 /* TRANS: _Load (100% chance of success). */
6332 return N_("%sLoad%s");
6333 case ACTION_TRANSPORT_DISEMBARK1:
6334 case ACTION_TRANSPORT_DISEMBARK3:
6335 case ACTION_TRANSPORT_DISEMBARK4:
6336 /* TRANS: _Disembark (100% chance of success). */
6337 return N_("%sDisembark%s");
6338 case ACTION_TRANSPORT_DISEMBARK2:
6339 /* TRANS: _Disembark 2 (100% chance of success). */
6340 return N_("%sDisembark 2%s");
6341 case ACTION_SPY_ATTACK:
6342 /* TRANS: _Eliminate Diplomat (100% chance of success). */
6343 return N_("%sEliminate Diplomat%s");
6344 case ACTION_HUT_ENTER:
6345 case ACTION_HUT_ENTER2:
6346 case ACTION_HUT_ENTER3:
6347 case ACTION_HUT_ENTER4:
6348 /* TRANS: Enter _Hut (100% chance of success). */
6349 return N_("Enter %sHut%s");
6350 case ACTION_HUT_FRIGHTEN:
6351 case ACTION_HUT_FRIGHTEN2:
6352 case ACTION_HUT_FRIGHTEN3:
6353 case ACTION_HUT_FRIGHTEN4:
6354 /* TRANS: Frighten _Hut (100% chance of success). */
6355 return N_("Frighten %sHut%s");
6356 case ACTION_UNIT_MOVE:
6357 case ACTION_UNIT_MOVE2:
6358 case ACTION_UNIT_MOVE3:
6359 /* TRANS: Regular _Move (100% chance of success). */
6360 return N_("Regular %sMove%s");
6361 case ACTION_TELEPORT:
6362 case ACTION_TELEPORT2:
6363 case ACTION_TELEPORT3:
6364 /* TRANS: _Teleport (100% chance of success). */
6365 return N_("%sTeleport%s");
6366 case ACTION_TELEPORT_CONQUER:
6367 /* TRANS: _Teleport (100% chance of success). */
6368 return N_("%sTeleport%s");
6369 case ACTION_TELEPORT_FRIGHTEN:
6370 /* TRANS: _Teleport (100% chance of success). */
6371 return N_("%sTeleport%s");
6372 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6373 /* TRANS: _Teleport (100% chance of success). */
6374 return N_("%sTeleport%s");
6375 case ACTION_TELEPORT_ENTER:
6376 /* TRANS: _Teleport (100% chance of success). */
6377 return N_("%sTeleport%s");
6378 case ACTION_TELEPORT_ENTER_CONQUER:
6379 /* TRANS: _Teleport (100% chance of success). */
6380 return N_("%sTeleport%s");
6381 case ACTION_SPY_ESCAPE:
6382 /* TRANS: _Escape To Nearest City (100% chance of success). */
6383 return N_("%sEscape To Nearest City%s");
6384 case ACTION_USER_ACTION1:
6385 /* TRANS: _User Action 1 (100% chance of success). */
6386 return N_("%sUser Action 1%s");
6387 case ACTION_USER_ACTION2:
6388 /* TRANS: _User Action 2 (100% chance of success). */
6389 return N_("%sUser Action 2%s");
6390 case ACTION_USER_ACTION3:
6391 /* TRANS: _User Action 3 (100% chance of success). */
6392 return N_("%sUser Action 3%s");
6393 case ACTION_USER_ACTION4:
6394 /* TRANS: _User Action 4 (100% chance of success). */
6395 return N_("%sUser Action 4%s");
6396 case ACTION_GAIN_VETERANCY:
6397 return N_("%sGain Veterancy%s");
6398 case ACTION_ESCAPE:
6399 return N_("%sEscape%s");
6400 case ACTION_COUNT:
6401 fc_assert(act != ACTION_COUNT);
6402 break;
6403 }
6404
6405 return NULL;
6406}
6407
6408/**********************************************************************/
6414 const char *action_min_range_ruleset_var_name(int act)
6415{
6416 switch ((enum gen_action)act) {
6417 case ACTION_SPY_POISON:
6418 case ACTION_SPY_POISON_ESC:
6419 case ACTION_SPY_SABOTAGE_UNIT:
6420 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6421 case ACTION_SPY_BRIBE_UNIT:
6422 case ACTION_SPY_SABOTAGE_CITY:
6423 case ACTION_SPY_SABOTAGE_CITY_ESC:
6424 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6425 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6426 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6427 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6428 case ACTION_SPY_INCITE_CITY:
6429 case ACTION_SPY_INCITE_CITY_ESC:
6430 case ACTION_ESTABLISH_EMBASSY:
6431 case ACTION_ESTABLISH_EMBASSY_STAY:
6432 case ACTION_SPY_STEAL_TECH:
6433 case ACTION_SPY_STEAL_TECH_ESC:
6434 case ACTION_SPY_TARGETED_STEAL_TECH:
6435 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6436 case ACTION_SPY_INVESTIGATE_CITY:
6437 case ACTION_INV_CITY_SPEND:
6438 case ACTION_SPY_STEAL_GOLD:
6439 case ACTION_SPY_STEAL_GOLD_ESC:
6440 case ACTION_SPY_SPREAD_PLAGUE:
6441 case ACTION_STEAL_MAPS:
6442 case ACTION_STEAL_MAPS_ESC:
6443 case ACTION_TRADE_ROUTE:
6444 case ACTION_MARKETPLACE:
6445 case ACTION_HELP_WONDER:
6446 case ACTION_CAPTURE_UNITS:
6447 case ACTION_EXPEL_UNIT:
6448 case ACTION_FOUND_CITY:
6449 case ACTION_JOIN_CITY:
6450 case ACTION_SPY_NUKE:
6451 case ACTION_SPY_NUKE_ESC:
6452 case ACTION_DESTROY_CITY:
6453 case ACTION_DISBAND_UNIT_RECOVER:
6454 case ACTION_DISBAND_UNIT:
6455 case ACTION_HOME_CITY:
6456 case ACTION_HOMELESS:
6457 case ACTION_UPGRADE_UNIT:
6458 case ACTION_PARADROP:
6459 case ACTION_PARADROP_CONQUER:
6460 case ACTION_PARADROP_FRIGHTEN:
6461 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6462 case ACTION_PARADROP_ENTER:
6463 case ACTION_PARADROP_ENTER_CONQUER:
6464 case ACTION_AIRLIFT:
6465 case ACTION_ATTACK:
6466 case ACTION_ATTACK2:
6467 case ACTION_SUICIDE_ATTACK:
6468 case ACTION_SUICIDE_ATTACK2:
6469 case ACTION_WIPE_UNITS:
6470 case ACTION_COLLECT_RANSOM:
6471 case ACTION_STRIKE_BUILDING:
6472 case ACTION_STRIKE_PRODUCTION:
6473 case ACTION_CONQUER_CITY:
6474 case ACTION_CONQUER_CITY2:
6475 case ACTION_CONQUER_CITY3:
6476 case ACTION_CONQUER_CITY4:
6477 case ACTION_HEAL_UNIT:
6478 case ACTION_HEAL_UNIT2:
6479 case ACTION_TRANSFORM_TERRAIN:
6480 case ACTION_TRANSFORM_TERRAIN2:
6481 case ACTION_CULTIVATE:
6482 case ACTION_CULTIVATE2:
6483 case ACTION_PLANT:
6484 case ACTION_PLANT2:
6485 case ACTION_PILLAGE:
6486 case ACTION_PILLAGE2:
6487 case ACTION_CLEAN:
6488 case ACTION_CLEAN2:
6489 case ACTION_FORTIFY:
6490 case ACTION_FORTIFY2:
6491 case ACTION_ROAD:
6492 case ACTION_ROAD2:
6493 case ACTION_CONVERT:
6494 case ACTION_BASE:
6495 case ACTION_BASE2:
6496 case ACTION_MINE:
6497 case ACTION_MINE2:
6498 case ACTION_IRRIGATE:
6499 case ACTION_IRRIGATE2:
6500 case ACTION_TRANSPORT_DEBOARD:
6501 case ACTION_TRANSPORT_BOARD:
6502 case ACTION_TRANSPORT_BOARD2:
6503 case ACTION_TRANSPORT_BOARD3:
6504 case ACTION_TRANSPORT_EMBARK:
6505 case ACTION_TRANSPORT_EMBARK2:
6506 case ACTION_TRANSPORT_EMBARK3:
6507 case ACTION_TRANSPORT_EMBARK4:
6508 case ACTION_TRANSPORT_UNLOAD:
6509 case ACTION_TRANSPORT_LOAD:
6510 case ACTION_TRANSPORT_LOAD2:
6511 case ACTION_TRANSPORT_LOAD3:
6512 case ACTION_TRANSPORT_DISEMBARK1:
6513 case ACTION_TRANSPORT_DISEMBARK2:
6514 case ACTION_TRANSPORT_DISEMBARK3:
6515 case ACTION_TRANSPORT_DISEMBARK4:
6516 case ACTION_BOMBARD:
6517 case ACTION_BOMBARD2:
6518 case ACTION_BOMBARD3:
6519 case ACTION_BOMBARD4:
6520 case ACTION_BOMBARD_LETHAL:
6521 case ACTION_BOMBARD_LETHAL2:
6522 case ACTION_SPY_ATTACK:
6523 case ACTION_CONQUER_EXTRAS:
6524 case ACTION_CONQUER_EXTRAS2:
6525 case ACTION_CONQUER_EXTRAS3:
6526 case ACTION_CONQUER_EXTRAS4:
6527 case ACTION_HUT_ENTER:
6528 case ACTION_HUT_ENTER2:
6529 case ACTION_HUT_ENTER3:
6530 case ACTION_HUT_ENTER4:
6531 case ACTION_HUT_FRIGHTEN:
6532 case ACTION_HUT_FRIGHTEN2:
6533 case ACTION_HUT_FRIGHTEN4:
6534 case ACTION_HUT_FRIGHTEN3:
6535 case ACTION_UNIT_MOVE:
6536 case ACTION_UNIT_MOVE2:
6537 case ACTION_UNIT_MOVE3:
6538 case ACTION_SPY_ESCAPE:
6539 case ACTION_GAIN_VETERANCY:
6540 case ACTION_ESCAPE:
6541 /* Min range is not ruleset changeable */
6542 return NULL;
6543 case ACTION_NUKE:
6544 return "explode_nuclear_min_range";
6545 case ACTION_NUKE_CITY:
6546 return "nuke_city_min_range";
6547 case ACTION_NUKE_UNITS:
6548 return "nuke_units_min_range";
6549 case ACTION_TELEPORT:
6550 return "teleport_min_range";
6551 case ACTION_TELEPORT2:
6552 return "teleport_2_min_range";
6553 case ACTION_TELEPORT3:
6554 return "teleport_3_min_range";
6555 case ACTION_TELEPORT_CONQUER:
6556 return "teleport_conquer_min_range";
6557 case ACTION_TELEPORT_FRIGHTEN:
6558 return "teleport_frighten_min_range";
6559 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6560 return "teleport_frighten_conquer_min_range";
6561 case ACTION_TELEPORT_ENTER:
6562 return "teleport_enter_min_range";
6563 case ACTION_TELEPORT_ENTER_CONQUER:
6564 return "teleport_enter_conquer_min_range";
6565 case ACTION_USER_ACTION1:
6566 return "user_action_1_min_range";
6567 case ACTION_USER_ACTION2:
6568 return "user_action_2_min_range";
6569 case ACTION_USER_ACTION3:
6570 return "user_action_3_min_range";
6571 case ACTION_USER_ACTION4:
6572 return "user_action_4_min_range";
6573 case ACTION_COUNT:
6574 break;
6575
6576 ASSERT_UNUSED_ACTION_CASES;
6577 }
6578
6579 fc_assert(act >= 0 && act < ACTION_COUNT);
6580
6581 return NULL;
6582}
6583
6584/**********************************************************************/
6590 const char *action_max_range_ruleset_var_name(int act)
6591{
6592 switch ((enum gen_action)act) {
6593 case ACTION_SPY_POISON:
6594 case ACTION_SPY_POISON_ESC:
6595 case ACTION_SPY_SABOTAGE_UNIT:
6596 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6597 case ACTION_SPY_BRIBE_UNIT:
6598 case ACTION_SPY_SABOTAGE_CITY:
6599 case ACTION_SPY_SABOTAGE_CITY_ESC:
6600 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6601 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6602 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6603 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6604 case ACTION_SPY_INCITE_CITY:
6605 case ACTION_SPY_INCITE_CITY_ESC:
6606 case ACTION_ESTABLISH_EMBASSY:
6607 case ACTION_ESTABLISH_EMBASSY_STAY:
6608 case ACTION_SPY_STEAL_TECH:
6609 case ACTION_SPY_STEAL_TECH_ESC:
6610 case ACTION_SPY_TARGETED_STEAL_TECH:
6611 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6612 case ACTION_SPY_INVESTIGATE_CITY:
6613 case ACTION_INV_CITY_SPEND:
6614 case ACTION_SPY_STEAL_GOLD:
6615 case ACTION_SPY_STEAL_GOLD_ESC:
6616 case ACTION_SPY_SPREAD_PLAGUE:
6617 case ACTION_STEAL_MAPS:
6618 case ACTION_STEAL_MAPS_ESC:
6619 case ACTION_TRADE_ROUTE:
6620 case ACTION_MARKETPLACE:
6621 case ACTION_CAPTURE_UNITS:
6622 case ACTION_EXPEL_UNIT:
6623 case ACTION_FOUND_CITY:
6624 case ACTION_JOIN_CITY:
6625 case ACTION_SPY_NUKE:
6626 case ACTION_SPY_NUKE_ESC:
6627 case ACTION_DESTROY_CITY:
6628 case ACTION_DISBAND_UNIT:
6629 case ACTION_HOME_CITY:
6630 case ACTION_HOMELESS:
6631 case ACTION_UPGRADE_UNIT:
6632 case ACTION_PARADROP:
6633 case ACTION_PARADROP_CONQUER:
6634 case ACTION_PARADROP_FRIGHTEN:
6635 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6636 case ACTION_PARADROP_ENTER:
6637 case ACTION_PARADROP_ENTER_CONQUER:
6638 case ACTION_ATTACK:
6639 case ACTION_ATTACK2:
6640 case ACTION_SUICIDE_ATTACK:
6641 case ACTION_SUICIDE_ATTACK2:
6642 case ACTION_WIPE_UNITS:
6643 case ACTION_COLLECT_RANSOM:
6644 case ACTION_STRIKE_BUILDING:
6645 case ACTION_STRIKE_PRODUCTION:
6646 case ACTION_CONQUER_CITY:
6647 case ACTION_CONQUER_CITY2:
6648 case ACTION_CONQUER_CITY3:
6649 case ACTION_CONQUER_CITY4:
6650 case ACTION_HEAL_UNIT:
6651 case ACTION_HEAL_UNIT2:
6652 case ACTION_TRANSFORM_TERRAIN:
6653 case ACTION_TRANSFORM_TERRAIN2:
6654 case ACTION_CULTIVATE:
6655 case ACTION_CULTIVATE2:
6656 case ACTION_PLANT:
6657 case ACTION_PLANT2:
6658 case ACTION_PILLAGE:
6659 case ACTION_PILLAGE2:
6660 case ACTION_CLEAN:
6661 case ACTION_CLEAN2:
6662 case ACTION_FORTIFY:
6663 case ACTION_FORTIFY2:
6664 case ACTION_ROAD:
6665 case ACTION_ROAD2:
6666 case ACTION_CONVERT:
6667 case ACTION_BASE:
6668 case ACTION_BASE2:
6669 case ACTION_MINE:
6670 case ACTION_MINE2:
6671 case ACTION_IRRIGATE:
6672 case ACTION_IRRIGATE2:
6673 case ACTION_TRANSPORT_DEBOARD:
6674 case ACTION_TRANSPORT_BOARD:
6675 case ACTION_TRANSPORT_BOARD2:
6676 case ACTION_TRANSPORT_BOARD3:
6677 case ACTION_TRANSPORT_EMBARK:
6678 case ACTION_TRANSPORT_EMBARK2:
6679 case ACTION_TRANSPORT_EMBARK3:
6680 case ACTION_TRANSPORT_EMBARK4:
6681 case ACTION_TRANSPORT_UNLOAD:
6682 case ACTION_TRANSPORT_LOAD:
6683 case ACTION_TRANSPORT_LOAD2:
6684 case ACTION_TRANSPORT_LOAD3:
6685 case ACTION_TRANSPORT_DISEMBARK1:
6686 case ACTION_TRANSPORT_DISEMBARK2:
6687 case ACTION_TRANSPORT_DISEMBARK3:
6688 case ACTION_TRANSPORT_DISEMBARK4:
6689 case ACTION_SPY_ATTACK:
6690 case ACTION_CONQUER_EXTRAS:
6691 case ACTION_CONQUER_EXTRAS2:
6692 case ACTION_CONQUER_EXTRAS3:
6693 case ACTION_CONQUER_EXTRAS4:
6694 case ACTION_HUT_ENTER:
6695 case ACTION_HUT_ENTER2:
6696 case ACTION_HUT_ENTER3:
6697 case ACTION_HUT_ENTER4:
6698 case ACTION_HUT_FRIGHTEN:
6699 case ACTION_HUT_FRIGHTEN2:
6700 case ACTION_HUT_FRIGHTEN3:
6701 case ACTION_HUT_FRIGHTEN4:
6702 case ACTION_UNIT_MOVE:
6703 case ACTION_UNIT_MOVE2:
6704 case ACTION_UNIT_MOVE3:
6705 case ACTION_SPY_ESCAPE:
6706 case ACTION_GAIN_VETERANCY:
6707 case ACTION_ESCAPE:
6708 /* Max range is not ruleset changeable */
6709 return NULL;
6710 case ACTION_HELP_WONDER:
6711 return "help_wonder_max_range";
6712 case ACTION_DISBAND_UNIT_RECOVER:
6713 return "disband_unit_recover_max_range";
6714 case ACTION_BOMBARD:
6715 return "bombard_max_range";
6716 case ACTION_BOMBARD2:
6717 return "bombard_2_max_range";
6718 case ACTION_BOMBARD3:
6719 return "bombard_3_max_range";
6720 case ACTION_BOMBARD4:
6721 return "bombard_4_max_range";
6722 case ACTION_BOMBARD_LETHAL:
6723 return "bombard_lethal_max_range";
6724 case ACTION_BOMBARD_LETHAL2:
6725 return "bombard_lethal_2_max_range";
6726 case ACTION_NUKE:
6727 return "explode_nuclear_max_range";
6728 case ACTION_NUKE_CITY:
6729 return "nuke_city_max_range";
6730 case ACTION_NUKE_UNITS:
6731 return "nuke_units_max_range";
6732 case ACTION_AIRLIFT:
6733 return "airlift_max_range";
6734 case ACTION_TELEPORT:
6735 return "teleport_max_range";
6736 case ACTION_TELEPORT2:
6737 return "teleport_2_max_range";
6738 case ACTION_TELEPORT3:
6739 return "teleport_3_max_range";
6740 case ACTION_TELEPORT_CONQUER:
6741 return "teleport_conquer_max_range";
6742 case ACTION_TELEPORT_FRIGHTEN:
6743 return "teleport_frighten_max_range";
6744 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6745 return "teleport_frighten_conquer_max_range";
6746 case ACTION_TELEPORT_ENTER:
6747 return "teleport_enter_max_range";
6748 case ACTION_TELEPORT_ENTER_CONQUER:
6749 return "teleport_enter_conquer_max_range";
6750 case ACTION_USER_ACTION1:
6751 return "user_action_1_max_range";
6752 case ACTION_USER_ACTION2:
6753 return "user_action_2_max_range";
6754 case ACTION_USER_ACTION3:
6755 return "user_action_3_max_range";
6756 case ACTION_USER_ACTION4:
6757 return "user_action_4_max_range";
6758 case ACTION_COUNT:
6759 break;
6760
6761 ASSERT_UNUSED_ACTION_CASES;
6762 }
6763
6764 fc_assert(act >= 0 && act < ACTION_COUNT);
6765
6766 return NULL;
6767}
6768
6769/**********************************************************************/
6775 const char *action_target_kind_ruleset_var_name(int act)
6776{
6777 switch ((enum gen_action)act) {
6778 case ACTION_SPY_POISON:
6779 case ACTION_SPY_POISON_ESC:
6780 case ACTION_SPY_SABOTAGE_UNIT:
6781 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6782 case ACTION_SPY_BRIBE_UNIT:
6783 case ACTION_SPY_SABOTAGE_CITY:
6784 case ACTION_SPY_SABOTAGE_CITY_ESC:
6785 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6786 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6787 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6788 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6789 case ACTION_SPY_INCITE_CITY:
6790 case ACTION_SPY_INCITE_CITY_ESC:
6791 case ACTION_ESTABLISH_EMBASSY:
6792 case ACTION_ESTABLISH_EMBASSY_STAY:
6793 case ACTION_SPY_STEAL_TECH:
6794 case ACTION_SPY_STEAL_TECH_ESC:
6795 case ACTION_SPY_TARGETED_STEAL_TECH:
6796 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6797 case ACTION_SPY_INVESTIGATE_CITY:
6798 case ACTION_INV_CITY_SPEND:
6799 case ACTION_SPY_STEAL_GOLD:
6800 case ACTION_SPY_STEAL_GOLD_ESC:
6801 case ACTION_SPY_SPREAD_PLAGUE:
6802 case ACTION_STEAL_MAPS:
6803 case ACTION_STEAL_MAPS_ESC:
6804 case ACTION_TRADE_ROUTE:
6805 case ACTION_MARKETPLACE:
6806 case ACTION_HELP_WONDER:
6807 case ACTION_CAPTURE_UNITS:
6808 case ACTION_EXPEL_UNIT:
6809 case ACTION_FOUND_CITY:
6810 case ACTION_JOIN_CITY:
6811 case ACTION_SPY_NUKE:
6812 case ACTION_SPY_NUKE_ESC:
6813 case ACTION_NUKE_UNITS:
6814 case ACTION_DESTROY_CITY:
6815 case ACTION_DISBAND_UNIT_RECOVER:
6816 case ACTION_DISBAND_UNIT:
6817 case ACTION_HOME_CITY:
6818 case ACTION_HOMELESS:
6819 case ACTION_UPGRADE_UNIT:
6820 case ACTION_PARADROP:
6821 case ACTION_PARADROP_CONQUER:
6822 case ACTION_PARADROP_FRIGHTEN:
6823 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6824 case ACTION_PARADROP_ENTER:
6825 case ACTION_PARADROP_ENTER_CONQUER:
6826 case ACTION_AIRLIFT:
6827 case ACTION_ATTACK:
6828 case ACTION_ATTACK2:
6829 case ACTION_SUICIDE_ATTACK:
6830 case ACTION_SUICIDE_ATTACK2:
6831 case ACTION_WIPE_UNITS:
6832 case ACTION_COLLECT_RANSOM:
6833 case ACTION_STRIKE_BUILDING:
6834 case ACTION_STRIKE_PRODUCTION:
6835 case ACTION_CONQUER_CITY:
6836 case ACTION_CONQUER_CITY2:
6837 case ACTION_CONQUER_CITY3:
6838 case ACTION_CONQUER_CITY4:
6839 case ACTION_HEAL_UNIT:
6840 case ACTION_HEAL_UNIT2:
6841 case ACTION_TRANSFORM_TERRAIN:
6842 case ACTION_TRANSFORM_TERRAIN2:
6843 case ACTION_CULTIVATE:
6844 case ACTION_CULTIVATE2:
6845 case ACTION_PLANT:
6846 case ACTION_PLANT2:
6847 case ACTION_CLEAN:
6848 case ACTION_CLEAN2:
6849 case ACTION_FORTIFY:
6850 case ACTION_FORTIFY2:
6851 case ACTION_ROAD:
6852 case ACTION_ROAD2:
6853 case ACTION_CONVERT:
6854 case ACTION_BASE:
6855 case ACTION_BASE2:
6856 case ACTION_MINE:
6857 case ACTION_MINE2:
6858 case ACTION_IRRIGATE:
6859 case ACTION_IRRIGATE2:
6860 case ACTION_TRANSPORT_DEBOARD:
6861 case ACTION_TRANSPORT_BOARD:
6862 case ACTION_TRANSPORT_BOARD2:
6863 case ACTION_TRANSPORT_BOARD3:
6864 case ACTION_TRANSPORT_EMBARK:
6865 case ACTION_TRANSPORT_EMBARK2:
6866 case ACTION_TRANSPORT_EMBARK3:
6867 case ACTION_TRANSPORT_EMBARK4:
6868 case ACTION_TRANSPORT_UNLOAD:
6869 case ACTION_TRANSPORT_LOAD:
6870 case ACTION_TRANSPORT_LOAD2:
6871 case ACTION_TRANSPORT_LOAD3:
6872 case ACTION_TRANSPORT_DISEMBARK1:
6873 case ACTION_TRANSPORT_DISEMBARK2:
6874 case ACTION_TRANSPORT_DISEMBARK3:
6875 case ACTION_TRANSPORT_DISEMBARK4:
6876 case ACTION_BOMBARD:
6877 case ACTION_BOMBARD2:
6878 case ACTION_BOMBARD3:
6879 case ACTION_BOMBARD4:
6880 case ACTION_BOMBARD_LETHAL:
6881 case ACTION_BOMBARD_LETHAL2:
6882 case ACTION_SPY_ATTACK:
6883 case ACTION_CONQUER_EXTRAS:
6884 case ACTION_CONQUER_EXTRAS2:
6885 case ACTION_CONQUER_EXTRAS3:
6886 case ACTION_CONQUER_EXTRAS4:
6887 case ACTION_HUT_ENTER:
6888 case ACTION_HUT_ENTER2:
6889 case ACTION_HUT_ENTER3:
6890 case ACTION_HUT_ENTER4:
6891 case ACTION_HUT_FRIGHTEN:
6892 case ACTION_HUT_FRIGHTEN2:
6893 case ACTION_HUT_FRIGHTEN3:
6894 case ACTION_HUT_FRIGHTEN4:
6895 case ACTION_UNIT_MOVE:
6896 case ACTION_UNIT_MOVE2:
6897 case ACTION_UNIT_MOVE3:
6898 case ACTION_TELEPORT:
6899 case ACTION_TELEPORT2:
6900 case ACTION_TELEPORT3:
6901 case ACTION_TELEPORT_CONQUER:
6902 case ACTION_TELEPORT_FRIGHTEN:
6903 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
6904 case ACTION_TELEPORT_ENTER:
6905 case ACTION_TELEPORT_ENTER_CONQUER:
6906 case ACTION_SPY_ESCAPE:
6907 case ACTION_GAIN_VETERANCY:
6908 case ACTION_ESCAPE:
6909 /* Target kind is not ruleset changeable */
6910 return NULL;
6911 case ACTION_NUKE:
6912 return "explode_nuclear_target_kind";
6913 case ACTION_NUKE_CITY:
6914 return "nuke_city_target_kind";
6915 case ACTION_PILLAGE:
6916 return "pillage_target_kind";
6917 case ACTION_PILLAGE2:
6918 return "pillage_2_target_kind";
6919 case ACTION_USER_ACTION1:
6920 return "user_action_1_target_kind";
6921 case ACTION_USER_ACTION2:
6922 return "user_action_2_target_kind";
6923 case ACTION_USER_ACTION3:
6924 return "user_action_3_target_kind";
6925 case ACTION_USER_ACTION4:
6926 return "user_action_4_target_kind";
6927 case ACTION_COUNT:
6928 break;
6929
6930 ASSERT_UNUSED_ACTION_CASES;
6931 }
6932
6933 fc_assert(act >= 0 && act < ACTION_COUNT);
6934
6935 return NULL;
6936}
6937
6938/**********************************************************************/
6945 const char *action_actor_consuming_always_ruleset_var_name(action_id act)
6946{
6947 switch ((enum gen_action)act) {
6948 case ACTION_SPY_POISON:
6949 case ACTION_SPY_POISON_ESC:
6950 case ACTION_SPY_SABOTAGE_UNIT:
6951 case ACTION_SPY_SABOTAGE_UNIT_ESC:
6952 case ACTION_SPY_BRIBE_UNIT:
6953 case ACTION_SPY_SABOTAGE_CITY:
6954 case ACTION_SPY_SABOTAGE_CITY_ESC:
6955 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
6956 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
6957 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
6958 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
6959 case ACTION_SPY_INCITE_CITY:
6960 case ACTION_SPY_INCITE_CITY_ESC:
6961 case ACTION_ESTABLISH_EMBASSY:
6962 case ACTION_ESTABLISH_EMBASSY_STAY:
6963 case ACTION_SPY_STEAL_TECH:
6964 case ACTION_SPY_STEAL_TECH_ESC:
6965 case ACTION_SPY_TARGETED_STEAL_TECH:
6966 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
6967 case ACTION_SPY_INVESTIGATE_CITY:
6968 case ACTION_INV_CITY_SPEND:
6969 case ACTION_SPY_STEAL_GOLD:
6970 case ACTION_SPY_STEAL_GOLD_ESC:
6971 case ACTION_STEAL_MAPS:
6972 case ACTION_STEAL_MAPS_ESC:
6973 case ACTION_TRADE_ROUTE:
6974 case ACTION_MARKETPLACE:
6975 case ACTION_HELP_WONDER:
6976 case ACTION_CAPTURE_UNITS:
6977 case ACTION_EXPEL_UNIT:
6978 case ACTION_JOIN_CITY:
6979 case ACTION_SPY_NUKE:
6980 case ACTION_SPY_NUKE_ESC:
6981 case ACTION_DESTROY_CITY:
6982 case ACTION_DISBAND_UNIT_RECOVER:
6983 case ACTION_DISBAND_UNIT:
6984 case ACTION_HOME_CITY:
6985 case ACTION_HOMELESS:
6986 case ACTION_UPGRADE_UNIT:
6987 case ACTION_PARADROP:
6988 case ACTION_PARADROP_CONQUER:
6989 case ACTION_PARADROP_FRIGHTEN:
6990 case ACTION_PARADROP_FRIGHTEN_CONQUER:
6991 case ACTION_PARADROP_ENTER:
6992 case ACTION_PARADROP_ENTER_CONQUER:
6993 case ACTION_AIRLIFT:
6994 case ACTION_ATTACK:
6995 case ACTION_ATTACK2:
6996 case ACTION_SUICIDE_ATTACK:
6997 case ACTION_SUICIDE_ATTACK2:
6998 case ACTION_WIPE_UNITS:
6999 case ACTION_COLLECT_RANSOM:
7000 case ACTION_STRIKE_BUILDING:
7001 case ACTION_STRIKE_PRODUCTION:
7002 case ACTION_CONQUER_CITY:
7003 case ACTION_CONQUER_CITY2:
7004 case ACTION_CONQUER_CITY3:
7005 case ACTION_CONQUER_CITY4:
7006 case ACTION_HEAL_UNIT:
7007 case ACTION_HEAL_UNIT2:
7008 case ACTION_TRANSFORM_TERRAIN:
7009 case ACTION_TRANSFORM_TERRAIN2:
7010 case ACTION_CULTIVATE:
7011 case ACTION_CULTIVATE2:
7012 case ACTION_PLANT:
7013 case ACTION_PLANT2:
7014 case ACTION_PILLAGE:
7015 case ACTION_PILLAGE2:
7016 case ACTION_CLEAN:
7017 case ACTION_CLEAN2:
7018 case ACTION_FORTIFY:
7019 case ACTION_FORTIFY2:
7020 case ACTION_ROAD:
7021 case ACTION_ROAD2:
7022 case ACTION_CONVERT:
7023 case ACTION_BASE:
7024 case ACTION_BASE2:
7025 case ACTION_MINE:
7026 case ACTION_MINE2:
7027 case ACTION_IRRIGATE:
7028 case ACTION_IRRIGATE2:
7029 case ACTION_TRANSPORT_DEBOARD:
7030 case ACTION_TRANSPORT_BOARD:
7031 case ACTION_TRANSPORT_BOARD2:
7032 case ACTION_TRANSPORT_BOARD3:
7033 case ACTION_TRANSPORT_EMBARK:
7034 case ACTION_TRANSPORT_EMBARK2:
7035 case ACTION_TRANSPORT_EMBARK3:
7036 case ACTION_TRANSPORT_EMBARK4:
7037 case ACTION_TRANSPORT_UNLOAD:
7038 case ACTION_TRANSPORT_LOAD:
7039 case ACTION_TRANSPORT_LOAD2:
7040 case ACTION_TRANSPORT_LOAD3:
7041 case ACTION_TRANSPORT_DISEMBARK1:
7042 case ACTION_TRANSPORT_DISEMBARK2:
7043 case ACTION_TRANSPORT_DISEMBARK3:
7044 case ACTION_TRANSPORT_DISEMBARK4:
7045 case ACTION_BOMBARD:
7046 case ACTION_BOMBARD2:
7047 case ACTION_BOMBARD3:
7048 case ACTION_BOMBARD4:
7049 case ACTION_BOMBARD_LETHAL:
7050 case ACTION_BOMBARD_LETHAL2:
7051 case ACTION_SPY_ATTACK:
7052 case ACTION_CONQUER_EXTRAS:
7053 case ACTION_CONQUER_EXTRAS2:
7054 case ACTION_CONQUER_EXTRAS3:
7055 case ACTION_CONQUER_EXTRAS4:
7056 case ACTION_HUT_ENTER:
7057 case ACTION_HUT_ENTER2:
7058 case ACTION_HUT_ENTER3:
7059 case ACTION_HUT_ENTER4:
7060 case ACTION_HUT_FRIGHTEN:
7061 case ACTION_HUT_FRIGHTEN2:
7062 case ACTION_HUT_FRIGHTEN3:
7063 case ACTION_HUT_FRIGHTEN4:
7064 case ACTION_UNIT_MOVE:
7065 case ACTION_UNIT_MOVE2:
7066 case ACTION_UNIT_MOVE3:
7067 case ACTION_TELEPORT:
7068 case ACTION_TELEPORT2:
7069 case ACTION_TELEPORT3:
7070 case ACTION_TELEPORT_CONQUER:
7071 case ACTION_TELEPORT_FRIGHTEN:
7072 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7073 case ACTION_TELEPORT_ENTER:
7074 case ACTION_TELEPORT_ENTER_CONQUER:
7075 case ACTION_SPY_ESCAPE:
7076 case ACTION_GAIN_VETERANCY:
7077 case ACTION_ESCAPE:
7078 /* Actor consuming always is not ruleset changeable */
7079 return NULL;
7080 case ACTION_FOUND_CITY:
7081 return "found_city_consuming_always";
7082 case ACTION_NUKE:
7083 return "explode_nuclear_consuming_always";
7084 case ACTION_NUKE_CITY:
7085 return "nuke_city_consuming_always";
7086 case ACTION_NUKE_UNITS:
7087 return "nuke_units_consuming_always";
7088 case ACTION_SPY_SPREAD_PLAGUE:
7089 return "spread_plague_actor_consuming_always";
7090 case ACTION_USER_ACTION1:
7091 return "user_action_1_actor_consuming_always";
7092 case ACTION_USER_ACTION2:
7093 return "user_action_2_actor_consuming_always";
7094 case ACTION_USER_ACTION3:
7095 return "user_action_3_actor_consuming_always";
7096 case ACTION_USER_ACTION4:
7097 return "user_action_4_actor_consuming_always";
7098 case ACTION_COUNT:
7099 break;
7100
7101 ASSERT_UNUSED_ACTION_CASES;
7102 }
7103
7104 fc_assert(act >= 0 && act < ACTION_COUNT);
7105
7106 return NULL;
7107}
7108
7109/**********************************************************************/
7116 const char *action_blocked_by_ruleset_var_name(const struct action *act)
7117{
7118 fc_assert_ret_val(act != NULL, NULL);
7119
7120 switch ((enum gen_action)action_number(act)) {
7121 case ACTION_MARKETPLACE:
7122 return "enter_marketplace_blocked_by";
7123 case ACTION_BOMBARD:
7124 return "bombard_blocked_by";
7125 case ACTION_BOMBARD2:
7126 return "bombard_2_blocked_by";
7127 case ACTION_BOMBARD3:
7128 return "bombard_3_blocked_by";
7129 case ACTION_BOMBARD4:
7130 return "bombard_4_blocked_by";
7131 case ACTION_BOMBARD_LETHAL:
7132 return "bombard_lethal_blocked_by";
7133 case ACTION_BOMBARD_LETHAL2:
7134 return "bombard_lethal_2_blocked_by";
7135 case ACTION_NUKE:
7136 return "explode_nuclear_blocked_by";
7137 case ACTION_NUKE_CITY:
7138 return "nuke_city_blocked_by";
7139 case ACTION_NUKE_UNITS:
7140 return "nuke_units_blocked_by";
7141 case ACTION_ATTACK:
7142 return "attack_blocked_by";
7143 case ACTION_ATTACK2:
7144 return "attack_2_blocked_by";
7145 case ACTION_SUICIDE_ATTACK:
7146 return "suicide_attack_blocked_by";
7147 case ACTION_SUICIDE_ATTACK2:
7148 return "suicide_attack_2_blocked_by";
7149 case ACTION_WIPE_UNITS:
7150 return "wipe_units_blocked_by";
7151 case ACTION_COLLECT_RANSOM:
7152 return "collect_ransom_blocked_by";
7153 case ACTION_CONQUER_CITY:
7154 return "conquer_city_blocked_by";
7155 case ACTION_CONQUER_CITY2:
7156 return "conquer_city_2_blocked_by";
7157 case ACTION_CONQUER_CITY3:
7158 return "conquer_city_3_blocked_by";
7159 case ACTION_CONQUER_CITY4:
7160 return "conquer_city_4_blocked_by";
7161 case ACTION_UNIT_MOVE:
7162 return "move_blocked_by";
7163 case ACTION_UNIT_MOVE2:
7164 return "move_2_blocked_by";
7165 case ACTION_UNIT_MOVE3:
7166 return "move_3_blocked_by";
7167 case ACTION_TELEPORT:
7168 return "teleport_blocked_by";
7169 case ACTION_TELEPORT2:
7170 return "teleport_2_blocked_by";
7171 case ACTION_TELEPORT3:
7172 return "teleport_3_blocked_by";
7173 case ACTION_TELEPORT_CONQUER:
7174 return "teleport_conquer_blocked_by";
7175 case ACTION_TELEPORT_FRIGHTEN:
7176 return "teleport_frighten_blocked_by";
7177 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7178 return "teleport_frighten_conquer_blocked_by";
7179 case ACTION_TELEPORT_ENTER:
7180 return "teleport_enter_blocked_by";
7181 case ACTION_TELEPORT_ENTER_CONQUER:
7182 return "teleport_enter_conquer_blocked_by";
7183 case ACTION_SPY_ESCAPE:
7184 case ACTION_SPY_POISON:
7185 case ACTION_SPY_POISON_ESC:
7186 case ACTION_SPY_SABOTAGE_UNIT:
7187 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7188 case ACTION_SPY_BRIBE_UNIT:
7189 case ACTION_SPY_SABOTAGE_CITY:
7190 case ACTION_SPY_SABOTAGE_CITY_ESC:
7191 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7192 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7193 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7194 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7195 case ACTION_SPY_INCITE_CITY:
7196 case ACTION_SPY_INCITE_CITY_ESC:
7197 case ACTION_ESTABLISH_EMBASSY:
7198 case ACTION_ESTABLISH_EMBASSY_STAY:
7199 case ACTION_SPY_STEAL_TECH:
7200 case ACTION_SPY_STEAL_TECH_ESC:
7201 case ACTION_SPY_TARGETED_STEAL_TECH:
7202 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7203 case ACTION_SPY_INVESTIGATE_CITY:
7204 case ACTION_INV_CITY_SPEND:
7205 case ACTION_SPY_STEAL_GOLD:
7206 case ACTION_SPY_STEAL_GOLD_ESC:
7207 case ACTION_STEAL_MAPS:
7208 case ACTION_STEAL_MAPS_ESC:
7209 case ACTION_TRADE_ROUTE:
7210 case ACTION_HELP_WONDER:
7211 case ACTION_CAPTURE_UNITS:
7212 case ACTION_EXPEL_UNIT:
7213 case ACTION_FOUND_CITY:
7214 case ACTION_JOIN_CITY:
7215 case ACTION_SPY_NUKE:
7216 case ACTION_SPY_NUKE_ESC:
7217 case ACTION_DESTROY_CITY:
7218 case ACTION_DISBAND_UNIT_RECOVER:
7219 case ACTION_DISBAND_UNIT:
7220 case ACTION_HOME_CITY:
7221 case ACTION_HOMELESS:
7222 case ACTION_UPGRADE_UNIT:
7223 case ACTION_PARADROP:
7224 case ACTION_PARADROP_CONQUER:
7225 case ACTION_PARADROP_FRIGHTEN:
7226 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7227 case ACTION_PARADROP_ENTER:
7228 case ACTION_PARADROP_ENTER_CONQUER:
7229 case ACTION_AIRLIFT:
7230 case ACTION_STRIKE_BUILDING:
7231 case ACTION_STRIKE_PRODUCTION:
7232 case ACTION_HEAL_UNIT:
7233 case ACTION_HEAL_UNIT2:
7234 case ACTION_TRANSFORM_TERRAIN:
7235 case ACTION_TRANSFORM_TERRAIN2:
7236 case ACTION_CULTIVATE:
7237 case ACTION_CULTIVATE2:
7238 case ACTION_PLANT:
7239 case ACTION_PLANT2:
7240 case ACTION_PILLAGE:
7241 case ACTION_PILLAGE2:
7242 case ACTION_CLEAN:
7243 case ACTION_CLEAN2:
7244 case ACTION_FORTIFY:
7245 case ACTION_FORTIFY2:
7246 case ACTION_ROAD:
7247 case ACTION_ROAD2:
7248 case ACTION_CONVERT:
7249 case ACTION_BASE:
7250 case ACTION_BASE2:
7251 case ACTION_MINE:
7252 case ACTION_MINE2:
7253 case ACTION_IRRIGATE:
7254 case ACTION_IRRIGATE2:
7255 case ACTION_TRANSPORT_DEBOARD:
7256 case ACTION_TRANSPORT_BOARD:
7257 case ACTION_TRANSPORT_BOARD2:
7258 case ACTION_TRANSPORT_BOARD3:
7259 case ACTION_TRANSPORT_EMBARK:
7260 case ACTION_TRANSPORT_EMBARK2:
7261 case ACTION_TRANSPORT_EMBARK3:
7262 case ACTION_TRANSPORT_EMBARK4:
7263 case ACTION_TRANSPORT_UNLOAD:
7264 case ACTION_TRANSPORT_LOAD:
7265 case ACTION_TRANSPORT_LOAD2:
7266 case ACTION_TRANSPORT_LOAD3:
7267 case ACTION_TRANSPORT_DISEMBARK1:
7268 case ACTION_TRANSPORT_DISEMBARK2:
7269 case ACTION_TRANSPORT_DISEMBARK3:
7270 case ACTION_TRANSPORT_DISEMBARK4:
7271 case ACTION_SPY_SPREAD_PLAGUE:
7272 case ACTION_SPY_ATTACK:
7273 case ACTION_CONQUER_EXTRAS:
7274 case ACTION_CONQUER_EXTRAS2:
7275 case ACTION_CONQUER_EXTRAS3:
7276 case ACTION_CONQUER_EXTRAS4:
7277 case ACTION_HUT_ENTER:
7278 case ACTION_HUT_ENTER2:
7279 case ACTION_HUT_ENTER3:
7280 case ACTION_HUT_ENTER4:
7281 case ACTION_HUT_FRIGHTEN:
7282 case ACTION_HUT_FRIGHTEN2:
7283 case ACTION_HUT_FRIGHTEN3:
7284 case ACTION_HUT_FRIGHTEN4:
7285 case ACTION_GAIN_VETERANCY:
7286 case ACTION_ESCAPE:
7287 case ACTION_USER_ACTION1:
7288 case ACTION_USER_ACTION2:
7289 case ACTION_USER_ACTION3:
7290 case ACTION_USER_ACTION4:
7291 /* blocked_by is not ruleset changeable */
7292 return NULL;
7293 case ACTION_COUNT:
7294 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
7295 break;
7296
7297 ASSERT_UNUSED_ACTION_CASES;
7298 }
7299
7300 return NULL;
7301}
7302
7303/**********************************************************************/
7307const char *
7308action_post_success_forced_ruleset_var_name(const struct action *act)
7309{
7310 fc_assert_ret_val(act != NULL, NULL);
7311
7312 if (!(action_has_result(act, ACTRES_SPY_BRIBE_UNIT)
7313 || action_has_result(act, ACTRES_ATTACK)
7314 || action_has_result(act, ACTRES_WIPE_UNITS)
7315 || action_has_result(act, ACTRES_COLLECT_RANSOM))) {
7316 /* No support in the action performer function */
7317 return NULL;
7318 }
7319
7320 switch ((enum gen_action)action_number(act)) {
7321 case ACTION_SPY_BRIBE_UNIT:
7322 return "bribe_unit_post_success_forced_actions";
7323 case ACTION_ATTACK:
7324 return "attack_post_success_forced_actions";
7325 case ACTION_ATTACK2:
7326 return "attack_2_post_success_forced_actions";
7327 case ACTION_WIPE_UNITS:
7328 return "wipe_units_post_success_forced_actions";
7329 case ACTION_COLLECT_RANSOM:
7330 return "collect_ransom_post_success_forced_actions";
7331 case ACTION_MARKETPLACE:
7332 case ACTION_BOMBARD:
7333 case ACTION_BOMBARD2:
7334 case ACTION_BOMBARD3:
7335 case ACTION_BOMBARD4:
7336 case ACTION_BOMBARD_LETHAL:
7337 case ACTION_BOMBARD_LETHAL2:
7338 case ACTION_NUKE:
7339 case ACTION_NUKE_CITY:
7340 case ACTION_NUKE_UNITS:
7341 case ACTION_SUICIDE_ATTACK:
7342 case ACTION_SUICIDE_ATTACK2:
7343 case ACTION_CONQUER_CITY:
7344 case ACTION_CONQUER_CITY2:
7345 case ACTION_CONQUER_CITY3:
7346 case ACTION_CONQUER_CITY4:
7347 case ACTION_SPY_POISON:
7348 case ACTION_SPY_POISON_ESC:
7349 case ACTION_SPY_SABOTAGE_UNIT:
7350 case ACTION_SPY_SABOTAGE_UNIT_ESC:
7351 case ACTION_SPY_SABOTAGE_CITY:
7352 case ACTION_SPY_SABOTAGE_CITY_ESC:
7353 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
7354 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION:
7355 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
7356 case ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC:
7357 case ACTION_SPY_INCITE_CITY:
7358 case ACTION_SPY_INCITE_CITY_ESC:
7359 case ACTION_ESTABLISH_EMBASSY:
7360 case ACTION_ESTABLISH_EMBASSY_STAY:
7361 case ACTION_SPY_STEAL_TECH:
7362 case ACTION_SPY_STEAL_TECH_ESC:
7363 case ACTION_SPY_TARGETED_STEAL_TECH:
7364 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
7365 case ACTION_SPY_INVESTIGATE_CITY:
7366 case ACTION_INV_CITY_SPEND:
7367 case ACTION_SPY_STEAL_GOLD:
7368 case ACTION_SPY_STEAL_GOLD_ESC:
7369 case ACTION_STEAL_MAPS:
7370 case ACTION_STEAL_MAPS_ESC:
7371 case ACTION_TRADE_ROUTE:
7372 case ACTION_HELP_WONDER:
7373 case ACTION_CAPTURE_UNITS:
7374 case ACTION_EXPEL_UNIT:
7375 case ACTION_FOUND_CITY:
7376 case ACTION_JOIN_CITY:
7377 case ACTION_SPY_NUKE:
7378 case ACTION_SPY_NUKE_ESC:
7379 case ACTION_DESTROY_CITY:
7380 case ACTION_DISBAND_UNIT_RECOVER:
7381 case ACTION_DISBAND_UNIT:
7382 case ACTION_HOME_CITY:
7383 case ACTION_HOMELESS:
7384 case ACTION_UPGRADE_UNIT:
7385 case ACTION_PARADROP:
7386 case ACTION_PARADROP_CONQUER:
7387 case ACTION_PARADROP_FRIGHTEN:
7388 case ACTION_PARADROP_FRIGHTEN_CONQUER:
7389 case ACTION_PARADROP_ENTER:
7390 case ACTION_PARADROP_ENTER_CONQUER:
7391 case ACTION_AIRLIFT:
7392 case ACTION_STRIKE_BUILDING:
7393 case ACTION_STRIKE_PRODUCTION:
7394 case ACTION_HEAL_UNIT:
7395 case ACTION_HEAL_UNIT2:
7396 case ACTION_TRANSFORM_TERRAIN:
7397 case ACTION_TRANSFORM_TERRAIN2:
7398 case ACTION_CULTIVATE:
7399 case ACTION_CULTIVATE2:
7400 case ACTION_PLANT:
7401 case ACTION_PLANT2:
7402 case ACTION_PILLAGE:
7403 case ACTION_PILLAGE2:
7404 case ACTION_CLEAN:
7405 case ACTION_CLEAN2:
7406 case ACTION_FORTIFY:
7407 case ACTION_FORTIFY2:
7408 case ACTION_ROAD:
7409 case ACTION_ROAD2:
7410 case ACTION_CONVERT:
7411 case ACTION_BASE:
7412 case ACTION_BASE2:
7413 case ACTION_MINE:
7414 case ACTION_MINE2:
7415 case ACTION_IRRIGATE:
7416 case ACTION_IRRIGATE2:
7417 case ACTION_TRANSPORT_DEBOARD:
7418 case ACTION_TRANSPORT_BOARD:
7419 case ACTION_TRANSPORT_BOARD2:
7420 case ACTION_TRANSPORT_BOARD3:
7421 case ACTION_TRANSPORT_EMBARK:
7422 case ACTION_TRANSPORT_EMBARK2:
7423 case ACTION_TRANSPORT_EMBARK3:
7424 case ACTION_TRANSPORT_EMBARK4:
7425 case ACTION_TRANSPORT_UNLOAD:
7426 case ACTION_TRANSPORT_LOAD:
7427 case ACTION_TRANSPORT_LOAD2:
7428 case ACTION_TRANSPORT_LOAD3:
7429 case ACTION_TRANSPORT_DISEMBARK1:
7430 case ACTION_TRANSPORT_DISEMBARK2:
7431 case ACTION_TRANSPORT_DISEMBARK3:
7432 case ACTION_TRANSPORT_DISEMBARK4:
7433 case ACTION_SPY_SPREAD_PLAGUE:
7434 case ACTION_SPY_ATTACK:
7435 case ACTION_CONQUER_EXTRAS:
7436 case ACTION_CONQUER_EXTRAS2:
7437 case ACTION_CONQUER_EXTRAS3:
7438 case ACTION_CONQUER_EXTRAS4:
7439 case ACTION_HUT_ENTER:
7440 case ACTION_HUT_ENTER2:
7441 case ACTION_HUT_ENTER3:
7442 case ACTION_HUT_ENTER4:
7443 case ACTION_HUT_FRIGHTEN:
7444 case ACTION_HUT_FRIGHTEN2:
7445 case ACTION_HUT_FRIGHTEN3:
7446 case ACTION_HUT_FRIGHTEN4:
7447 case ACTION_UNIT_MOVE:
7448 case ACTION_UNIT_MOVE2:
7449 case ACTION_UNIT_MOVE3:
7450 case ACTION_TELEPORT:
7451 case ACTION_TELEPORT2:
7452 case ACTION_TELEPORT3:
7453 case ACTION_TELEPORT_CONQUER:
7454 case ACTION_TELEPORT_FRIGHTEN:
7455 case ACTION_TELEPORT_FRIGHTEN_CONQUER:
7456 case ACTION_TELEPORT_ENTER:
7457 case ACTION_TELEPORT_ENTER_CONQUER:
7458 case ACTION_SPY_ESCAPE:
7459 case ACTION_GAIN_VETERANCY:
7460 case ACTION_ESCAPE:
7461 case ACTION_USER_ACTION1:
7462 case ACTION_USER_ACTION2:
7463 case ACTION_USER_ACTION3:
7464 case ACTION_USER_ACTION4:
7465 /* Not ruleset changeable */
7466 return NULL;
7467 case ACTION_COUNT:
7468 fc_assert_ret_val(action_number(act) != ACTION_COUNT, NULL);
7469 break;
7470
7471 ASSERT_UNUSED_ACTION_CASES;
7472 }
7473
7474 return NULL;
7475}
7476
7477/**********************************************************************/
7481 bool action_ever_possible(action_id action)
7482{
7483 return action_enabler_list_size(action_enablers_for_action(action)) > 0;
7484}
7485
7486/**********************************************************************/
7489 const char *gen_action_name_update_cb(const char *old_name)
7490{
7491 /* Uncomment and fill implementation, if compat mode
7492 * action name conversions needed. */
7493#if 0
7494 if (is_ruleset_compat_mode()) {
7495 }
7496#endif
7497
7498 return old_name;
7499}
7500
7501 const char *atk_helpnames[ATK_COUNT] =
7502{
7503 N_("individual cities"), /* ATK_CITY */
7504 N_("individual units"), /* ATK_UNIT */
7505 N_("unit stacks"), /* ATK_UNITS */
7506 N_("tiles"), /* ATK_TILE */
7507 N_("tile extras"), /* ATK_EXTRAS */
7508 N_("itself") /* ATK_SELF */
7509};
7510
7511/**********************************************************************/
7515 const char *action_target_kind_help(enum action_target_kind kind)
7516{
7517 fc_assert(kind >= 0 && kind < ATK_COUNT);
7518
7519 return _(atk_helpnames[kind]);
7520}
7521
7522/************************************************************************/
7525 struct action_list *action_list_by_result(enum action_result result)
7526{
7527 fc_assert(result < ACTRES_LAST);
7528
7529 return actlist_by_result[result];
7530}
7531
7532/************************************************************************/
7535 struct action_list *action_list_by_activity(enum unit_activity activity)
7536{
7537 fc_assert(activity < ACTIVITY_LAST);
7538
7539 return actlist_by_activity[activity];
7540}
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:5444
actions
static struct action * actions[MAX_NUM_ACTIONS]
Definition actions.c:57
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:1287
action_distance_inside_max
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1148
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:2775
action_prob_explain
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:1398
action_mp_full_makes_legal
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:5522
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:3743
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:3390
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1073
action_prob_certain
bool action_prob_certain(const struct act_prob probability)
Definition actions.c:5054
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1225
action_auto_perf_slot_number
struct action_auto_perf * action_auto_perf_slot_number(const int num)
Definition actions.c:5675
action_enabler_vector_number
req_vec_num_in_item action_enabler_vector_number(const void *enabler, const struct requirement_vector *vec)
Definition actions.c:2022
action_has_complex_target
bool action_has_complex_target(const struct action *paction)
Definition actions.c:1107
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:2362
action_prob_self
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4717
action_enabler_suggest_repair
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:1892
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:3235
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5044
ACTPROB_VAL_NOT_IMPL
#define ACTPROB_VAL_NOT_IMPL
Definition actions.c:55
auto_perfs
struct action_auto_perf auto_perfs[MAX_NUM_ACTION_AUTO_PERFORMERS]
Definition actions.c:59
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:2569
action_prob_new_not_impl
struct act_prob action_prob_new_not_impl(void)
Definition actions.c:5023
action_enabler_suggest_improvement
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:1958
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:3470
actions_rs_pre_san_gen
void actions_rs_pre_san_gen(void)
Definition actions.c:879
action_min_range_ruleset_var_name
const char * action_min_range_ruleset_var_name(int act)
Definition actions.c:6414
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 req_context *other_context)
Definition actions.c:3517
action_blocked_by_ruleset_var_name
const char * action_blocked_by_ruleset_var_name(const struct action *act)
Definition actions.c:7116
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:2948
ACTPROB_VAL_MAX
#define ACTPROB_VAL_MAX
Definition actions.c:49
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:3791
action_enabler_suggest_repair_oblig
struct req_vec_problem * action_enabler_suggest_repair_oblig(const struct action_enabler *enabler)
Definition actions.c:1653
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:5740
action_name_translation
const char * action_name_translation(const struct action *paction)
Definition actions.c:1205
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:5344
action_array_end
void action_array_end(action_id *act_array, int size)
Definition actions.c:5723
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:3695
atk_helpnames
const char * atk_helpnames[ATK_COUNT]
Definition actions.c:7501
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:2589
hard_code_actions
static void hard_code_actions(void)
Definition actions.c:104
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:2987
action_is_in_use
bool action_is_in_use(struct action *paction)
Definition actions.c:5629
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:4739
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:1747
action_ever_possible
bool action_ever_possible(action_id action)
Definition actions.c:7481
action_enabler_vector_by_number_name
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:2069
are_action_probabilitys_equal
bool are_action_probabilitys_equal(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:5095
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:4664
action_post_success_forced_ruleset_var_name
const char * action_post_success_forced_ruleset_var_name(const struct action *act)
Definition actions.c:7308
action_by_rule_name
struct action * action_by_rule_name(const char *name)
Definition actions.c:1054
action_has_possible_actor_hard_reqs
static bool action_has_possible_actor_hard_reqs(struct action *paction)
Definition actions.c:5603
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1191
action_id_rule_name
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1214
action_get_sub_target_kind
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1094
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:2137
action_prob_not_relevant
static bool action_prob_not_relevant(const struct act_prob probability)
Definition actions.c:5065
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:3649
actions_free
void actions_free(void)
Definition actions.c:889
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:3312
action_enabler_free
void action_enabler_free(struct action_enabler *enabler)
Definition actions.c:1469
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:4562
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:3217
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:3536
actlist_by_result
static struct action_list * actlist_by_result[ACTRES_LAST]
Definition actions.c:97
action_list_by_activity
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7535
action_number
int action_number(const struct action *action)
Definition actions.c:1183
action_prob_new_unknown
struct act_prob action_prob_new_unknown(void)
Definition actions.c:5033
action_would_be_blocked_by
bool action_would_be_blocked_by(const struct action *blocked, const struct action *blocker)
Definition actions.c:1171
ACTPROB_VAL_NA
#define ACTPROB_VAL_NA
Definition actions.c:53
enabler_first_clarification
static struct req_vec_problem * enabler_first_clarification(const struct action_enabler *enabler)
Definition actions.c:1940
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:4965
action_prob_not_impl
static bool action_prob_not_impl(const struct act_prob probability)
Definition actions.c:5076
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:3293
action_prob_and
struct act_prob action_prob_and(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:5182
actions_initialized
static bool actions_initialized
Definition actions.c:60
action_actor_consuming_always_ruleset_var_name
const char * action_actor_consuming_always_ruleset_var_name(action_id act)
Definition actions.c:6945
action_immune_government
bool action_immune_government(struct government *gov, action_id act)
Definition actions.c:5400
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:5423
ap_dipl_battle_win
static struct act_prob ap_dipl_battle_win(const struct unit *pattacker, const struct unit *pdefender)
Definition actions.c:3572
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:4303
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:2249
action_prob_new_certain
struct act_prob action_prob_new_certain(void)
Definition actions.c:5003
action_max_range_ruleset_var_name
const char * action_max_range_ruleset_var_name(int act)
Definition actions.c:6590
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:4864
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:4116
action_is_internal
bool action_is_internal(struct action *paction)
Definition actions.c:5655
action_dice_roll_initial_odds
int action_dice_roll_initial_odds(const struct action *paction)
Definition actions.c:5320
action_prob_fall_back
struct act_prob action_prob_fall_back(const struct act_prob *ap1, const struct act_prob *ap2)
Definition actions.c:5252
tgt_city_local_utype
static const struct unit_type * tgt_city_local_utype(const struct city *target_city)
Definition actions.c:2112
req_vec_first_local_diplrel
static struct requirement * req_vec_first_local_diplrel(const struct requirement_vector *vec)
Definition actions.c:1703
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:4478
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:4496
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:4931
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:3052
action_list_by_result
struct action_list * action_list_by_result(enum action_result result)
Definition actions.c:7525
action_univs_not_blocking
bool action_univs_not_blocking(const struct action *paction, struct universal *actor_uni, struct universal *target_uni)
Definition actions.c:5699
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:1724
actions_are_ready
bool actions_are_ready(void)
Definition actions.c:931
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:3129
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:4796
action_prob_vs_city
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4203
action_target_kind_ruleset_var_name
const char * action_target_kind_ruleset_var_name(int act)
Definition actions.c:6775
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:4219
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:5467
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:2931
action_enablers_by_action
static struct action_enabler_list * action_enablers_by_action[MAX_NUM_ACTIONS]
Definition actions.c:62
action_enabler_add
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:1496
action_ui_name_default
const char * action_ui_name_default(int act)
Definition actions.c:6055
ACTPROB_VAL_1_PCT
#define ACTPROB_VAL_1_PCT
Definition actions.c:51
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:5545
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:3677
action_enabler_new
struct action_enabler * action_enabler_new(void)
Definition actions.c:1450
action_requires_details
bool action_requires_details(const struct action *paction)
Definition actions.c:1120
action_prob_new_not_relevant
struct act_prob action_prob_new_not_relevant(void)
Definition actions.c:5013
action_target_kind_help
const char * action_target_kind_help(enum action_target_kind kind)
Definition actions.c:7515
enabler_first_self_contradiction
static struct req_vec_problem * enabler_first_self_contradiction(const struct action_enabler *enabler)
Definition actions.c:1820
action_get_role
int action_get_role(const struct action *paction)
Definition actions.c:1438
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:4646
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:1018
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:4831
action_auto_perf_by_number
const struct action_auto_perf * action_auto_perf_by_number(const int num)
Definition actions.c:5691
action_prob_new_impossible
struct act_prob action_prob_new_impossible(void)
Definition actions.c:4993
action_enabler_possible_actor
bool action_enabler_possible_actor(const struct action_enabler *ae)
Definition actions.c:5572
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:2195
_actions
struct action ** _actions
Definition actions.c:58
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1043
action_enabler_remove
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:1513
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1083
action_prob_is_signal
static bool action_prob_is_signal(const struct act_prob probability)
Definition actions.c:5087
action_enabler_copy
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:1481
action_prob_to_text
static const char * action_prob_to_text(const struct act_prob prob)
Definition actions.c:1246
action_prob_cmp_pessimist
int action_prob_cmp_pessimist(const struct act_prob ap1, const struct act_prob ap2)
Definition actions.c:5104
action_id_is_internal
bool action_id_is_internal(action_id act)
Definition actions.c:5667
is_action_enabled_unit_on_self
bool is_action_enabled_unit_on_self(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit)
Definition actions.c:3442
action_id_is_rare_pop_up
bool action_id_is_rare_pop_up(action_id act_id)
Definition actions.c:1135
actions_init
void actions_init(void)
Definition actions.c:830
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:4897
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:955
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:1549
action_prob_vs_unit
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:4286
tgt_city_local_building
static const struct impr_type * tgt_city_local_building(const struct city *target_city)
Definition actions.c:2089
ui_name_str
static struct astring ui_name_str
Definition actions.c:64
is_action_enabled_unit_on_extras
bool is_action_enabled_unit_on_extras(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:3370
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:3070
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:3147
action_prob_to_0_to_1_pessimist
double action_prob_to_0_to_1_pessimist(const struct act_prob ap)
Definition actions.c:5155
gen_action_name_update_cb
const char * gen_action_name_update_cb(const char *old_name)
Definition actions.c:7489
actlist_by_activity
static struct action_list * actlist_by_activity[ACTIVITY_LAST]
Definition actions.c:98
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1529
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:2045
action_distance_accepted
bool action_distance_accepted(const struct action *action, const int distance)
Definition actions.c:1159
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:4580
action_ui_name_ruleset_var_name
const char * action_ui_name_ruleset_var_name(int act)
Definition actions.c:5760
action_get_ui_name_mnemonic
const char * action_get_ui_name_mnemonic(action_id act_id, const char *mnemonic)
Definition actions.c:1233
ACTPROB_VAL_MIN
#define ACTPROB_VAL_MIN
Definition actions.c:47
actions.h
action_noninternal_iterate_end
#define action_noninternal_iterate_end
Definition actions.h:231
ACTION_DISTANCE_MAX
#define ACTION_DISTANCE_MAX
Definition actions.h:103
enabler_get_action
#define enabler_get_action(_enabler_)
Definition actions.h:177
ASSERT_UNUSED_ACTION_CASES
#define ASSERT_UNUSED_ACTION_CASES
Definition actions.h:38
ACTPROB_CERTAIN
#define ACTPROB_CERTAIN
Definition actions.h:666
enabler_get_action_id
#define enabler_get_action_id(_enabler_)
Definition actions.h:178
ACTPROB_NA
#define ACTPROB_NA
Definition actions.h:667
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:390
action_enabler_list_re_iterate_end
#define action_enabler_list_re_iterate_end
Definition actions.h:191
ACTION_DISTANCE_LAST_NON_SIGNAL
#define ACTION_DISTANCE_LAST_NON_SIGNAL
Definition actions.h:99
action_enabler_list_re_iterate
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:187
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:175
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:185
ACTION_DISTANCE_UNLIMITED
#define ACTION_DISTANCE_UNLIMITED
Definition actions.h:101
action_iterate_end
#define action_iterate_end
Definition actions.h:209
MAX_NUM_ACTIONS
#define MAX_NUM_ACTIONS
Definition actions.h:58
action_iterate_all
#define action_iterate_all(_act_)
Definition actions.h:195
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:403
action_iterate_all_end
#define action_iterate_all_end
Definition actions.h:200
ACTPROB_NOT_KNOWN
#define ACTPROB_NOT_KNOWN
Definition actions.h:669
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:183
action_id_distance_accepted
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:439
ACTPROB_IMPOSSIBLE
#define ACTPROB_IMPOSSIBLE
Definition actions.h:665
ACTPROB_NOT_IMPLEMENTED
#define ACTPROB_NOT_IMPLEMENTED
Definition actions.h:668
action_iterate
#define action_iterate(_act_)
Definition actions.h:205
ACTION_ANY
#define ACTION_ANY
Definition actions.h:52
action_noninternal_iterate
#define action_noninternal_iterate(_act_)
Definition actions.h:226
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:407
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:420
ACTION_ODDS_PCT_DICE_ROLL_NA
#define ACTION_ODDS_PCT_DICE_ROLL_NA
Definition actions.h:672
ACTION_NONE
#define ACTION_NONE
Definition actions.h:55
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:148
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:251
astr_clear
void astr_clear(struct astring *astr)
Definition astring.c:201
astr_add
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:271
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:162
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:751
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:480
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:257
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:839
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:945
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:312
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 req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
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:81
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
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:857
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:381
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:678
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:677
action_id
int action_id
Definition fc_types.h:393
ACTRES_NONE
#define ACTRES_NONE
Definition fc_types.h:331
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:61
wld
struct world wld
Definition game.c:62
game.h
is_ruleset_compat_mode
static bool is_ruleset_compat_mode(void)
Definition game.h:362
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_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:636
map.h
MAP_DISTANCE_MAX
#define MAP_DISTANCE_MAX
Definition map.h:632
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:781
mke_eval_reqs
enum fc_tristate mke_eval_reqs(const struct player *pov_player, const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition metaknowledge.c:755
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:318
is_native_tile
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:330
unit_move_rate
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
unit_could_load_at
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:912
can_unit_type_transport
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:869
can_attack_non_native
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:213
movement.h
oblig_hard_reqs_init
void oblig_hard_reqs_init(void)
Definition oblig_reqs.c:807
oblig_hard_reqs_free
void oblig_hard_reqs_free(void)
Definition oblig_reqs.c:827
hard_code_oblig_hard_reqs_ruleset
void hard_code_oblig_hard_reqs_ruleset(void)
Definition oblig_reqs.c:770
hard_code_oblig_hard_reqs
void hard_code_oblig_hard_reqs(void)
Definition oblig_reqs.c:250
oblig_hard_reqs_get
struct obligatory_req_vector * oblig_hard_reqs_get(enum action_result res)
Definition oblig_reqs.c:852
oblig_hard_reqs_get_sub
struct obligatory_req_vector * oblig_hard_reqs_get_sub(enum action_sub_result res)
Definition oblig_reqs.c:863
oblig_reqs.h
obligatory_req_vector_iterate_end
#define obligatory_req_vector_iterate_end
Definition oblig_reqs.h:48
obligatory_req_vector_iterate
#define obligatory_req_vector_iterate(obreq_vec, pobreq)
Definition oblig_reqs.h:46
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:1409
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:6164
req_context_empty
const struct req_context * req_context_empty(void)
Definition requirements.c:1011
req_to_fstring
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
Definition requirements.c:1026
universal_fulfills_requirements
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Definition requirements.c:7575
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:6570
are_requirements_contradictions
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
Definition requirements.c:1688
req_vec_problem_new
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *descr,...)
Definition requirements.c:6460
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:5807
does_req_contradicts_reqs
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:1867
req_vec_is_impossible_to_fulfill
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
Definition requirements.c:6260
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:6742
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:127
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
size
size_t size
Definition specvec.h:72
act_prob
Definition fc_types.h:1220
act_prob::max
int max
Definition fc_types.h:1222
act_prob::min
int min
Definition fc_types.h:1221
action_auto_perf
Definition actions.h:316
action_auto_perf::cause
enum action_auto_perf_cause cause
Definition actions.h:318
action_auto_perf::alternatives
action_id alternatives[MAX_NUM_ACTIONS]
Definition actions.h:326
action_enabler
Definition actions.h:165
action_enabler::action
action_id action
Definition actions.h:166
action_enabler::actor_reqs
struct requirement_vector actor_reqs
Definition actions.h:167
action_enabler::target_reqs
struct requirement_vector target_reqs
Definition actions.h:168
action
Definition actions.h:106
action::unitwaittime_controlled
bool unitwaittime_controlled
Definition actions.h:155
action::id
action_id id
Definition actions.h:107
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:139
action::rare_pop_up
bool rare_pop_up
Definition actions.h:152
action::max_distance
int max_distance
Definition actions.h:122
action::quiet
bool quiet
Definition actions.h:129
action::sub_target_kind
enum action_sub_target_kind sub_target_kind
Definition actions.h:114
action::moves_actor
enum moves_actor_kind moves_actor
Definition actions.h:159
action::is_unit
struct action::@12::@13 is_unit
action::result
enum action_result result
Definition actions.h:109
action::ui_name
char ui_name[MAX_LEN_NAME]
Definition actions.h:125
action::sub_results
bv_action_sub_results sub_results
Definition actions.h:110
action::actor_kind
enum action_actor_kind actor_kind
Definition actions.h:112
action::target_complexity
enum act_tgt_compl target_complexity
Definition actions.h:117
action::blocked_by
bv_actions blocked_by
Definition actions.h:133
action::actor
union action::@12 actor
action::target_kind
enum action_target_kind target_kind
Definition actions.h:113
action::min_distance
int min_distance
Definition actions.h:122
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
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:215
packet_game_info::airlifting_style
enum airlifting_style airlifting_style
Definition packets_gen.h:122
packet_game_info::airlift_from_always_enabled
bool airlift_from_always_enabled
Definition packets_gen.h:123
packet_game_info::diplchance_initial_odds
bv_actions diplchance_initial_odds
Definition packets_gen.h:152
player
Definition player.h:249
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:507
unit_type::veteran
struct veteran_system * veteran
Definition unittype.h:551
unit
Definition unit.h:140
unit::moves_left
int moves_left
Definition unit.h:152
unit::tile
struct tile * tile
Definition unit.h:142
unit::paradropped
bool paradropped
Definition unit.h:177
unit::utype
const struct unit_type * utype
Definition unit.h:141
universal
Definition fc_types.h:878
universal::kind
enum universals_n kind
Definition fc_types.h:880
veteran_level
Definition unittype.h:493
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:186
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:276
advance_iterate_end
#define advance_iterate_end
Definition tech.h:277
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:97
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2499
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:386
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2483
can_unit_unload
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:776
unit_can_convert
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2073
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:397
unit_owner
#define unit_owner(_pu)
Definition unit.h:396
unit_home
#define unit_home(_pu_)
Definition unit.h:394
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:756
L_LAST
#define L_LAST
Definition unittype.h:446
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:859
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:866
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:535