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

Freeciv-3.2

Loading...
Searching...
No Matches
unittype.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 <string.h>
19#include <math.h> /* ceil */
20
21/* utility */
22#include "astring.h"
23#include "fcintl.h"
24#include "log.h"
25#include "mem.h"
26#include "shared.h"
27#include "string_vector.h"
28#include "support.h"
29
30/* common */
31#include "ai.h"
32#include "combat.h"
33#include "game.h"
34#include "government.h"
35#include "movement.h"
36#include "player.h"
37#include "research.h"
38#include "unitlist.h"
39
40#include "unittype.h"
41
42#define MAX_UNIT_ROLES L_LAST + ACTION_COUNT
43
44 static struct unit_type unit_types[U_LAST];
45 static struct unit_class unit_classes[UCL_LAST];
46/* the unit_types and unit_classes arrays are now setup in:
47 server/ruleset.c (for the server)
48 client/packhand.c (for the client)
49*/
50
51 static struct user_flag user_type_flags[MAX_NUM_USER_UNIT_FLAGS];
52
53 static struct user_flag user_class_flags[MAX_NUM_USER_UCLASS_FLAGS];
54
55/**********************************************************************/
58 struct unit_type *unit_type_array_first(void)
59{
60 if (game.control.num_unit_types > 0) {
61 return unit_types;
62 }
63 return NULL;
64}
65
66/**********************************************************************/
69 const struct unit_type *unit_type_array_last(void)
70{
71 if (game.control.num_unit_types > 0) {
72 return &unit_types[game.control.num_unit_types - 1];
73 }
74 return NULL;
75}
76
77/**********************************************************************/
80 Unit_type_id utype_count(void)
81{
82 return game.control.num_unit_types;
83}
84
85/**********************************************************************/
91 Unit_type_id utype_index(const struct unit_type *punittype)
92{
93 fc_assert_ret_val(punittype, -1);
94 return punittype - unit_types;
95}
96
97/**********************************************************************/
100 Unit_type_id utype_number(const struct unit_type *punittype)
101{
102 fc_assert_ret_val(punittype, -1);
103 return punittype->item_number;
104}
105
106/**********************************************************************/
112 struct unit_type *utype_by_number(const Unit_type_id id)
113{
114 if (id < 0 || id >= game.control.num_unit_types) {
115 return NULL;
116 }
117 return &unit_types[id];
118}
119
120/**********************************************************************/
123 const struct unit_type *unit_type_get(const struct unit *punit)
124{
125 fc_assert_ret_val(NULL != punit, NULL);
126 return punit->utype;
127}
128
129/**********************************************************************/
132 int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer,
133 Output_type_id otype)
134{
135 int val = ut->upkeep[otype], gold_upkeep_factor;
136
137 if (BV_ISSET(ut->flags, UTYF_FANATIC)
138 && get_player_bonus(pplayer, EFT_FANATICS) > 0) {
139 /* Special case: fanatics have no upkeep under fanaticism. */
140 return 0;
141 }
142
143 /* Switch shield upkeep to gold upkeep if
144 - the effect 'EFT_SHIELD2GOLD_FACTOR' is non-zero (it gives the
145 conversion factor in percent) and
146 - the unit has the corresponding flag set (UTYF_SHIELD2GOLD)
147 FIXME: Should the ai know about this? */
148 if (utype_has_flag(ut, UTYF_SHIELD2GOLD)
149 && (otype == O_GOLD || otype == O_SHIELD)) {
150 gold_upkeep_factor = get_player_bonus(pplayer, EFT_SHIELD2GOLD_FACTOR);
151 if (gold_upkeep_factor > 0) {
152 switch (otype) {
153 case O_GOLD:
154 val = ceil((0.01 * gold_upkeep_factor) * ut->upkeep[O_SHIELD]);
155 break;
156 case O_SHIELD:
157 val = 0;
158 break;
159 default:
160 fc_assert(otype == O_GOLD || otype == O_SHIELD);
161 break;
162 }
163 }
164 }
165
166 val *= get_target_bonus_effects(NULL,
167 &(const struct req_context) {
168 .player = pplayer,
169 .output = get_output_type(otype),
170 .unittype = ut
171 },
172 NULL, EFT_UPKEEP_FACTOR);
173
174 return val;
175}
176
177/**********************************************************************/
181 int utype_happy_cost(const struct unit_type *ut,
182 const struct player *pplayer)
183{
184 return ut->happy_cost * get_player_bonus(pplayer, EFT_UNHAPPY_FACTOR);
185}
186
187/**********************************************************************/
190 bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
191{
192 return utype_has_flag(unit_type_get(punit), flag);
193}
194
195/**********************************************************************/
199 bool utype_has_role(const struct unit_type *punittype, int role)
200{
201 fc_assert_ret_val(role >= L_FIRST && role < L_LAST, FALSE);
202 return BV_ISSET(punittype->roles, role - L_FIRST);
203}
204
205/**********************************************************************/
208 bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
209{
210 return utype_has_role(unit_type_get(punit), role);
211}
212
213/**********************************************************************/
217 bool utype_can_create_extra(const struct unit_type *putype,
218 const struct extra_type *pextra)
219{
220 action_iterate(act_id) {
221 struct action *paction = action_by_number(act_id);
222
223 if (!utype_can_do_action(putype, act_id)) {
224 /* Not relevant. */
225 continue;
226 }
227
228 if (actres_creates_extra(paction->result, pextra)) {
229 /* Can create */
230 return TRUE;
231 }
232 } action_iterate_end;
233
234 return FALSE;
235}
236
237/**********************************************************************/
241 bool utype_can_remove_extra(const struct unit_type *putype,
242 const struct extra_type *pextra)
243{
244 action_iterate(act_id) {
245 struct action *paction = action_by_number(act_id);
246
247 if (!utype_can_do_action(putype, act_id)) {
248 /* Not relevant. */
249 continue;
250 }
251
252 if (actres_removes_extra(paction->result, pextra)) {
253 /* Can remove */
254 return TRUE;
255 }
256 } action_iterate_end;
257
258 return FALSE;
259}
260
261/**********************************************************************/
264 bool unit_can_take_over(const struct unit *punit)
265{
266 /* TODO: Should unit state dependent action enablers be considered?
267 * Some callers aren't yet ready for changeable unit state (like current
268 * location) playing a role. */
269 return unit_owner(punit)->ai_common.barbarian_type != ANIMAL_BARBARIAN
270 && utype_can_take_over(unit_type_get(punit));
271}
272
273/**********************************************************************/
276 bool utype_can_take_over(const struct unit_type *punittype)
277{
278 /* FIXME: "Paradrop Unit" can in certain circumstances result in city
279 * conquest. */
280 return utype_can_do_action_result(punittype, ACTRES_CONQUER_CITY);
281}
282
283/**********************************************************************/
288 bool utype_can_freely_load(const struct unit_type *pcargotype,
289 const struct unit_type *ptranstype)
290{
291 return BV_ISSET(pcargotype->embarks,
292 uclass_index(utype_class(ptranstype)));
293}
294
295/**********************************************************************/
300 bool utype_can_freely_unload(const struct unit_type *pcargotype,
301 const struct unit_type *ptranstype)
302{
303 return BV_ISSET(pcargotype->disembarks,
304 uclass_index(utype_class(ptranstype)));
305}
306
307/* Fake action id representing any hostile action. */
308#define ACTION_HOSTILE ACTION_COUNT + 1
309
310/* Number of real and fake actions. */
311#define ACTION_AND_FAKES ACTION_HOSTILE + 1
312
313/* Cache of what generalized (ruleset defined) action enabler controlled
314 * actions units of each type can perform. Checking if any action can be
315 * done at all is done via the fake action id ACTION_ANY. If any hostile
316 * action can be performed is done via ACTION_HOSTILE. */
317 static bv_unit_types unit_can_act_cache[ACTION_AND_FAKES];
318
319/**********************************************************************/
323 static void unit_can_act_cache_set(struct unit_type *putype)
324{
325 /* Clear old values. */
326 action_iterate(act_id) {
327 BV_CLR(unit_can_act_cache[act_id], utype_index(putype));
328 } action_iterate_end;
329 BV_CLR(unit_can_act_cache[ACTION_ANY], utype_index(putype));
330 BV_CLR(unit_can_act_cache[ACTION_HOSTILE], utype_index(putype));
331
332 /* See if the unit type can do an action controlled by generalized action
333 * enablers */
334 action_enablers_iterate(enabler) {
335 const struct action *paction = enabler_get_action(enabler);
336 action_id act_id = action_id(paction);
337
338 if (action_get_actor_kind(paction) == AAK_UNIT
339 && action_actor_utype_hard_reqs_ok(paction, putype)
340 && requirement_fulfilled_by_unit_type(putype,
341 &(enabler->actor_reqs))) {
342 log_debug("act_cache: %s can %s",
343 utype_rule_name(putype),
344 action_rule_name(paction));
345 BV_SET(unit_can_act_cache[act_id], utype_index(putype));
346 BV_SET(unit_can_act_cache[ACTION_ANY], utype_index(putype));
347
348 if (actres_is_hostile(paction->result)) {
349 BV_SET(unit_can_act_cache[ACTION_HOSTILE], utype_index(putype));
350 }
351 }
352 } action_enablers_iterate_end;
353}
354
355/**********************************************************************/
359 bool utype_may_act_at_all(const struct unit_type *putype)
360{
361 return utype_can_do_action(putype, ACTION_ANY);
362}
363
364/**********************************************************************/
371 bool utype_can_do_action(const struct unit_type *putype,
372 const action_id act_id)
373{
374 fc_assert_ret_val(putype, FALSE);
375 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
376
377 return BV_ISSET(unit_can_act_cache[act_id], utype_index(putype));
378}
379
380/**********************************************************************/
387 bool utype_can_do_action_result(const struct unit_type *putype,
388 enum action_result result)
389{
390 fc_assert_ret_val(putype, FALSE);
391
392 action_by_result_iterate(paction, result) {
393 if (utype_can_do_action(putype, action_id(paction))) {
394 return TRUE;
395 }
396 } action_by_result_iterate_end;
397
398 return FALSE;
399}
400
401/**********************************************************************/
408 bool utype_can_do_action_sub_result(const struct unit_type *putype,
409 enum action_sub_result sub_result)
410{
411 fc_assert_ret_val(putype, FALSE);
412
413 action_iterate(act_id) {
414 struct action *paction = action_by_number(act_id);
415
416 if (!BV_ISSET(paction->sub_results, sub_result)) {
417 /* Not relevant */
418 continue;
419 }
420
421 if (utype_can_do_action(putype, paction->id)) {
422 return TRUE;
423 }
424 } action_iterate_end;
425
426 return FALSE;
427}
428
429/**********************************************************************/
433 static bool utype_can_do_action_role(const struct unit_type *putype,
434 const int role)
435{
436 return utype_can_do_action(putype, role - L_LAST);
437}
438
439/**********************************************************************/
443 bool utype_acts_hostile(const struct unit_type *putype)
444{
445 return utype_can_do_action(putype, ACTION_HOSTILE);
446}
447
448/* Cache of if a generalized (ruleset defined) action enabler controlled
449 * action always spends all remaining movement of a unit of the specified
450 * unit type. */
451 static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT];
452
453/**********************************************************************/
457 static void utype_act_takes_all_mp_cache_set(struct unit_type *putype)
458{
459 action_iterate(act_id) {
460 /* See if the unit type has all remaining MP spent by the specified
461 * action. */
462
463 struct action *paction = action_by_number(act_id);
464 struct universal unis[] = {
465 { .kind = VUT_ACTION, .value = {.action = (paction)} },
466 { .kind = VUT_UTYPE, .value = {.utype = (putype)} }
467 };
468
469 if (!utype_can_do_action(putype, paction->id)) {
470 /* Not relevant. */
471 continue;
472 }
473
474 if (effect_universals_value_never_below(EFT_ACTION_SUCCESS_MOVE_COST,
475 unis, ARRAY_SIZE(unis),
476 MAX_MOVE_FRAGS)) {
477 /* Guaranteed to always consume all remaining MP of an actor unit of
478 * this type. */
479 log_debug("unit_act_takes_all_mp_cache_set: %s takes all MP from %s",
480 utype_rule_name(putype), action_rule_name(paction));
481 BV_SET(utype_act_takes_all_mp_cache[paction->id], utype_index(putype));
482 } else {
483 /* Clear old value in case it was set. */
484 BV_CLR(utype_act_takes_all_mp_cache[paction->id], utype_index(putype));
485 }
486 } action_iterate_end;
487}
488
489/* Cache of if a generalized (ruleset defined) action enabler controlled
490 * action always spends all remaining movement of a unit of the specified
491 * unit type given the specified unit state property. */
492static bv_unit_types
493utype_act_takes_all_mp_ustate_cache[ACTION_COUNT][USP_COUNT];
494
495/**********************************************************************/
500 static void utype_act_takes_all_mp_ustate_cache_set(struct unit_type *putype)
501{
502 action_iterate(act_id) {
503 /* See if the unit type has all remaining MP spent by the specified
504 * action given the specified unit state property. */
505
506 enum ustate_prop prop = ustate_prop_begin();
507 struct action *paction = action_by_number(act_id);
508 struct universal unis[] = {
509 { .kind = VUT_ACTION, .value = {.action = (paction)} },
510 { .kind = VUT_UTYPE, .value = {.utype = (putype)} },
511 { .kind = VUT_UNITSTATE, .value = {.unit_state = (prop)} }
512 };
513
514 if (!utype_can_do_action(putype, paction->id)) {
515 /* Not relevant. */
516 continue;
517 }
518
519 for (prop = ustate_prop_begin(); prop != ustate_prop_end();
520 prop = ustate_prop_next(prop)) {
521 unis[2].value.unit_state = prop;
522 if (effect_universals_value_never_below(EFT_ACTION_SUCCESS_MOVE_COST,
523 unis, ARRAY_SIZE(unis),
524 MAX_MOVE_FRAGS)) {
525 /* Guaranteed to always consume all remaining MP of an actor unit of
526 * this type given the specified unit state property. */
527 log_debug("unit_act_takes_all_mp_cache_set: %s takes all MP from %s"
528 " when unit state is %s",
529 utype_rule_name(putype), action_rule_name(paction),
530 ustate_prop_name(prop));
531 BV_SET(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
532 utype_index(putype));
533 } else {
534 /* Clear old value in case it was set. */
535 BV_CLR(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
536 utype_index(putype));
537 }
538 }
539 } action_iterate_end;
540}
541
542/* Cache if any action at all may be possible when the actor unit's state
543 * is...
544 * bit 0 to USP_COUNT - 1: Possible when the corresponding property is TRUE
545 * bit USP_COUNT to ((USP_COUNT * 2) - 1): Possible when the corresponding
546 * property is FALSE
547 */
548 BV_DEFINE(bv_ustate_act_cache, USP_COUNT * 2);
549
550/* Cache what actions may be possible when the target's local citytile state
551 * is
552 * bit 0 to CITYT_LAST - 1: Possible when the corresponding property is TRUE
553 * bit USP_COUNT to ((CITYT_LAST * 2) - 1): Possible when the corresponding
554 * property is FALSE
555 */
556 BV_DEFINE(bv_citytile_cache, CITYT_LAST * 2);
557
558/* Cache position lookup functions */
559#define requirement_unit_state_ereq(_id_, _present_) \
560 requirement_kind_ereq(_id_, REQ_RANGE_LOCAL, _present_, USP_COUNT)
561#define requirement_citytile_ereq(_id_, _present_) \
562 requirement_kind_ereq(_id_, REQ_RANGE_LOCAL, _present_, CITYT_LAST)
563
564/* Caches for each unit type */
565 static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES];
566 static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES];
567static bv_diplrel_all_reqs
568dipl_rel_tile_other_tgt_a_cache[U_LAST][ACTION_AND_FAKES];
569 static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES];
570
571/**********************************************************************/
576 static void unit_state_action_cache_set(struct unit_type *putype)
577{
578 struct requirement req;
579 int uidx = utype_index(putype);
580
581 /* The unit is not yet known to be allowed to perform any actions no
582 * matter what its unit state is. */
583 action_iterate(act_id) {
584 BV_CLR_ALL(ustate_act_cache[uidx][act_id]);
585 } action_iterate_end;
586 BV_CLR_ALL(ustate_act_cache[uidx][ACTION_ANY]);
587 BV_CLR_ALL(ustate_act_cache[uidx][ACTION_HOSTILE]);
588
589 if (!utype_may_act_at_all(putype)) {
590 /* Not an actor unit. */
591 return;
592 }
593
594 /* Common for every situation */
595 req.range = REQ_RANGE_LOCAL;
596 req.survives = FALSE;
597 req.source.kind = VUT_UNITSTATE;
598
599 for (req.source.value.unit_state = ustate_prop_begin();
600 req.source.value.unit_state != ustate_prop_end();
601 req.source.value.unit_state = ustate_prop_next(
602 req.source.value.unit_state)) {
603
604 /* No action will ever be possible in a specific unit state if the
605 * opposite unit state is required in all action enablers.
606 * No unit state except present and !present of the same property
607 * implies or conflicts with another so the tests can be simple. */
608 action_enablers_iterate(enabler) {
609 struct action *paction = enabler_get_action(enabler);
610
611 if (requirement_fulfilled_by_unit_type(putype,
612 &(enabler->actor_reqs))
613 && action_get_actor_kind(paction) == AAK_UNIT) {
614 bool present = TRUE;
615
616 do {
617 action_id act_id = enabler_get_action_id(enabler);
618
619 /* OK if not mentioned */
620 req.present = present;
621 if (!is_req_in_vec(&req, &(enabler->actor_reqs))) {
622 BV_SET(ustate_act_cache[utype_index(putype)][act_id],
623 requirement_unit_state_ereq(req.source.value.unit_state,
624 !req.present));
625 if (actres_is_hostile(paction->result)) {
626 BV_SET(ustate_act_cache[utype_index(putype)][ACTION_HOSTILE],
627 requirement_unit_state_ereq(req.source.value.unit_state,
628 !req.present));
629 }
630 BV_SET(ustate_act_cache[utype_index(putype)][ACTION_ANY],
631 requirement_unit_state_ereq(req.source.value.unit_state,
632 !req.present));
633 }
634 present = !present;
635 } while (!present);
636 }
637 } action_enablers_iterate_end;
638 }
639}
640
641/**********************************************************************/
649 static void local_dipl_rel_action_cache_set(struct unit_type *putype)
650{
651 struct requirement req;
652 struct requirement tile_is_claimed;
653 int uidx = utype_index(putype);
654
655 /* The unit is not yet known to be allowed to perform any actions no
656 * matter what the diplomatic state is. */
657 action_iterate(act_id) {
658 BV_CLR_ALL(dipl_rel_action_cache[uidx][act_id]);
659 } action_iterate_end;
660 BV_CLR_ALL(dipl_rel_action_cache[uidx][ACTION_ANY]);
661 BV_CLR_ALL(dipl_rel_action_cache[uidx][ACTION_HOSTILE]);
662
663 if (!utype_may_act_at_all(putype)) {
664 /* Not an actor unit. */
665 return;
666 }
667
668 /* Tile is claimed as a requirement. */
669 tile_is_claimed.range = REQ_RANGE_TILE;
670 tile_is_claimed.survives = FALSE;
671 tile_is_claimed.source.kind = VUT_CITYTILE;
672 tile_is_claimed.present = TRUE;
673 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
674
675 /* Common for every situation */
676 req.range = REQ_RANGE_LOCAL;
677 req.survives = FALSE;
678 req.source.kind = VUT_DIPLREL;
679
680 /* DiplRel starts with diplstate_type and ends with diplrel_other */
681 for (req.source.value.diplrel = diplstate_type_begin();
682 req.source.value.diplrel != DRO_LAST;
683 req.source.value.diplrel++) {
684
685 /* No action will ever be possible in a specific diplomatic relation if
686 * its presence contradicts all action enablers.
687 * Everything was set to false above. It is therefore OK to only change
688 * the cache when units can do an action given a certain diplomatic
689 * relationship property value. */
690 action_enablers_iterate(enabler) {
691 struct action *paction = enabler_get_action(enabler);
692
693 if (requirement_fulfilled_by_unit_type(putype,
694 &(enabler->actor_reqs))
695 && action_get_actor_kind(paction) == AAK_UNIT
696 && ((action_get_target_kind(paction) != ATK_TILE
697 && action_get_target_kind(paction) != ATK_EXTRAS)
698 /* No diplomatic relation to Nature */
699 || !does_req_contradicts_reqs(&tile_is_claimed,
700 &enabler->target_reqs))) {
701 bool present = TRUE;
702
703 do {
704 action_id act_id = enabler_get_action_id(enabler);
705
706 req.present = present;
707 if (!does_req_contradicts_reqs(&req, &(enabler->actor_reqs))) {
708 BV_SET(dipl_rel_action_cache[uidx][act_id],
709 requirement_diplrel_ereq(req.source.value.diplrel,
710 REQ_RANGE_LOCAL, req.present));
711 if (actres_is_hostile(paction->result)) {
712 BV_SET(dipl_rel_action_cache[uidx][ACTION_HOSTILE],
713 requirement_diplrel_ereq(req.source.value.diplrel,
714 REQ_RANGE_LOCAL,
715 req.present));
716 }
717 BV_SET(dipl_rel_action_cache[uidx][ACTION_ANY],
718 requirement_diplrel_ereq(req.source.value.diplrel,
719 REQ_RANGE_LOCAL, req.present));
720 }
721 present = !present;
722 } while (!present);
723 }
724 } action_enablers_iterate_end;
725 }
726}
727
728/**********************************************************************/
733static void
734local_dipl_rel_tile_other_tgt_action_cache_set(struct unit_type *putype)
735{
736 struct requirement req;
737 struct requirement tile_is_claimed;
738 int uidx = utype_index(putype);
739
740 /* The unit is not yet known to be allowed to perform any actions no
741 * matter what the diplomatic state is. */
742 action_iterate(act_id) {
743 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][act_id]);
744 } action_iterate_end;
745 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_ANY]);
746 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_HOSTILE]);
747
748 /* Tile is claimed as a requirement. */
749 tile_is_claimed.range = REQ_RANGE_TILE;
750 tile_is_claimed.survives = FALSE;
751 tile_is_claimed.source.kind = VUT_CITYTILE;
752 tile_is_claimed.present = TRUE;
753 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
754
755 /* Common for every situation */
756 req.range = REQ_RANGE_LOCAL;
757 req.survives = FALSE;
758 req.source.kind = VUT_DIPLREL_TILE_O;
759
760 /* DiplRel starts with diplstate_type and ends with diplrel_other */
761 for (req.source.value.diplrel = diplstate_type_begin();
762 req.source.value.diplrel != DRO_LAST;
763 req.source.value.diplrel++) {
764
765 /* No action will ever be possible in a specific diplomatic relation if
766 * its presence contradicts all action enablers.
767 * Everything was set to false above. It is therefore OK to only change
768 * the cache when units can do an action given a certain diplomatic
769 * relationship property value. */
770 action_enablers_iterate(enabler) {
771 struct action *paction = enabler_get_action(enabler);
772
773 if (requirement_fulfilled_by_unit_type(putype,
774 &(enabler->actor_reqs))
775 && action_get_actor_kind(paction) == AAK_UNIT
776 /* No diplomatic relation to Nature */
777 && !does_req_contradicts_reqs(&tile_is_claimed,
778 &enabler->target_reqs)) {
779 bool present = TRUE;
780
781 do {
782 action_id act_id = enabler_get_action_id(enabler);
783
784 req.present = present;
785 if (!does_req_contradicts_reqs(&req, &(enabler->target_reqs))) {
786 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][act_id],
787 requirement_diplrel_ereq(req.source.value.diplrel,
788 REQ_RANGE_LOCAL, req.present));
789 if (actres_is_hostile(paction->result)) {
790 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_HOSTILE],
791 requirement_diplrel_ereq(req.source.value.diplrel,
792 REQ_RANGE_LOCAL,
793 req.present));
794 }
795 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_ANY],
796 requirement_diplrel_ereq(req.source.value.diplrel,
797 REQ_RANGE_LOCAL, req.present));
798 }
799 present = !present;
800 } while (!present);
801 }
802 } action_enablers_iterate_end;
803 }
804}
805
806/**********************************************************************/
811 static void tgt_citytile_act_cache_set(struct unit_type *putype)
812{
813 struct requirement req;
814 int uidx = utype_index(putype);
815
816 /* The unit is not yet known to be allowed to perform any actions no
817 * matter what its target's CityTile state is. */
818 action_iterate(act_id) {
819 BV_CLR_ALL(ctile_tgt_act_cache[uidx][act_id]);
820 } action_iterate_end;
821 BV_CLR_ALL(ctile_tgt_act_cache[uidx][ACTION_ANY]);
822 BV_CLR_ALL(ctile_tgt_act_cache[uidx][ACTION_HOSTILE]);
823
824 if (!utype_may_act_at_all(putype)) {
825 /* Not an actor unit. */
826 return;
827 }
828
829 /* Common for every situation */
830 req.range = REQ_RANGE_TILE;
831 req.survives = FALSE;
832 req.source.kind = VUT_CITYTILE;
833
834 for (req.source.value.citytile = citytile_type_begin();
835 req.source.value.citytile != citytile_type_end();
836 req.source.value.citytile = citytile_type_next(
837 req.source.value.citytile)) {
838
839 /* No action will ever be possible in a target CityTile state if the
840 * opposite target CityTile state is required in all action enablers.
841 * No CityTile property state except present and !present of the same
842 * property implies or conflicts with another so the tests can be
843 * simple. */
844 action_enablers_iterate(enabler) {
845 struct action *paction = enabler_get_action(enabler);
846
847 if (requirement_fulfilled_by_unit_type(putype,
848 &(enabler->target_reqs))
849 && action_get_actor_kind(paction) == AAK_UNIT) {
850 bool present = TRUE;
851
852 do {
853 action_id act_id = enabler_get_action_id(enabler);
854
855 /* OK if not mentioned */
856 req.present = present;
857 if (!is_req_in_vec(&req, &(enabler->target_reqs))) {
858 BV_SET(
859 ctile_tgt_act_cache[utype_index(putype)][act_id],
860 requirement_citytile_ereq(req.source.value.citytile,
861 !req.present));
862 if (actres_is_hostile(paction->result)) {
863 BV_SET(
864 ctile_tgt_act_cache[utype_index(putype)][ACTION_HOSTILE],
865 requirement_citytile_ereq(req.source.value.citytile,
866 !req.present));
867 }
868 BV_SET(ctile_tgt_act_cache[utype_index(putype)][ACTION_ANY],
869 requirement_citytile_ereq(req.source.value.citytile,
870 !req.present));
871 }
872 present = !present;
873 } while (!present);
874 }
875 } action_enablers_iterate_end;
876 }
877}
878
879 struct range {
880 int min;
881 int max;
882};
883
884#define MOVES_LEFT_INFINITY -1
885
886/**********************************************************************/
890 static struct range *moves_left_range(struct requirement_vector *reqs)
891{
892 struct range *prange = fc_malloc(sizeof(prange));
893
894 prange->min = 0;
895 prange->max = MOVES_LEFT_INFINITY;
896
897 requirement_vector_iterate(reqs, preq) {
898 if (preq->source.kind == VUT_MINMOVES) {
899 if (preq->present) {
900 prange->min = preq->source.value.minmoves;
901 } else {
902 prange->max = preq->source.value.minmoves;
903 }
904 }
905 } requirement_vector_iterate_end;
906
907 return prange;
908}
909
910/**********************************************************************/
915 void unit_type_action_cache_set(struct unit_type *ptype)
916{
917 unit_can_act_cache_set(ptype);
918 unit_state_action_cache_set(ptype);
919 local_dipl_rel_action_cache_set(ptype);
920 local_dipl_rel_tile_other_tgt_action_cache_set(ptype);
921 tgt_citytile_act_cache_set(ptype);
922
923 utype_act_takes_all_mp_cache_set(ptype);
924 utype_act_takes_all_mp_ustate_cache_set(ptype);
925}
926
927/**********************************************************************/
931 void unit_type_action_cache_init(void)
932{
933 unit_type_iterate(u) {
934 unit_type_action_cache_set(u);
935 } unit_type_iterate_end;
936}
937
938/**********************************************************************/
943 bool can_unit_act_when_ustate_is(const struct unit_type *punit_type,
944 const enum ustate_prop prop,
945 const bool is_there)
946{
947 return utype_can_do_act_when_ustate(punit_type, ACTION_ANY, prop, is_there);
948}
949
950/**********************************************************************/
955 bool utype_can_do_act_when_ustate(const struct unit_type *punit_type,
956 const action_id act_id,
957 const enum ustate_prop prop,
958 const bool is_there)
959{
960 fc_assert_ret_val(punit_type, FALSE);
961 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
962
963 return BV_ISSET(ustate_act_cache[utype_index(punit_type)][act_id],
964 requirement_unit_state_ereq(prop, is_there));
965}
966
967/**********************************************************************/
975 bool utype_can_do_action_result_when_ustate(const struct unit_type *putype,
976 enum action_result result,
977 const enum ustate_prop prop,
978 const bool is_there)
979{
980 fc_assert_ret_val(putype, FALSE);
981
982 action_by_result_iterate(paction, result) {
983 if (utype_can_do_act_when_ustate(putype, action_id(paction), prop, is_there)) {
984 return TRUE;
985 }
986 } action_by_result_iterate_end;
987
988 return FALSE;
989}
990
991/**********************************************************************/
996 bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type,
997 const action_id act_id,
998 const enum citytile_type prop,
999 const bool is_there)
1000{
1001 fc_assert_ret_val(punit_type, FALSE);
1002 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1003
1004 return BV_ISSET(ctile_tgt_act_cache[utype_index(punit_type)][act_id],
1005 requirement_citytile_ereq(prop, is_there));
1006}
1007
1008/**********************************************************************/
1017 bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type,
1018 const action_id act_id,
1019 const int prop,
1020 const bool is_there)
1021{
1022 fc_assert_ret_val(punit_type, FALSE);
1023 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1024
1025 return BV_ISSET(dipl_rel_action_cache[utype_index(punit_type)][act_id],
1026 requirement_diplrel_ereq(prop, REQ_RANGE_LOCAL, is_there));
1027}
1028
1029/**********************************************************************/
1035bool
1036utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type,
1037 const action_id act_id,
1038 const int prop,
1039 const bool is_there)
1040{
1041 fc_assert_ret_val(punit_type, FALSE);
1042 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1043
1044 return BV_ISSET(
1045 dipl_rel_tile_other_tgt_a_cache[utype_index(punit_type)][act_id],
1046 requirement_diplrel_ereq(prop, REQ_RANGE_LOCAL, is_there));
1047}
1048
1049/**********************************************************************/
1058 bool utype_may_act_move_frags(const struct unit_type *punit_type,
1059 const action_id act_id,
1060 const int move_fragments)
1061{
1062 struct range *ml_range;
1063
1064 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
1065
1066 if (!utype_may_act_at_all(punit_type)) {
1067 /* Not an actor unit. */
1068 return FALSE;
1069 }
1070
1071 if (act_id == ACTION_ANY) {
1072 /* Any action is OK. */
1073 action_iterate(alt_act) {
1074 if (utype_may_act_move_frags(punit_type, alt_act,
1075 move_fragments)) {
1076 /* It only has to be true for one action. */
1077 return TRUE;
1078 }
1079 } action_iterate_end;
1080
1081 /* No action enabled. */
1082 return FALSE;
1083 }
1084
1085 if (action_id_get_actor_kind(act_id) != AAK_UNIT) {
1086 /* This action isn't performed by any unit at all so this unit type
1087 * can't do it. */
1088 return FALSE;
1089 }
1090
1091 action_enabler_list_iterate(action_enablers_for_action(act_id),
1092 enabler) {
1093 if (!requirement_fulfilled_by_unit_type(punit_type,
1094 &(enabler->actor_reqs))) {
1095 /* This action enabler isn't for this unit type at all. */
1096 continue;
1097 }
1098
1099 ml_range = moves_left_range(&(enabler->actor_reqs));
1100 if (ml_range->min <= move_fragments
1101 && (ml_range->max == MOVES_LEFT_INFINITY
1102 || ml_range->max > move_fragments)) {
1103 /* The number of move fragments is in range of the action enabler. */
1104
1105 free(ml_range);
1106
1107 return TRUE;
1108 }
1109
1110 free(ml_range);
1111 } action_enabler_list_iterate_end;
1112
1113 return FALSE;
1114}
1115
1116/**********************************************************************/
1124 bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type,
1125 const action_id act_id,
1126 const enum citytile_type prop,
1127 const bool is_there)
1128{
1129 struct requirement req;
1130
1131 if (!utype_may_act_at_all(punit_type)) {
1132 /* Not an actor unit. */
1133 return FALSE;
1134 }
1135
1136 if (act_id == ACTION_ANY) {
1137 /* Any action is OK. */
1138 action_iterate(alt_act) {
1139 if (utype_may_act_tgt_city_tile(punit_type, alt_act,
1140 prop, is_there)) {
1141 /* It only has to be true for one action. */
1142 return TRUE;
1143 }
1144 } action_iterate_end;
1145
1146 /* No action enabled. */
1147 return FALSE;
1148 }
1149
1150 if (action_id_get_actor_kind(act_id) != AAK_UNIT) {
1151 /* This action isn't performed by any unit at all so this unit type
1152 * can't do it. */
1153 return FALSE;
1154 }
1155
1156 /* Common for every situation */
1157 req.range = REQ_RANGE_TILE;
1158 req.survives = FALSE;
1159 req.source.kind = VUT_CITYTILE;
1160
1161 /* Will only check for the specified is_there */
1162 req.present = is_there;
1163
1164 /* Will only check the specified property */
1165 req.source.value.citytile = prop;
1166
1167 action_enabler_list_iterate(action_enablers_for_action(act_id),
1168 enabler) {
1169 if (!requirement_fulfilled_by_unit_type(punit_type,
1170 &(enabler->actor_reqs))) {
1171 /* This action enabler isn't for this unit type at all. */
1172 continue;
1173 }
1174
1175 if (!does_req_contradicts_reqs(&req, &(enabler->target_reqs))) {
1176 /* This action isn't blocked by the given target tile property. */
1177 return TRUE;
1178 }
1179 } action_enabler_list_iterate_end;
1180
1181 return FALSE;
1182}
1183
1184/**********************************************************************/
1191 bool utype_action_takes_all_mp(const struct unit_type *putype,
1192 struct action *paction)
1193{
1194 return BV_ISSET(utype_act_takes_all_mp_cache[paction->id],
1195 utype_index(putype));
1196}
1197
1198/**********************************************************************/
1207 bool utype_action_takes_all_mp_if_ustate_is(const struct unit_type *putype,
1208 struct action *paction,
1209 const enum ustate_prop prop)
1210{
1211 return BV_ISSET(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
1212 utype_index(putype));
1213}
1214
1215/**********************************************************************/
1219 bool utype_is_consumed_by_action(const struct action *paction,
1220 const struct unit_type *utype)
1221{
1222 return paction->actor_consuming_always;
1223}
1224
1225/**********************************************************************/
1229 bool utype_is_consumed_by_action_result(enum action_result result,
1230 const struct unit_type *utype)
1231{
1232 action_by_result_iterate(paction, result) {
1233 if (!utype_can_do_action(utype, action_id(paction))) {
1234 continue;
1235 }
1236
1237 if (utype_is_consumed_by_action(paction, utype)) {
1238 return TRUE;
1239 }
1240 } action_by_result_iterate_end;
1241
1242 return FALSE;
1243}
1244
1245/**********************************************************************/
1249 bool utype_is_moved_to_tgt_by_action(const struct action *paction,
1250 const struct unit_type *utype)
1251{
1252 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
1253
1254 if (paction->actor_consuming_always) {
1255 return FALSE;
1256 }
1257
1258 switch (paction->actor.is_unit.moves_actor) {
1259 case MAK_STAYS:
1260 /* Stays at the tile were it was. */
1261 return FALSE;
1262 case MAK_REGULAR:
1263 /* A "regular" move. Does it charge the move cost of a regular move?
1264 * Update utype_pays_for_regular_move_to_tgt() if yes. */
1265 return TRUE;
1266 case MAK_TELEPORT:
1267 /* A teleporting move. */
1268 return TRUE;
1269 case MAK_FORCED:
1270 /* Tries a forced move under certain conditions. */
1271 return FALSE;
1272 case MAK_ESCAPE:
1273 /* May die, may be teleported to a safe city. */
1274 return FALSE;
1275 case MAK_UNREPRESENTABLE:
1276 /* Too complex to determine. */
1277 return FALSE;
1278 }
1279
1280 fc_assert_msg(FALSE, "Should not reach this code.");
1281 return FALSE;
1282}
1283
1284/**********************************************************************/
1288 bool utype_is_unmoved_by_action(const struct action *paction,
1289 const struct unit_type *utype)
1290{
1291 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
1292
1293 if (paction->actor_consuming_always) {
1294 /* Dead counts as moved off the board */
1295 return FALSE;
1296 }
1297
1298 switch (paction->actor.is_unit.moves_actor) {
1299 case MAK_STAYS:
1300 /* Stays at the tile were it was. */
1301 return TRUE;
1302 case MAK_REGULAR:
1303 /* A "regular" move. Does it charge the move cost of a regular move?
1304 * Update utype_pays_for_regular_move_to_tgt() if yes. */
1305 return FALSE;
1306 case MAK_TELEPORT:
1307 /* A teleporting move. */
1308 return FALSE;
1309 case MAK_FORCED:
1310 /* Tries a forced move under certain conditions. */
1311 return FALSE;
1312 case MAK_ESCAPE:
1313 /* May die, may be teleported to a safe city. */
1314 return FALSE;
1315 case MAK_UNREPRESENTABLE:
1316 /* Too complex to determine. */
1317 return FALSE;
1318 }
1319
1320 fc_assert_msg(FALSE, "Should not reach this code.");
1321 return FALSE;
1322}
1323
1324/**********************************************************************/
1330 bool utype_pays_for_regular_move_to_tgt(const struct action *paction,
1331 const struct unit_type *utype)
1332{
1333 if (!utype_is_moved_to_tgt_by_action(paction, utype)) {
1334 /* Not even a move. */
1335 return FALSE;
1336 }
1337
1338 if (action_has_result(paction, ACTRES_CONQUER_CITY)) {
1339 /* Moves into the city to occupy it. */
1340 return TRUE;
1341 }
1342
1343 if (action_has_result(paction, ACTRES_CONQUER_EXTRAS)) {
1344 /* Moves into the tile with the extras to capture them. */
1345 return TRUE;
1346 }
1347
1348 if (action_has_result(paction, ACTRES_HUT_ENTER)) {
1349 /* Moves into the tile with the hut to enter it. */
1350 return TRUE;
1351 }
1352
1353 if (action_has_result(paction, ACTRES_HUT_FRIGHTEN)) {
1354 /* Moves into the tile with the hut to frighten it. */
1355 return TRUE;
1356 }
1357
1358 if (action_has_result(paction, ACTRES_TRANSPORT_DISEMBARK)) {
1359 /* Moves out of the transport to disembark. */
1360 return TRUE;
1361 }
1362
1363 if (action_has_result(paction, ACTRES_TRANSPORT_EMBARK)) {
1364 /* Moves into the transport to embark. */
1365 return TRUE;
1366 }
1367
1368 if (action_has_result(paction, ACTRES_UNIT_MOVE)) {
1369 /* Is a regular move. */
1370 return TRUE;
1371 }
1372
1373 return FALSE;
1374}
1375
1376/**********************************************************************/
1381 int utype_pays_mp_for_action_base(const struct action *paction,
1382 const struct unit_type *putype)
1383{
1384 int mpco = 0;
1385
1386 return mpco;
1387}
1388
1389/**********************************************************************/
1393 int utype_pays_mp_for_action_estimate(const struct civ_map *nmap,
1394 const struct action *paction,
1395 const struct unit_type *putype,
1396 const struct player *act_player,
1397 const struct tile *act_tile,
1398 const struct tile *tgt_tile)
1399{
1400 const struct tile *post_action_tile;
1401 int mpco = utype_pays_mp_for_action_base(paction, putype);
1402
1403 if (utype_is_moved_to_tgt_by_action(paction, putype)) {
1404 post_action_tile = tgt_tile;
1405 } else {
1406 /* FIXME: Not 100% true. May escape, have a probability for moving to
1407 * target tile etc. */
1408 post_action_tile = act_tile;
1409 }
1410
1411 if (utype_pays_for_regular_move_to_tgt(paction, putype)) {
1412 /* Add the cost from the move. */
1413 mpco += map_move_cost(nmap, act_player, putype,
1414 act_tile, tgt_tile);
1415 }
1416
1417 /* FIXME: Probably wrong result if the effect
1418 * EFT_ACTION_SUCCESS_MOVE_COST depends on unit state. Add unit state
1419 * parameters? */
1420 mpco += get_target_bonus_effects(NULL,
1421 &(const struct req_context) {
1422 .player = act_player,
1423 .city = tile_city(post_action_tile),
1424 .tile = tgt_tile,
1425 .unittype = putype,
1426 .action = paction,
1427 },
1428 NULL,
1429 EFT_ACTION_SUCCESS_MOVE_COST);
1430
1431 return mpco;
1432}
1433
1434/**********************************************************************/
1438 int utype_build_shield_cost(const struct city *pcity,
1439 const struct player *pplayer,
1440 const struct unit_type *punittype)
1441{
1442 int base;
1443 const struct player *owner;
1444 const struct tile *ptile;
1445
1446 if (pcity != NULL) {
1447 owner = city_owner(pcity);
1448 ptile = city_tile(pcity);
1449 } else {
1450 owner = NULL;
1451 ptile = NULL;
1452 }
1453 if (pplayer != NULL) {
1454 /* Override city owner. */
1455 owner = pplayer;
1456 }
1457
1458 base = punittype->build_cost
1459 * (100 + get_unittype_bonus(owner, ptile, punittype, NULL,
1460 EFT_UNIT_BUILD_COST_PCT)) / 100;
1461
1462 return MAX(base * game.info.shieldbox / 100, 1);
1463}
1464
1465/**********************************************************************/
1468 int utype_build_shield_cost_base(const struct unit_type *punittype)
1469{
1470 return MAX(punittype->build_cost * game.info.shieldbox / 100, 1);
1471}
1472
1473/**********************************************************************/
1476 int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
1477{
1478 return utype_build_shield_cost(pcity, NULL, unit_type_get(punit));
1479}
1480
1481/**********************************************************************/
1484 int unit_build_shield_cost_base(const struct unit *punit)
1485{
1486 return utype_build_shield_cost_base(unit_type_get(punit));
1487}
1488
1489/**********************************************************************/
1492 int utype_buy_gold_cost(const struct city *pcity,
1493 const struct unit_type *punittype,
1494 int shields_in_stock)
1495{
1496 int cost = 0;
1497 const int missing = utype_build_shield_cost(pcity, NULL, punittype) - shields_in_stock;
1498 struct player *owner;
1499 struct tile *ptile;
1500
1501 if (missing > 0) {
1502 cost = 2 * missing + (missing * missing) / 20;
1503 }
1504
1505 if (shields_in_stock == 0) {
1506 cost *= 2;
1507 }
1508
1509 if (pcity != NULL) {
1510 owner = city_owner(pcity);
1511 ptile = city_tile(pcity);
1512 } else {
1513 owner = NULL;
1514 ptile = NULL;
1515 }
1516
1517 cost = cost
1518 * (100 + get_unittype_bonus(owner, ptile, punittype, NULL,
1519 EFT_UNIT_BUY_COST_PCT))
1520 / 100;
1521
1522 return cost;
1523}
1524
1525/**********************************************************************/
1528 int utype_pop_value(const struct unit_type *punittype, const struct city *pcity)
1529{
1530 int pop_cost = punittype->pop_cost;
1531
1532 pop_cost -= get_unittype_bonus(city_owner(pcity), city_tile(pcity),
1533 punittype, NULL, EFT_POPCOST_FREE);
1534
1535 return MAX(0, pop_cost);
1536}
1537
1538/**********************************************************************/
1543 int unit_pop_value(const struct unit *punit)
1544{
1545 return unit_type_get(punit)->pop_cost;
1546}
1547
1548/**********************************************************************/
1551 enum unit_move_type utype_move_type(const struct unit_type *punittype)
1552{
1553 return utype_class(punittype)->move_type;
1554}
1555
1556/**********************************************************************/
1560 const char *utype_name_translation(const struct unit_type *punittype)
1561{
1562 return name_translation_get(&punittype->name);
1563}
1564
1565/**********************************************************************/
1569 const char *unit_name_translation(const struct unit *punit)
1570{
1571 return utype_name_translation(unit_type_get(punit));
1572}
1573
1574/**********************************************************************/
1578 const char *utype_rule_name(const struct unit_type *punittype)
1579{
1580 return rule_name_get(&punittype->name);
1581}
1582
1583/**********************************************************************/
1587 const char *unit_rule_name(const struct unit *punit)
1588{
1589 return utype_rule_name(unit_type_get(punit));
1590}
1591
1592/**********************************************************************/
1596 const char *utype_values_string(const struct unit_type *punittype)
1597{
1598 static char buffer[256];
1599
1600 /* Print in two parts as move_points_text() returns a static buffer */
1601 fc_snprintf(buffer, sizeof(buffer), "%d/%d/%s",
1602 punittype->attack_strength,
1603 punittype->defense_strength,
1604 move_points_text(punittype->move_rate, TRUE));
1605 if (utype_fuel(punittype)) {
1606 cat_snprintf(buffer, sizeof(buffer), "(%s)",
1607 move_points_text(punittype->move_rate * utype_fuel(punittype),
1608 TRUE));
1609 }
1610 return buffer;
1611}
1612
1613/**********************************************************************/
1617 const char *utype_values_translation(const struct unit_type *punittype)
1618{
1619 static char buffer[256];
1620
1621 fc_snprintf(buffer, sizeof(buffer),
1622 "%s [%s]",
1623 utype_name_translation(punittype),
1624 utype_values_string(punittype));
1625 return buffer;
1626}
1627
1628/**********************************************************************/
1632 const char *uclass_name_translation(const struct unit_class *pclass)
1633{
1634 return name_translation_get(&pclass->name);
1635}
1636
1637/**********************************************************************/
1641 const char *uclass_rule_name(const struct unit_class *pclass)
1642{
1643 return rule_name_get(&pclass->name);
1644}
1645
1646/**********************************************************************/
1649 bool unit_has_class_flag(const struct unit *punit, enum unit_class_flag_id flag)
1650{
1651 return uclass_has_flag(unit_class_get(punit), flag);
1652}
1653
1654/**********************************************************************/
1657 bool utype_has_class_flag(const struct unit_type *ptype,
1658 enum unit_class_flag_id flag)
1659{
1660 return uclass_has_flag(utype_class(ptype), flag);
1661}
1662
1663/**********************************************************************/
1668 bool role_units_translations(struct astring *astr, int flag, bool alts)
1669{
1670 const int count = num_role_units(flag);
1671
1672 if (4 < count) {
1673 if (alts) {
1674 astr_set(astr, _("%s or similar units"),
1675 utype_name_translation(get_role_unit(flag, 0)));
1676 } else {
1677 astr_set(astr, _("%s and similar units"),
1678 utype_name_translation(get_role_unit(flag, 0)));
1679 }
1680 return TRUE;
1681 } else if (0 < count) {
1682 const char *vec[count];
1683 int i;
1684
1685 for (i = 0; i < count; i++) {
1686 vec[i] = utype_name_translation(get_role_unit(flag, i));
1687 }
1688
1689 if (alts) {
1690 astr_build_or_list(astr, vec, count);
1691 } else {
1692 astr_build_and_list(astr, vec, count);
1693 }
1694 return TRUE;
1695 }
1696 return FALSE;
1697}
1698
1699/**********************************************************************/
1703 const struct unit_type *can_upgrade_unittype(const struct player *pplayer,
1704 const struct unit_type *punittype)
1705{
1706 const struct unit_type *upgrade = punittype;
1707 const struct unit_type *best_upgrade = NULL;
1708
1709 /* For some reason this used to check
1710 * can_player_build_unit_direct() for the unittype
1711 * we're updating from.
1712 * That check is now removed as it prevented legal updates
1713 * of units player had acquired via bribing, capturing,
1714 * diplomatic treaties, or lua script. */
1715
1716 while ((upgrade = upgrade->obsoleted_by) != U_NOT_OBSOLETED) {
1717 if (can_player_build_unit_direct(pplayer, upgrade, TRUE)) {
1718 best_upgrade = upgrade;
1719 }
1720 }
1721
1722 return best_upgrade;
1723}
1724
1725/**********************************************************************/
1731 int unit_upgrade_price(const struct player *pplayer,
1732 const struct unit_type *from,
1733 const struct unit_type *to)
1734{
1735 /* Upgrade price is only paid for "Upgrade Unit" so it is safe to hard
1736 * code the action ID for now. paction will have to become a parameter
1737 * before generalized actions appears. */
1738 const struct action *paction = action_by_number(ACTION_UPGRADE_UNIT);
1739 int missing = (utype_build_shield_cost_base(to)
1740 - unit_shield_value(NULL, from, paction));
1741 int base_cost = 2 * missing + (missing * missing) / 20;
1742
1743 return base_cost
1744 * (100 + get_player_bonus(pplayer, EFT_UPGRADE_PRICE_PCT))
1745 / 100;
1746}
1747
1748/**********************************************************************/
1752 struct unit_type *unit_type_by_translated_name(const char *name)
1753{
1754 unit_type_iterate(punittype) {
1755 if (0 == strcmp(utype_name_translation(punittype), name)) {
1756 return punittype;
1757 }
1758 } unit_type_iterate_end;
1759
1760 return NULL;
1761}
1762
1763/**********************************************************************/
1767 struct unit_type *unit_type_by_rule_name(const char *name)
1768{
1769 const char *qname = Qn_(name);
1770
1771 unit_type_iterate(punittype) {
1772 if (0 == fc_strcasecmp(utype_rule_name(punittype), qname)) {
1773 return punittype;
1774 }
1775 } unit_type_iterate_end;
1776
1777 return NULL;
1778}
1779
1780/**********************************************************************/
1784 struct unit_class *unit_class_by_rule_name(const char *s)
1785{
1786 const char *qs = Qn_(s);
1787
1788 unit_class_iterate(pclass) {
1789 if (0 == fc_strcasecmp(uclass_rule_name(pclass), qs)) {
1790 return pclass;
1791 }
1792 } unit_class_iterate_end;
1793
1794 return NULL;
1795}
1796
1797/**********************************************************************/
1800 void user_unit_class_flags_init(void)
1801{
1802 int i;
1803
1804 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
1805 user_flag_init(&user_class_flags[i]);
1806 }
1807}
1808
1809/**********************************************************************/
1812 void set_user_unit_class_flag_name(enum unit_class_flag_id id,
1813 const char *name,
1814 const char *helptxt)
1815{
1816 int ufid = id - UCF_USER_FLAG_1;
1817
1818 fc_assert_ret(id >= UCF_USER_FLAG_1 && id <= UCF_LAST_USER_FLAG);
1819
1820 if (user_class_flags[ufid].name != NULL) {
1821 FC_FREE(user_class_flags[ufid].name);
1822 user_class_flags[ufid].name = NULL;
1823 }
1824
1825 if (name && name[0] != '\0') {
1826 user_class_flags[ufid].name = fc_strdup(name);
1827 }
1828
1829 if (user_class_flags[ufid].helptxt != NULL) {
1830 free(user_class_flags[ufid].helptxt);
1831 user_class_flags[ufid].helptxt = NULL;
1832 }
1833
1834 if (helptxt && helptxt[0] != '\0') {
1835 user_class_flags[ufid].helptxt = fc_strdup(helptxt);
1836 }
1837}
1838
1839/**********************************************************************/
1842 const char *unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
1843{
1844 if (flag < UCF_USER_FLAG_1 || flag > UCF_LAST_USER_FLAG) {
1845 return NULL;
1846 }
1847
1848 return user_class_flags[flag - UCF_USER_FLAG_1].name;
1849}
1850
1851/**********************************************************************/
1854 const char *unit_class_flag_helptxt(enum unit_class_flag_id id)
1855{
1856 fc_assert(id >= UCF_USER_FLAG_1 && id <= UCF_LAST_USER_FLAG);
1857
1858 return user_class_flags[id - UCF_USER_FLAG_1].helptxt;
1859}
1860
1861/**********************************************************************/
1864 void user_unit_type_flags_init(void)
1865{
1866 int i;
1867
1868 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
1869 user_flag_init(&user_type_flags[i]);
1870 }
1871}
1872
1873/**********************************************************************/
1876 void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name,
1877 const char *helptxt)
1878{
1879 int ufid = id - UTYF_USER_FLAG_1;
1880
1881 fc_assert_ret(id >= UTYF_USER_FLAG_1 && id <= UTYF_LAST_USER_FLAG);
1882
1883 if (user_type_flags[ufid].name != NULL) {
1884 FC_FREE(user_type_flags[ufid].name);
1885 user_type_flags[ufid].name = NULL;
1886 }
1887
1888 if (name && name[0] != '\0') {
1889 user_type_flags[ufid].name = fc_strdup(name);
1890 }
1891
1892 if (user_type_flags[ufid].helptxt != NULL) {
1893 free(user_type_flags[ufid].helptxt);
1894 user_type_flags[ufid].helptxt = NULL;
1895 }
1896
1897 if (helptxt && helptxt[0] != '\0') {
1898 user_type_flags[ufid].helptxt = fc_strdup(helptxt);
1899 }
1900}
1901
1902/**********************************************************************/
1905 const char *unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
1906{
1907 if (flag < UTYF_USER_FLAG_1 || flag > UTYF_LAST_USER_FLAG) {
1908 return NULL;
1909 }
1910
1911 return user_type_flags[flag - UTYF_USER_FLAG_1].name;
1912}
1913
1914/**********************************************************************/
1917 const char *unit_type_flag_helptxt(enum unit_type_flag_id id)
1918{
1919 fc_assert(id >= UTYF_USER_FLAG_1 && id <= UTYF_LAST_USER_FLAG);
1920
1921 return user_type_flags[id - UTYF_USER_FLAG_1].helptxt;
1922}
1923
1924/**********************************************************************/
1927 bool utype_player_already_has_this_unique(const struct player *pplayer,
1928 const struct unit_type *putype)
1929{
1930 if (!utype_has_flag(putype, UTYF_UNIQUE)) {
1931 /* This isn't a unique unit type. */
1932 return FALSE;
1933 }
1934
1935 return utype_player_already_has_this(pplayer, putype);
1936}
1937
1938/**********************************************************************/
1941 bool utype_player_already_has_this(const struct player *pplayer,
1942 const struct unit_type *putype)
1943{
1944 unit_list_iterate(pplayer->units, existing_unit) {
1945 if (putype == unit_type_get(existing_unit)) {
1946 /* FIXME: This could be slow if we have lots of units. We could
1947 * consider keeping an array of unittypes updated with this info
1948 * instead. */
1949
1950 return TRUE;
1951 }
1952 } unit_list_iterate_end;
1953
1954 /* The player doesn't already have one. */
1955 return FALSE;
1956}
1957
1958/**********************************************************************/
1968 bool can_player_build_unit_direct(const struct player *p,
1969 const struct unit_type *punittype,
1970 bool consider_reg_impr_req)
1971{
1972 const struct req_context context = { .player = p, .unittype = punittype };
1973 bool barbarian = is_barbarian(p);
1974
1975 fc_assert_ret_val(NULL != punittype, FALSE);
1976
1977 if (barbarian
1978 && !utype_has_role(punittype, L_BARBARIAN_BUILD)
1979 && !utype_has_role(punittype, L_BARBARIAN_BUILD_TECH)) {
1980 /* Barbarians can build only role units */
1981 return FALSE;
1982 }
1983
1984 if ((utype_can_do_action_result(punittype, ACTRES_NUKE_UNITS)
1985 || utype_can_do_action_result(punittype, ACTRES_NUKE))
1986 && get_player_bonus(p, EFT_ENABLE_NUKE) <= 0) {
1987 return FALSE;
1988 }
1989 if (utype_has_flag(punittype, UTYF_NOBUILD)) {
1990 return FALSE;
1991 }
1992
1993 if (utype_has_flag(punittype, UTYF_BARBARIAN_ONLY)
1994 && !barbarian) {
1995 /* Unit can be built by barbarians only and this player is
1996 * not barbarian */
1997 return FALSE;
1998 }
1999
2000 if (utype_has_flag(punittype, UTYF_NEWCITY_GAMES_ONLY)
2001 && game.scenario.prevent_new_cities) {
2002 /* Unit is usable only in games where founding of new cities is allowed. */
2003 return FALSE;
2004 }
2005
2006 requirement_vector_iterate(&punittype->build_reqs, preq) {
2007 if (preq->source.kind == VUT_IMPROVEMENT
2008 && preq->range == REQ_RANGE_CITY && preq->present) {
2009 /* If the unit has a building requirement, we check to see if the
2010 * player can build that building. Note that individual cities may
2011 * not have that building, so they still may not be able to build the
2012 * unit. */
2013 if (is_great_wonder(preq->source.value.building)
2014 && (great_wonder_is_built(preq->source.value.building)
2015 || great_wonder_is_destroyed(preq->source.value.building))) {
2016 /* It's already built great wonder */
2017 if (great_wonder_owner(preq->source.value.building) != p) {
2018 /* Not owned by this player. Either destroyed or owned by somebody
2019 * else. */
2020 return FALSE;
2021 }
2022 } else if (is_small_wonder(preq->source.value.building)) {
2023 if (!city_from_wonder(p, preq->source.value.building)
2024 && consider_reg_impr_req
2025 && !can_player_build_improvement_direct(p, preq->source.value.building)) {
2026 return FALSE;
2027 }
2028 } else {
2029 if (consider_reg_impr_req
2030 && !can_player_build_improvement_direct(p, preq->source.value.building)) {
2031 return FALSE;
2032 }
2033 }
2034 }
2035
2036 if (preq->range < REQ_RANGE_PLAYER) {
2037 /* The question *here* is if the *player* can build this unit */
2038 continue;
2039 }
2040
2041 if (preq->source.kind == VUT_ADVANCE && barbarian) {
2042 /* Tech requirements do not apply to Barbarians building
2043 * L_BARBARIAN_BUILD units. */
2044 if (!utype_has_role(punittype, L_BARBARIAN_BUILD)) {
2045 /* For L_BARBARIAN_BUILD_TECH the tech requirement must be met at World range
2046 * (i.e. *anyone* must know the tech) */
2047 if (preq->range < REQ_RANGE_WORLD /* If range already World, no need to adjust */
2048 && utype_has_role(punittype, L_BARBARIAN_BUILD_TECH)) {
2049 struct requirement copy;
2050
2051 req_copy(&copy, preq);
2052 copy.range = REQ_RANGE_WORLD;
2053
2054 if (!is_req_active(&context, NULL, &copy, RPT_CERTAIN)) {
2055 return FALSE;
2056 }
2057 } else if (!is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
2058 return FALSE;
2059 }
2060 }
2061 } else if (!is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
2062 return FALSE;
2063 }
2064 } requirement_vector_iterate_end;
2065
2066 if (utype_player_already_has_this_unique(p, punittype)) {
2067 /* A player can only have one unit of each unique unit type. */
2068 return FALSE;
2069 }
2070
2071 return TRUE;
2072}
2073
2074/**********************************************************************/
2078 bool can_player_build_unit_now(const struct player *p,
2079 const struct unit_type *punittype)
2080{
2081 if (!can_player_build_unit_direct(p, punittype, FALSE)) {
2082 return FALSE;
2083 }
2084
2085 while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
2086 if (can_player_build_unit_direct(p, punittype, TRUE)) {
2087 return FALSE;
2088 }
2089 }
2090
2091 return TRUE;
2092}
2093
2094/**********************************************************************/
2099 bool can_player_build_unit_later(const struct player *p,
2100 const struct unit_type *punittype)
2101{
2102 fc_assert_ret_val(NULL != punittype, FALSE);
2103
2104 if (utype_has_flag(punittype, UTYF_NOBUILD)) {
2105 return FALSE;
2106 }
2107
2108 while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
2109 if (can_player_build_unit_direct(p, punittype, TRUE)) {
2110 return FALSE;
2111 }
2112 }
2113
2114 return TRUE;
2115}
2116
2117/**************************************************************************
2118 The following functions use static variables so we can quickly look up
2119 which unit types have given flag or role.
2120 For these functions flags and roles are considered to be in the same "space",
2121 and any "role" argument can also be a "flag".
2122 Unit order is in terms of the order in the units ruleset.
2123**************************************************************************/
2124 static bool first_init = TRUE;
2125 static int n_with_role[MAX_UNIT_ROLES];
2126 static struct unit_type **with_role[MAX_UNIT_ROLES];
2127
2128/**********************************************************************/
2132 static void precalc_one(int i,
2133 bool (*func_has)(const struct unit_type *, int))
2134{
2135 int j;
2136
2137 /* Count: */
2138 fc_assert(n_with_role[i] == 0);
2139 unit_type_iterate(u) {
2140 if (func_has(u, i)) {
2141 n_with_role[i]++;
2142 }
2143 } unit_type_iterate_end;
2144
2145 if (n_with_role[i] > 0) {
2146 with_role[i] = fc_malloc(n_with_role[i] * sizeof(*with_role[i]));
2147 j = 0;
2148 unit_type_iterate(u) {
2149 if (func_has(u, i)) {
2150 with_role[i][j++] = u;
2151 }
2152 } unit_type_iterate_end;
2153 fc_assert(j == n_with_role[i]);
2154 }
2155}
2156
2157/**********************************************************************/
2160 void role_unit_precalcs_free(void)
2161{
2162 int i;
2163
2164 for (i = 0; i < MAX_UNIT_ROLES; i++) {
2165 free(with_role[i]);
2166 with_role[i] = NULL;
2167 n_with_role[i] = 0;
2168 }
2169}
2170
2171/**********************************************************************/
2175 void role_unit_precalcs(void)
2176{
2177 int i;
2178
2179 if (first_init) {
2180 for (i = 0; i < MAX_UNIT_ROLES; i++) {
2181 with_role[i] = NULL;
2182 n_with_role[i] = 0;
2183 }
2184 } else {
2185 role_unit_precalcs_free();
2186 }
2187
2188 for (i = 0; i <= UTYF_LAST_USER_FLAG; i++) {
2189 precalc_one(i, utype_has_flag);
2190 }
2191 for (i = L_FIRST; i < L_LAST; i++) {
2192 precalc_one(i, utype_has_role);
2193 }
2194 for (i = L_LAST; i < MAX_UNIT_ROLES; i++) {
2195 precalc_one(i, utype_can_do_action_role);
2196 }
2197 first_init = FALSE;
2198}
2199
2200/**********************************************************************/
2203 int num_role_units(int role)
2204{
2205 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2206 || (role >= L_FIRST && role < L_LAST)
2207 || (role >= L_LAST && role < MAX_UNIT_ROLES), -1);
2208 fc_assert_ret_val(!first_init, -1);
2209 return n_with_role[role];
2210}
2211
2212/**********************************************************************/
2217 struct unit_type *role_units_iterate(int role, role_unit_callback cb, void *data)
2218{
2219 int i;
2220
2221 for (i = 0; i < n_with_role[role]; i++) {
2222 if (cb(with_role[role][i], data)) {
2223 return with_role[role][i];
2224 }
2225 }
2226
2227 return NULL;
2228}
2229
2230/**********************************************************************/
2236 struct unit_type *role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
2237{
2238 int i;
2239
2240 for (i = n_with_role[role] - 1; i >= 0; i--) {
2241 if (cb(with_role[role][i], data)) {
2242 return with_role[role][i];
2243 }
2244 }
2245
2246 return NULL;
2247}
2248
2249/**********************************************************************/
2253 struct unit_type *get_role_unit(int role, int role_index)
2254{
2255 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2256 || (role >= L_FIRST && role < L_LAST)
2257 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2258 fc_assert_ret_val(!first_init, NULL);
2259 if (role_index == -1) {
2260 role_index = n_with_role[role] - 1;
2261 }
2262 fc_assert_ret_val(role_index >= 0 && role_index < n_with_role[role], NULL);
2263
2264 return with_role[role][role_index];
2265}
2266
2267/**********************************************************************/
2271 struct unit_type *best_role_unit(const struct city *pcity, int role)
2272{
2273 struct unit_type *u;
2274 int j;
2275
2276 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2277 || (role >= L_FIRST && role < L_LAST)
2278 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2279 fc_assert_ret_val(!first_init, NULL);
2280
2281 for (j = n_with_role[role] - 1; j >= 0; j--) {
2282 u = with_role[role][j];
2283 if (can_city_build_unit_now(pcity, u)) {
2284 return u;
2285 }
2286 }
2287
2288 return NULL;
2289}
2290
2291/**********************************************************************/
2297 struct unit_type *best_role_unit_for_player(const struct player *pplayer,
2298 int role)
2299{
2300 int j;
2301
2302 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2303 || (role >= L_FIRST && role < L_LAST)
2304 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2305 fc_assert_ret_val(!first_init, NULL);
2306
2307 for (j = n_with_role[role] - 1; j >= 0; j--) {
2308 struct unit_type *utype = with_role[role][j];
2309
2310 if (can_player_build_unit_now(pplayer, utype)) {
2311 return utype;
2312 }
2313 }
2314
2315 return NULL;
2316}
2317
2318/**********************************************************************/
2322 struct unit_type *first_role_unit_for_player(const struct player *pplayer,
2323 int role)
2324{
2325 int j;
2326
2327 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2328 || (role >= L_FIRST && role < L_LAST)
2329 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2330 fc_assert_ret_val(!first_init, NULL);
2331
2332 for (j = 0; j < n_with_role[role]; j++) {
2333 struct unit_type *utype = with_role[role][j];
2334
2335 if (can_player_build_unit_now(pplayer, utype)) {
2336 return utype;
2337 }
2338 }
2339
2340 return NULL;
2341}
2342
2343/**********************************************************************/
2346 void unit_types_init(void)
2347{
2348 int i;
2349
2350 /* Can't use unit_type_iterate or utype_by_number here because
2351 * num_unit_types isn't known yet. */
2352 for (i = 0; i < ARRAY_SIZE(unit_types); i++) {
2353 unit_types[i].item_number = i;
2354 requirement_vector_init(&(unit_types[i].build_reqs));
2355 unit_types[i].helptext = NULL;
2356 unit_types[i].veteran = NULL;
2357 unit_types[i].bonuses = combat_bonus_list_new();
2358 unit_types[i].ruledit_disabled = FALSE;
2359 unit_types[i].ruledit_dlg = NULL;
2360 }
2361}
2362
2363/**********************************************************************/
2366 static void unit_type_free(struct unit_type *punittype)
2367{
2368 if (NULL != punittype->helptext) {
2369 strvec_destroy(punittype->helptext);
2370 punittype->helptext = NULL;
2371 }
2372
2373 requirement_vector_free(&(punittype->build_reqs));
2374
2375 veteran_system_destroy(punittype->veteran);
2376 combat_bonus_list_iterate(punittype->bonuses, pbonus) {
2377 FC_FREE(pbonus);
2378 } combat_bonus_list_iterate_end;
2379 combat_bonus_list_destroy(punittype->bonuses);
2380}
2381
2382/**********************************************************************/
2385 void unit_types_free(void)
2386{
2387 int i;
2388
2389 /* Can't use unit_type_iterate or utype_by_number here because
2390 * we want to free what unit_types_init() has allocated. */
2391 for (i = 0; i < ARRAY_SIZE(unit_types); i++) {
2392 unit_type_free(unit_types + i);
2393 }
2394}
2395
2396/**********************************************************************/
2399 void unit_type_flags_free(void)
2400{
2401 int i;
2402
2403 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
2404 user_flag_free(&user_type_flags[i]);
2405 }
2406}
2407
2408/**********************************************************************/
2411 void unit_class_flags_free(void)
2412{
2413 int i;
2414
2415 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
2416 user_flag_free(&user_class_flags[i]);
2417 }
2418}
2419
2420/**********************************************************************/
2423 struct unit_class *unit_class_array_first(void)
2424{
2425 if (game.control.num_unit_classes > 0) {
2426 return unit_classes;
2427 }
2428 return NULL;
2429}
2430
2431/**********************************************************************/
2434 const struct unit_class *unit_class_array_last(void)
2435{
2436 if (game.control.num_unit_classes > 0) {
2437 return &unit_classes[game.control.num_unit_classes - 1];
2438 }
2439 return NULL;
2440}
2441
2442/**********************************************************************/
2445 Unit_Class_id uclass_count(void)
2446{
2447 return game.control.num_unit_classes;
2448}
2449
2450#ifndef uclass_index
2451/**********************************************************************/
2457 Unit_Class_id uclass_index(const struct unit_class *pclass)
2458{
2459 fc_assert_ret_val(pclass, -1);
2460 return pclass - unit_classes;
2461}
2462#endif /* uclass_index */
2463
2464/**********************************************************************/
2467 Unit_Class_id uclass_number(const struct unit_class *pclass)
2468{
2469 fc_assert_ret_val(pclass, -1);
2470 return pclass->item_number;
2471}
2472
2473/**********************************************************************/
2476 struct unit_class *uclass_by_number(const Unit_Class_id id)
2477{
2478 if (id < 0 || id >= game.control.num_unit_classes) {
2479 return NULL;
2480 }
2481 return &unit_classes[id];
2482}
2483
2484#ifndef utype_class
2485/**********************************************************************/
2488struct unit_class *utype_class(const struct unit_type *punittype)
2489{
2490 fc_assert(NULL != punittype->uclass);
2491 return punittype->uclass;
2492}
2493#endif /* utype_class */
2494
2495/**********************************************************************/
2498 struct unit_class *unit_class_get(const struct unit *punit)
2499{
2500 return utype_class(unit_type_get(punit));
2501}
2502
2503/**********************************************************************/
2506 void unit_classes_init(void)
2507{
2508 int i;
2509
2510 /* Can't use unit_class_iterate or uclass_by_number here because
2511 * num_unit_classes isn't known yet. */
2512 for (i = 0; i < ARRAY_SIZE(unit_classes); i++) {
2513 unit_classes[i].item_number = i;
2514 unit_classes[i].cache.refuel_extras = NULL;
2515 unit_classes[i].cache.native_tile_extras = NULL;
2516 unit_classes[i].cache.native_bases = NULL;
2517 unit_classes[i].cache.bonus_roads = NULL;
2518 unit_classes[i].cache.hiding_extras = NULL;
2519 unit_classes[i].cache.subset_movers = NULL;
2520 unit_classes[i].helptext = NULL;
2521 unit_classes[i].ruledit_disabled = FALSE;
2522 }
2523}
2524
2525/**********************************************************************/
2528 void unit_classes_free(void)
2529{
2530 int i;
2531
2532 for (i = 0; i < ARRAY_SIZE(unit_classes); i++) {
2533 if (unit_classes[i].cache.refuel_extras != NULL) {
2534 extra_type_list_destroy(unit_classes[i].cache.refuel_extras);
2535 unit_classes[i].cache.refuel_extras = NULL;
2536 }
2537 if (unit_classes[i].cache.native_tile_extras != NULL) {
2538 extra_type_list_destroy(unit_classes[i].cache.native_tile_extras);
2539 unit_classes[i].cache.native_tile_extras = NULL;
2540 }
2541 if (unit_classes[i].cache.native_bases != NULL) {
2542 extra_type_list_destroy(unit_classes[i].cache.native_bases);
2543 unit_classes[i].cache.native_bases = NULL;
2544 }
2545 if (unit_classes[i].cache.bonus_roads != NULL) {
2546 extra_type_list_destroy(unit_classes[i].cache.bonus_roads);
2547 unit_classes[i].cache.bonus_roads = NULL;
2548 }
2549 if (unit_classes[i].cache.hiding_extras != NULL) {
2550 extra_type_list_destroy(unit_classes[i].cache.hiding_extras);
2551 unit_classes[i].cache.hiding_extras = NULL;
2552 }
2553 if (unit_classes[i].cache.subset_movers != NULL) {
2554 unit_class_list_destroy(unit_classes[i].cache.subset_movers);
2555 }
2556 if (unit_classes[i].helptext != NULL) {
2557 strvec_destroy(unit_classes[i].helptext);
2558 unit_classes[i].helptext = NULL;
2559 }
2560 }
2561}
2562
2563/**********************************************************************/
2566const struct veteran_system *
2567 utype_veteran_system(const struct unit_type *punittype)
2568{
2569 fc_assert_ret_val(punittype != NULL, NULL);
2570
2571 if (punittype->veteran) {
2572 return punittype->veteran;
2573 }
2574
2575 fc_assert_ret_val(game.veteran != NULL, NULL);
2576 return game.veteran;
2577}
2578
2579/**********************************************************************/
2582const struct veteran_level *
2583 utype_veteran_level(const struct unit_type *punittype, int level)
2584{
2585 const struct veteran_system *vsystem = utype_veteran_system(punittype);
2586
2587 fc_assert_ret_val(vsystem != NULL, NULL);
2588 fc_assert_ret_val(vsystem->definitions != NULL, NULL);
2589 fc_assert_ret_val(vsystem->levels > level, NULL);
2590
2591 return (vsystem->definitions + level);
2592}
2593
2594/**********************************************************************/
2598 const char *utype_veteran_name_translation(const struct unit_type *punittype,
2599 int level)
2600{
2601 if (utype_veteran_levels(punittype) <= 1) {
2602 return NULL;
2603 } else {
2604 const struct veteran_level *vlvl = utype_veteran_level(punittype, level);
2605
2606 return name_translation_get(&vlvl->name);
2607 }
2608}
2609
2610/**********************************************************************/
2613 int utype_veteran_levels(const struct unit_type *punittype)
2614{
2615 const struct veteran_system *vsystem = utype_veteran_system(punittype);
2616
2617 fc_assert_ret_val(vsystem != NULL, 1);
2618
2619 return vsystem->levels;
2620}
2621
2622/**********************************************************************/
2626 bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
2627{
2628 int i, initial_power_fact = utype_veteran_level(punittype, 0)->power_fact;
2629 for (i = 1; i < utype_veteran_levels(punittype); i++) {
2630 if (utype_veteran_level(punittype, i)->power_fact > initial_power_fact) {
2631 return TRUE;
2632 }
2633 }
2634 return FALSE;
2635}
2636
2637/**********************************************************************/
2640 struct veteran_system *veteran_system_new(int count)
2641{
2642 struct veteran_system *vsystem;
2643
2644 /* There must be at least one level. */
2645 fc_assert_ret_val(count > 0, NULL);
2646
2647 vsystem = fc_calloc(1, sizeof(*vsystem));
2648 vsystem->levels = count;
2649 vsystem->definitions = fc_calloc(vsystem->levels,
2650 sizeof(*vsystem->definitions));
2651
2652 return vsystem;
2653}
2654
2655/**********************************************************************/
2658 void veteran_system_destroy(struct veteran_system *vsystem)
2659{
2660 if (vsystem) {
2661 if (vsystem->definitions) {
2662 free(vsystem->definitions);
2663 }
2664 free(vsystem);
2665 }
2666}
2667
2668/**********************************************************************/
2671 void veteran_system_definition(struct veteran_system *vsystem, int level,
2672 const char *vlist_name, int vlist_power,
2673 int vlist_move, int vlist_raise,
2674 int vlist_wraise)
2675{
2676 struct veteran_level *vlevel;
2677
2678 fc_assert_ret(vsystem != NULL);
2679 fc_assert_ret(vsystem->levels > level);
2680
2681 vlevel = vsystem->definitions + level;
2682
2683 names_set(&vlevel->name, NULL, vlist_name, NULL);
2684 vlevel->power_fact = vlist_power;
2685 vlevel->move_bonus = vlist_move;
2686 vlevel->base_raise_chance = vlist_raise;
2687 vlevel->work_raise_chance = vlist_wraise;
2688}
2689
2690/**********************************************************************/
2696 struct advance *utype_primary_tech_req(const struct unit_type *ptype)
2697{
2698 unit_tech_reqs_iterate(ptype, padv) {
2699 /* Return the very first! */
2700 return padv;
2701 } unit_tech_reqs_iterate_end;
2702
2703 /* There was no tech requirements */
2704 return advance_by_number(A_NONE);
2705}
2706
2707/**********************************************************************/
2710 bool is_tech_req_for_utype(const struct unit_type *ptype,
2711 struct advance *padv)
2712{
2713 unit_tech_reqs_iterate(ptype, preq) {
2714 if (padv == preq) {
2715 return TRUE;
2716 }
2717 } unit_tech_reqs_iterate_end;
2718
2719 return FALSE;
2720}
2721
2722/**********************************************************************/
2725 void *utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
2726{
2727 return ptype->ais[ai_type_number(ai)];
2728}
2729
2730/**********************************************************************/
2733 void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai,
2734 void *data)
2735{
2736 ptype->ais[ai_type_number(ai)] = data;
2737}
2738
2739/**********************************************************************/
2742 void set_unit_class_caches(struct unit_class *pclass)
2743{
2744 pclass->cache.refuel_extras = extra_type_list_new();
2745 pclass->cache.native_tile_extras = extra_type_list_new();
2746 pclass->cache.native_bases = extra_type_list_new();
2747 pclass->cache.bonus_roads = extra_type_list_new();
2748 pclass->cache.hiding_extras = extra_type_list_new();
2749 pclass->cache.subset_movers = unit_class_list_new();
2750
2751 extra_type_iterate(pextra) {
2752 if (is_native_extra_to_uclass(pextra, pclass)) {
2753 struct road_type *proad = extra_road_get(pextra);
2754
2755 if (extra_has_flag(pextra, EF_REFUEL)) {
2756 extra_type_list_append(pclass->cache.refuel_extras, pextra);
2757 }
2758 if (extra_has_flag(pextra, EF_NATIVE_TILE)) {
2759 extra_type_list_append(pclass->cache.native_tile_extras, pextra);
2760 }
2761 if (is_extra_caused_by(pextra, EC_BASE)) {
2762 extra_type_list_append(pclass->cache.native_bases, pextra);
2763 }
2764 if (proad != NULL && road_provides_move_bonus(proad)) {
2765 extra_type_list_append(pclass->cache.bonus_roads, pextra);
2766 }
2767 if (pextra->eus == EUS_HIDDEN) {
2768 extra_type_list_append(pclass->cache.hiding_extras, pextra);
2769 }
2770 }
2771 } extra_type_iterate_end;
2772
2773 unit_class_iterate(pcharge) {
2774 bool subset_mover = TRUE;
2775
2776 terrain_type_iterate(pterrain) {
2777 if (BV_ISSET(pterrain->native_to, uclass_index(pcharge))
2778 && !BV_ISSET(pterrain->native_to, uclass_index(pclass))) {
2779 subset_mover = FALSE;
2780 }
2781 } terrain_type_iterate_end;
2782
2783 if (subset_mover) {
2784 extra_type_iterate(pextra) {
2785 if (is_native_extra_to_uclass(pextra, pcharge)
2786 && !is_native_extra_to_uclass(pextra, pclass)) {
2787 subset_mover = FALSE;
2788 }
2789 } extra_type_list_iterate_end;
2790 }
2791
2792 if (subset_mover) {
2793 unit_class_list_append(pclass->cache.subset_movers, pcharge);
2794 }
2795 } unit_class_iterate_end;
2796}
2797
2798/**********************************************************************/
2801 void set_unit_type_caches(struct unit_type *ptype)
2802{
2803 ptype->cache.max_defense_mp_bonus_pct = -FC_INFINITY;
2804
2805 unit_type_iterate(utype) {
2806 int idx = utype_index(utype);
2807 int bonus = combat_bonus_against(
2808 ptype->bonuses, utype, CBONUS_DEFENSE_MULTIPLIER_PCT)
2809 + 100 * combat_bonus_against(ptype->bonuses, utype,
2810 CBONUS_DEFENSE_MULTIPLIER);
2811 int scramble_bonus =
2812 combat_bonus_against(ptype->bonuses, utype,
2813 CBONUS_SCRAMBLES_PCT);
2814
2815 ptype->cache.defense_mp_bonuses_pct[idx] = bonus;
2816 /* max value is for city defenders, so it considers scrambling */
2817 /* FIXME: if the unit's fuel != 1, scrambling is not so useful */
2818 if (scramble_bonus) {
2819 /* Guess about city defense effect value */
2820 struct universal u
2821 = { .kind = VUT_UTYPE, .value = {.utype = utype} };
2822 int emax = effect_cumulative_max(EFT_DEFEND_BONUS, &u, 1);
2823
2824 emax = CLIP(0, emax, 300); /* Likely sth wrong if more */
2825 emax -= emax >> 2; /* Might be no such building yet */
2826 bonus
2827 = (ptype->cache.scramble_coeff[idx]
2828 = (bonus + 100) * (scramble_bonus + 100)
2829 ) / (100 + emax) - 100;
2830 bonus = MAX(bonus, 1); /* to look better in assess_danger() */
2831 } else {
2832 ptype->cache.scramble_coeff[idx] = 0;
2833 }
2834 if (bonus > ptype->cache.max_defense_mp_bonus_pct) {
2835 ptype->cache.max_defense_mp_bonus_pct = bonus;
2836 }
2837 } unit_type_iterate_end;
2838}
2839
2840/**********************************************************************/
2843 static enum unit_move_type move_type_from_extra(struct extra_type *pextra,
2844 struct unit_class *puc)
2845{
2846 bool land_allowed = TRUE;
2847 bool sea_allowed = TRUE;
2848
2849 if (!extra_has_flag(pextra, EF_NATIVE_TILE)) {
2850 return unit_move_type_invalid();
2851 }
2852 if (!is_native_extra_to_uclass(pextra, puc)) {
2853 return unit_move_type_invalid();
2854 }
2855
2856 if (is_extra_caused_by(pextra, EC_ROAD)
2857 && road_has_flag(extra_road_get(pextra), RF_RIVER)) {
2858 /* Natural rivers are created to land only */
2859 sea_allowed = FALSE;
2860 }
2861
2862 requirement_vector_iterate(&pextra->reqs, preq) {
2863 if (preq->source.kind == VUT_TERRAINCLASS) {
2864 if (!preq->present) {
2865 if (preq->source.value.terrainclass == TC_LAND) {
2866 land_allowed = FALSE;
2867 } else if (preq->source.value.terrainclass == TC_OCEAN) {
2868 sea_allowed = FALSE;
2869 }
2870 } else {
2871 if (preq->source.value.terrainclass == TC_LAND) {
2872 sea_allowed = FALSE;
2873 } else if (preq->source.value.terrainclass == TC_OCEAN) {
2874 land_allowed = FALSE;
2875 }
2876 }
2877 } else if (preq->source.kind == VUT_TERRAIN) {
2878 if (!preq->present) {
2879 if (preq->source.value.terrain->tclass == TC_LAND) {
2880 land_allowed = FALSE;
2881 } else if (preq->source.value.terrain->tclass == TC_OCEAN) {
2882 sea_allowed = FALSE;
2883 }
2884 } else {
2885 if (preq->source.value.terrain->tclass == TC_LAND) {
2886 sea_allowed = FALSE;
2887 } else if (preq->source.value.terrain->tclass == TC_OCEAN) {
2888 land_allowed = FALSE;
2889 }
2890 }
2891 }
2892 } requirement_vector_iterate_end;
2893
2894 if (land_allowed && sea_allowed) {
2895 return UMT_BOTH;
2896 }
2897 if (land_allowed && !sea_allowed) {
2898 return UMT_LAND;
2899 }
2900 if (!land_allowed && sea_allowed) {
2901 return UMT_SEA;
2902 }
2903
2904 return unit_move_type_invalid();
2905}
2906
2907/**********************************************************************/
2910 void set_unit_move_type(struct unit_class *puclass)
2911{
2912 bool land_moving = FALSE;
2913 bool sea_moving = FALSE;
2914
2915 extra_type_iterate(pextra) {
2916 enum unit_move_type eut = move_type_from_extra(pextra, puclass);
2917
2918 if (eut == UMT_BOTH) {
2919 land_moving = TRUE;
2920 sea_moving = TRUE;
2921 } else if (eut == UMT_LAND) {
2922 land_moving = TRUE;
2923 } else if (eut == UMT_SEA) {
2924 sea_moving = TRUE;
2925 }
2926 } extra_type_iterate_end;
2927
2928 terrain_type_iterate(pterrain) {
2929 if (is_native_to_class(puclass, pterrain, NULL)) {
2930 if (is_ocean(pterrain)) {
2931 sea_moving = TRUE;
2932 } else {
2933 land_moving = TRUE;
2934 }
2935 }
2936 } terrain_type_iterate_end;
2937
2938 if (land_moving && sea_moving) {
2939 puclass->move_type = UMT_BOTH;
2940 } else if (sea_moving) {
2941 puclass->move_type = UMT_SEA;
2942 } else {
2943 /* If unit has no native terrains, it is considered land moving */
2944 puclass->move_type = UMT_LAND;
2945 }
2946}
2947
2948/**********************************************************************/
2951 bool utype_is_cityfounder(const struct unit_type *utype)
2952{
2953 if (game.scenario.prevent_new_cities) {
2954 /* No unit is allowed to found new cities */
2955 return FALSE;
2956 }
2957
2958 return utype_can_do_action_result(utype, ACTRES_FOUND_CITY);
2959}
2960
2961/**********************************************************************/
2967 bool uclass_flag_is_in_use(enum unit_class_flag_id ucflag)
2968{
2969 unit_class_iterate(uclass) {
2970 if (uclass_has_flag(uclass, ucflag)) {
2971 /* Found a user. */
2972 return TRUE;
2973 }
2974 } unit_class_iterate_end;
2975
2976 /* No users detected. */
2977 return FALSE;
2978}
2979
2980/**********************************************************************/
2986 bool utype_flag_is_in_use(enum unit_type_flag_id uflag)
2987{
2988 unit_type_iterate(putype) {
2989 if (utype_has_flag(putype, uflag)) {
2990 /* Found a user. */
2991 return TRUE;
2992 }
2993 } unit_type_iterate_end;
2994
2995 /* No users detected. */
2996 return FALSE;
2997}
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1850
action_actor_utype_hard_reqs_ok
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3347
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1968
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1820
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1860
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2306
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:479
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:517
enabler_get_action
#define enabler_get_action(_enabler_)
Definition actions.h:431
enabler_get_action_id
#define enabler_get_action_id(_enabler_)
Definition actions.h:432
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:429
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:439
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:483
action_iterate_end
#define action_iterate_end
Definition actions.h:463
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:646
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:511
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:437
action_id
#define action_id(_act_)
Definition actions.h:659
action_iterate
#define action_iterate(_act_)
Definition actions.h:459
ACTION_ANY
#define ACTION_ANY
Definition actions.h:306
actres_removes_extra
bool actres_removes_extra(enum action_result result, const struct extra_type *pextra)
Definition actres.c:806
actres_creates_extra
bool actres_creates_extra(enum action_result result, const struct extra_type *pextra)
Definition actres.c:785
actres_is_hostile
bool actres_is_hostile(enum action_result result)
Definition actres.c:286
ai_type_number
int ai_type_number(const struct ai_type *ai)
Definition ai.c:278
ai.h
astr_build_or_list
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:329
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
astr_build_and_list
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:367
astring.h
BV_DEFINE
#define BV_DEFINE(name, bits)
Definition bitvector.h:132
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_CLR
#define BV_CLR(bv, bit)
Definition bitvector.h:86
get_output_type
struct output_type * get_output_type(Output_type_id output)
Definition city.c:637
can_city_build_unit_now
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Definition city.c:945
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_owner
#define city_owner(_pcity_)
Definition city.h:563
combat_bonus_against
int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, enum combat_bonus_type type)
Definition combat.c:1000
combat.h
incite_cost
char * incite_cost
Definition comments.c:74
base
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2931
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
id
int int id
Definition editgui_g.h:28
effect_universals_value_never_below
bool effect_universals_value_never_below(enum effect_type type, struct universal *unis, size_t n_unis, int min_value)
Definition effects.c:545
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
effect_cumulative_max
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:388
get_unittype_bonus
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:1035
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
extra_has_flag
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:861
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_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:203
extra_type_list_iterate_end
#define extra_type_list_iterate_end
Definition extras.h:167
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:191
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:704
Unit_Class_id
int Unit_Class_id
Definition fc_types.h:421
action_id
int action_id
Definition fc_types.h:392
Unit_type_id
int Unit_type_id
Definition fc_types.h:385
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_GOLD
@ O_GOLD
Definition fc_types.h:101
UCL_LAST
#define UCL_LAST
Definition fc_types.h:420
Output_type_id
enum output_type_id Output_type_id
Definition fc_types.h:381
fcintl.h
_
#define _(String)
Definition fcintl.h:67
Qn_
#define Qn_(String)
Definition fcintl.h:89
user_flag_init
void user_flag_init(struct user_flag *flag)
Definition game.c:822
user_flag_free
void user_flag_free(struct user_flag *flag)
Definition game.c:831
game
struct civ_game game
Definition game.c:62
game.h
government.h
owner
struct city * owner
Definition citydlg.c:220
can_player_build_improvement_direct
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
Definition improvement.c:664
great_wonder_is_built
bool great_wonder_is_built(const struct impr_type *pimprove)
Definition improvement.c:982
great_wonder_is_destroyed
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
Definition improvement.c:993
city_from_wonder
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:891
is_great_wonder
bool is_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:772
is_small_wonder
bool is_small_wonder(const struct impr_type *pimprove)
Definition improvement.c:780
great_wonder_owner
struct player * great_wonder_owner(const struct impr_type *pimprove)
Definition improvement.c:1048
name
const char * name
Definition inputfile.c:127
log.h
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
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
map_move_cost
static int map_move_cost(const struct civ_map *nmap, const struct player *pplayer, const struct unit_type *punittype, const struct tile *src_tile, const struct tile *dst_tile)
Definition map.h:305
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
move_points_text
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1015
is_native_to_class
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
Definition movement.c:342
movement.h
MAX_MOVE_FRAGS
#define MAX_MOVE_FRAGS
Definition movement.h:29
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
name_translation_get
static const char * name_translation_get(const struct name_translation *ptrans)
Definition name_translation.h:121
names_set
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
Definition name_translation.h:60
player.h
is_barbarian
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
is_req_in_vec
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:5825
is_req_active
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
Definition requirements.c:5416
does_req_contradicts_reqs
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:1845
req_copy
void req_copy(struct requirement *dst, const struct requirement *src)
Definition requirements.c:1437
requirement_fulfilled_by_unit_type
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition requirements.h:426
requirement_diplrel_ereq
#define requirement_diplrel_ereq(_id_, _range_, _present_)
Definition requirements.h:449
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
research.h
road_has_flag
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
road_provides_move_bonus
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:499
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
shared.h
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:71
string_vector.h
action
Definition actions.h:360
action::result
enum action_result result
Definition actions.h:363
advance
Definition tech.h:124
ai_type
Definition ai.h:50
astring
Definition astring.h:36
city
Definition city.h:320
city::tile
struct tile * tile
Definition city.h:322
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::scenario
struct packet_scenario_info scenario
Definition game.h:87
civ_game::veteran
struct veteran_system * veteran
Definition game.h:101
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:88
extra_type::reqs
struct requirement_vector reqs
Definition extras.h:106
packet_game_info::shieldbox
int shieldbox
Definition packets_gen.h:221
packet_ruleset_control::num_unit_types
int num_unit_types
Definition packets_gen.h:1450
packet_ruleset_control::num_unit_classes
int num_unit_classes
Definition packets_gen.h:1449
packet_scenario_info::prevent_new_cities
bool prevent_new_cities
Definition packets_gen.h:1610
player
Definition player.h:247
player::units
struct unit_list * units
Definition player.h:280
range
Definition unittype.c:879
range::max
int max
Definition unittype.c:881
range::min
int min
Definition unittype.c:880
req_context
Definition requirements.h:100
req_context::player
const struct player * player
Definition requirements.h:101
requirement
Definition requirements.h:81
requirement::survives
bool survives
Definition requirements.h:84
requirement::present
bool present
Definition requirements.h:85
requirement::range
enum req_range range
Definition requirements.h:83
requirement::source
struct universal source
Definition requirements.h:82
road_type
Definition road.h:71
tile
Definition tile.h:50
unit_class
Definition unittype.h:149
unit_class::item_number
Unit_Class_id item_number
Definition unittype.h:150
unit_class::subset_movers
struct unit_class_list * subset_movers
Definition unittype.h:173
unit_class::refuel_extras
struct extra_type_list * refuel_extras
Definition unittype.h:168
unit_class::native_tile_extras
struct extra_type_list * native_tile_extras
Definition unittype.h:169
unit_class::cache
struct unit_class::@86 cache
unit_class::native_bases
struct extra_type_list * native_bases
Definition unittype.h:170
unit_class::bonus_roads
struct extra_type_list * bonus_roads
Definition unittype.h:171
unit_class::helptext
struct strvec * helptext
Definition unittype.h:159
unit_class::ruledit_disabled
bool ruledit_disabled
Definition unittype.h:152
unit_class::hiding_extras
struct extra_type_list * hiding_extras
Definition unittype.h:172
unit_type
Definition unittype.h:500
unit_type::pop_cost
int pop_cost
Definition unittype.h:513
unit_type::build_reqs
struct requirement_vector build_reqs
Definition unittype.h:520
unit_type::item_number
Unit_type_id item_number
Definition unittype.h:501
unit_type::veteran
struct veteran_system * veteran
Definition unittype.h:544
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:529
unit_type::helptext
struct strvec * helptext
Definition unittype.h:571
unit_type::upkeep
int upkeep[O_LAST]
Definition unittype.h:538
unit_type::ruledit_disabled
bool ruledit_disabled
Definition unittype.h:503
unit_type::bonuses
struct combat_bonus_list * bonuses
Definition unittype.h:526
unit_type::ruledit_dlg
void * ruledit_dlg
Definition unittype.h:504
unit
Definition unit.h:138
unit::utype
const struct unit_type * utype
Definition unit.h:139
universal
Definition fc_types.h:901
universal::kind
enum universals_n kind
Definition fc_types.h:903
universal::value
universals_u value
Definition fc_types.h:902
user_flag
Definition game.h:73
user_flag::name
char * name
Definition game.h:74
user_flag::helptxt
char * helptxt
Definition game.h:75
veteran_level
Definition unittype.h:486
veteran_level::power_fact
int power_fact
Definition unittype.h:488
veteran_system
Definition unittype.h:494
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
A_NONE
#define A_NONE
Definition tech.h:43
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:373
is_ocean
#define is_ocean(pterrain)
Definition terrain.h:301
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:379
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
universals_u::diplrel
int diplrel
Definition fc_types.h:750
universals_u::citytile
enum citytile_type citytile
Definition fc_types.h:733
universals_u::unit_state
enum ustate_prop unit_state
Definition fc_types.h:752
unit_shield_value
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:217
unit_owner
#define unit_owner(_pu)
Definition unit.h:389
unitlist.h
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
utype_may_act_tgt_city_tile
bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1124
utype_buy_gold_cost
int utype_buy_gold_cost(const struct city *pcity, const struct unit_type *punittype, int shields_in_stock)
Definition unittype.c:1492
unit_types_init
void unit_types_init(void)
Definition unittype.c:2346
can_unit_act_when_ustate_is
bool can_unit_act_when_ustate_is(const struct unit_type *punit_type, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:943
uclass_name_translation
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1632
set_unit_class_caches
void set_unit_class_caches(struct unit_class *pclass)
Definition unittype.c:2742
best_role_unit
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2271
unit_types
static struct unit_type unit_types[U_LAST]
Definition unittype.c:44
role_units_iterate
struct unit_type * role_units_iterate(int role, role_unit_callback cb, void *data)
Definition unittype.c:2217
utype_action_takes_all_mp
bool utype_action_takes_all_mp(const struct unit_type *putype, struct action *paction)
Definition unittype.c:1191
utype_veteran_name_translation
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2598
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
utype_has_class_flag
bool utype_has_class_flag(const struct unit_type *ptype, enum unit_class_flag_id flag)
Definition unittype.c:1657
user_unit_type_flags_init
void user_unit_type_flags_init(void)
Definition unittype.c:1864
utype_pays_mp_for_action_base
int utype_pays_mp_for_action_base(const struct action *paction, const struct unit_type *putype)
Definition unittype.c:1381
utype_player_already_has_this
bool utype_player_already_has_this(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1941
moves_left_range
static struct range * moves_left_range(struct requirement_vector *reqs)
Definition unittype.c:890
utype_can_freely_unload
bool utype_can_freely_unload(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:300
ACTION_HOSTILE
#define ACTION_HOSTILE
Definition unittype.c:308
unit_class_flag_helptxt
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1854
utype_pays_for_regular_move_to_tgt
bool utype_pays_for_regular_move_to_tgt(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1330
unit_type_free
static void unit_type_free(struct unit_type *punittype)
Definition unittype.c:2366
role_units_iterate_backwards
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Definition unittype.c:2236
precalc_one
static void precalc_one(int i, bool(*func_has)(const struct unit_type *, int))
Definition unittype.c:2132
user_class_flags
static struct user_flag user_class_flags[MAX_NUM_USER_UCLASS_FLAGS]
Definition unittype.c:53
dipl_rel_action_cache
static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:566
utype_can_remove_extra
bool utype_can_remove_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:241
unit_build_shield_cost
int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
Definition unittype.c:1476
unit_name_translation
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1569
utype_act_takes_all_mp_ustate_cache
static bv_unit_types utype_act_takes_all_mp_ustate_cache[ACTION_COUNT][USP_COUNT]
Definition unittype.c:493
unit_has_class_flag
bool unit_has_class_flag(const struct unit *punit, enum unit_class_flag_id flag)
Definition unittype.c:1649
can_player_build_unit_direct
bool can_player_build_unit_direct(const struct player *p, const struct unit_type *punittype, bool consider_reg_impr_req)
Definition unittype.c:1968
utype_is_moved_to_tgt_by_action
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1249
is_tech_req_for_utype
bool is_tech_req_for_utype(const struct unit_type *ptype, struct advance *padv)
Definition unittype.c:2710
ctile_tgt_act_cache
static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:569
utype_upkeep_cost
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
utype_move_type
enum unit_move_type utype_move_type(const struct unit_type *punittype)
Definition unittype.c:1551
first_role_unit_for_player
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2322
uclass_count
Unit_Class_id uclass_count(void)
Definition unittype.c:2445
utype_is_cityfounder
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2951
unit_class_array_last
const struct unit_class * unit_class_array_last(void)
Definition unittype.c:2434
unit_type_by_rule_name
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1767
get_role_unit
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2253
unit_type_array_first
struct unit_type * unit_type_array_first(void)
Definition unittype.c:58
unit_class_flags_free
void unit_class_flags_free(void)
Definition unittype.c:2411
uclass_flag_is_in_use
bool uclass_flag_is_in_use(enum unit_class_flag_id ucflag)
Definition unittype.c:2967
MAX_UNIT_ROLES
#define MAX_UNIT_ROLES
Definition unittype.c:42
unit_rule_name
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
utype_has_role
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:199
move_type_from_extra
static enum unit_move_type move_type_from_extra(struct extra_type *pextra, struct unit_class *puc)
Definition unittype.c:2843
set_unit_move_type
void set_unit_move_type(struct unit_class *puclass)
Definition unittype.c:2910
dipl_rel_tile_other_tgt_a_cache
static bv_diplrel_all_reqs dipl_rel_tile_other_tgt_a_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:568
unit_type_action_cache_init
void unit_type_action_cache_init(void)
Definition unittype.c:931
local_dipl_rel_tile_other_tgt_action_cache_set
static void local_dipl_rel_tile_other_tgt_action_cache_set(struct unit_type *putype)
Definition unittype.c:734
utype_build_shield_cost_base
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
set_unit_type_caches
void set_unit_type_caches(struct unit_type *ptype)
Definition unittype.c:2801
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_system
const struct veteran_system * utype_veteran_system(const struct unit_type *punittype)
Definition unittype.c:2567
utype_is_consumed_by_action_result
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Definition unittype.c:1229
num_role_units
int num_role_units(int role)
Definition unittype.c:2203
first_init
static bool first_init
Definition unittype.c:2124
utype_player_already_has_this_unique
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1927
utype_act_takes_all_mp_cache
static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT]
Definition unittype.c:451
utype_can_do_action_role
static bool utype_can_do_action_role(const struct unit_type *putype, const int role)
Definition unittype.c:433
unit_types_free
void unit_types_free(void)
Definition unittype.c:2385
utype_may_act_at_all
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:359
unit_build_shield_cost_base
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484
can_upgrade_unittype
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1703
best_role_unit_for_player
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2297
role_unit_precalcs
void role_unit_precalcs(void)
Definition unittype.c:2175
uclass_by_number
struct unit_class * uclass_by_number(const Unit_Class_id id)
Definition unittype.c:2476
utype_can_create_extra
bool utype_can_create_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:217
local_dipl_rel_action_cache_set
static void local_dipl_rel_action_cache_set(struct unit_type *putype)
Definition unittype.c:649
tgt_citytile_act_cache_set
static void tgt_citytile_act_cache_set(struct unit_type *putype)
Definition unittype.c:811
utype_primary_tech_req
struct advance * utype_primary_tech_req(const struct unit_type *ptype)
Definition unittype.c:2696
utype_can_freely_load
bool utype_can_freely_load(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:288
veteran_system_definition
void veteran_system_definition(struct veteran_system *vsystem, int level, const char *vlist_name, int vlist_power, int vlist_move, int vlist_raise, int vlist_wraise)
Definition unittype.c:2671
MOVES_LEFT_INFINITY
#define MOVES_LEFT_INFINITY
Definition unittype.c:884
requirement_citytile_ereq
#define requirement_citytile_ereq(_id_, _present_)
Definition unittype.c:561
utype_count
Unit_type_id utype_count(void)
Definition unittype.c:80
unit_state_action_cache_set
static void unit_state_action_cache_set(struct unit_type *putype)
Definition unittype.c:576
ustate_act_cache
static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:565
utype_veteran_levels
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2613
utype_pays_mp_for_action_estimate
int utype_pays_mp_for_action_estimate(const struct civ_map *nmap, const struct action *paction, const struct unit_type *putype, const struct player *act_player, const struct tile *act_tile, const struct tile *tgt_tile)
Definition unittype.c:1393
utype_can_do_act_when_ustate
bool utype_can_do_act_when_ustate(const struct unit_type *punit_type, const action_id act_id, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:955
veteran_system_destroy
void veteran_system_destroy(struct veteran_system *vsystem)
Definition unittype.c:2658
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
unit_class_get
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2498
utype_can_do_action_result_when_ustate
bool utype_can_do_action_result_when_ustate(const struct unit_type *putype, enum action_result result, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:975
utype_by_number
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
utype_can_do_action_result
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:387
unit_has_type_role
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:208
unit_can_act_cache_set
static void unit_can_act_cache_set(struct unit_type *putype)
Definition unittype.c:323
utype_action_takes_all_mp_if_ustate_is
bool utype_action_takes_all_mp_if_ustate_is(const struct unit_type *putype, struct action *paction, const enum ustate_prop prop)
Definition unittype.c:1207
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
unit_can_take_over
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:264
unit_can_act_cache
static bv_unit_types unit_can_act_cache[ACTION_AND_FAKES]
Definition unittype.c:317
unit_classes_free
void unit_classes_free(void)
Definition unittype.c:2528
unit_type_action_cache_set
void unit_type_action_cache_set(struct unit_type *ptype)
Definition unittype.c:915
uclass_rule_name
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1641
unit_class_flag_id_name_cb
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1842
utype_is_consumed_by_action
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1219
unit_type_flags_free
void unit_type_flags_free(void)
Definition unittype.c:2399
utype_act_takes_all_mp_cache_set
static void utype_act_takes_all_mp_cache_set(struct unit_type *putype)
Definition unittype.c:457
utype_act_takes_all_mp_ustate_cache_set
static void utype_act_takes_all_mp_ustate_cache_set(struct unit_type *putype)
Definition unittype.c:500
utype_number
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
unit_type_flag_id_name_cb
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1905
utype_veteran_has_power_bonus
bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
Definition unittype.c:2626
user_unit_class_flags_init
void user_unit_class_flags_init(void)
Definition unittype.c:1800
utype_can_act_if_tgt_diplrel_tile_other
bool utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1036
unit_class_by_rule_name
struct unit_class * unit_class_by_rule_name(const char *s)
Definition unittype.c:1784
unit_type_by_translated_name
struct unit_type * unit_type_by_translated_name(const char *name)
Definition unittype.c:1752
unit_type_flag_helptxt
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1917
utype_values_string
const char * utype_values_string(const struct unit_type *punittype)
Definition unittype.c:1596
utype_ai_data
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2725
unit_class_array_first
struct unit_class * unit_class_array_first(void)
Definition unittype.c:2423
utype_index
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
unit_classes_init
void unit_classes_init(void)
Definition unittype.c:2506
utype_flag_is_in_use
bool utype_flag_is_in_use(enum unit_type_flag_id uflag)
Definition unittype.c:2986
ACTION_AND_FAKES
#define ACTION_AND_FAKES
Definition unittype.c:311
user_type_flags
static struct user_flag user_type_flags[MAX_NUM_USER_UNIT_FLAGS]
Definition unittype.c:51
utype_pop_value
int utype_pop_value(const struct unit_type *punittype, const struct city *pcity)
Definition unittype.c:1528
utype_can_take_over
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:276
utype_set_ai_data
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2733
set_user_unit_class_flag_name
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1812
can_player_build_unit_later
bool can_player_build_unit_later(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2099
unit_classes
static struct unit_class unit_classes[UCL_LAST]
Definition unittype.c:45
utype_build_shield_cost
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
unit_pop_value
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1543
requirement_unit_state_ereq
#define requirement_unit_state_ereq(_id_, _present_)
Definition unittype.c:559
role_unit_precalcs_free
void role_unit_precalcs_free(void)
Definition unittype.c:2160
veteran_system_new
struct veteran_system * veteran_system_new(int count)
Definition unittype.c:2640
uclass_number
Unit_Class_id uclass_number(const struct unit_class *pclass)
Definition unittype.c:2467
can_player_build_unit_now
bool can_player_build_unit_now(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2078
utype_can_do_action_sub_result
bool utype_can_do_action_sub_result(const struct unit_type *putype, enum action_sub_result sub_result)
Definition unittype.c:408
with_role
static struct unit_type ** with_role[MAX_UNIT_ROLES]
Definition unittype.c:2126
utype_is_unmoved_by_action
bool utype_is_unmoved_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1288
utype_acts_hostile
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:443
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_name_translation
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
n_with_role
static int n_with_role[MAX_UNIT_ROLES]
Definition unittype.c:2125
can_utype_do_act_if_tgt_diplrel
bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1017
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
set_user_unit_type_flag_name
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1876
utype_happy_cost
int utype_happy_cost(const struct unit_type *ut, const struct player *pplayer)
Definition unittype.c:181
role_units_translations
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1668
utype_values_translation
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1617
unit_type_array_last
const struct unit_type * unit_type_array_last(void)
Definition unittype.c:69
unit_upgrade_price
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1731
unittype.h
UCF_LAST_USER_FLAG
#define UCF_LAST_USER_FLAG
Definition unittype.h:127
uclass_has_flag
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
utype_class
#define utype_class(_t_)
Definition unittype.h:749
utype_fuel
#define utype_fuel(ptype)
Definition unittype.h:836
combat_bonus_list_iterate_end
#define combat_bonus_list_iterate_end
Definition unittype.h:482
L_FIRST
#define L_FIRST
Definition unittype.h:349
combat_bonus_list_iterate
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:480
unit_tech_reqs_iterate_end
#define unit_tech_reqs_iterate_end
Definition unittype.h:878
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:905
unit_tech_reqs_iterate
#define unit_tech_reqs_iterate(_utype_, _p)
Definition unittype.h:872
MAX_NUM_USER_UNIT_FLAGS
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:332
utype_has_flag
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
UTYF_LAST_USER_FLAG
#define UTYF_LAST_USER_FLAG
Definition unittype.h:331
L_LAST
#define L_LAST
Definition unittype.h:439
role_unit_callback
bool(* role_unit_callback)(struct unit_type *ptype, void *data)
Definition unittype.h:722
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:852
U_LAST
#define U_LAST
Definition unittype.h:40
uclass_index
#define uclass_index(_c_)
Definition unittype.h:742
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:912
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:859
MAX_NUM_USER_UCLASS_FLAGS
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:128
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:528