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