Freeciv-3.1
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
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
52
54
55/**********************************************************************/
59{
60 if (game.control.num_unit_types > 0) {
61 return unit_types;
62 }
63 return NULL;
64}
65
66/**********************************************************************/
70{
71 if (game.control.num_unit_types > 0) {
73 }
74 return NULL;
75}
76
77/**********************************************************************/
84
85/**********************************************************************/
91Unit_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/**********************************************************************/
100Unit_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/**********************************************************************/
113{
114 if (id < 0 || id >= game.control.num_unit_types) {
115 return NULL;
116 }
117 return &unit_types[id];
118}
119
120/**********************************************************************/
123const 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/**********************************************************************/
132int 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_player_output_bonus(pplayer, get_output_type(otype),
167 EFT_UPKEEP_FACTOR);
168 return val;
169}
170
171/**********************************************************************/
175int utype_happy_cost(const struct unit_type *ut,
176 const struct player *pplayer)
177{
178 return ut->happy_cost * get_player_bonus(pplayer, EFT_UNHAPPY_FACTOR);
179}
180
181/**********************************************************************/
184bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
185{
186 return utype_has_flag(unit_type_get(punit), flag);
187}
188
189/**********************************************************************/
193bool utype_has_role(const struct unit_type *punittype, int role)
194{
195 fc_assert_ret_val(role >= L_FIRST && role < L_LAST, FALSE);
196 return BV_ISSET(punittype->roles, role - L_FIRST);
197}
198
199/**********************************************************************/
202bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
203{
204 return utype_has_role(unit_type_get(punit), role);
205}
206
207/**********************************************************************/
211bool utype_can_create_extra(const struct unit_type *putype,
212 const struct extra_type *pextra)
213{
214 action_iterate(act_id) {
215 struct action *paction = action_by_number(act_id);
216
217 if (!utype_can_do_action(putype, act_id)) {
218 /* Not relevant. */
219 continue;
220 }
221
222 if (action_creates_extra(paction, pextra)) {
223 /* Can create */
224 return TRUE;
225 }
227
228 return FALSE;
229}
230
231/**********************************************************************/
235bool utype_can_remove_extra(const struct unit_type *putype,
236 const struct extra_type *pextra)
237{
238 action_iterate(act_id) {
239 struct action *paction = action_by_number(act_id);
240
241 if (!utype_can_do_action(putype, act_id)) {
242 /* Not relevant. */
243 continue;
244 }
245
246 if (action_removes_extra(paction, pextra)) {
247 /* Can remove */
248 return TRUE;
249 }
251
252 return FALSE;
253}
254
255/**********************************************************************/
258bool unit_can_take_over(const struct unit *punit)
259{
260 /* TODO: Should unit state dependent action enablers be considered?
261 * Some callers aren't yet ready for changeable unit state (like current
262 * location) playing a role. */
263 return unit_owner(punit)->ai_common.barbarian_type != ANIMAL_BARBARIAN
265}
266
267/**********************************************************************/
270bool utype_can_take_over(const struct unit_type *punittype)
271{
272 /* FIXME: "Paradrop Unit" can in certain circumstances result in city
273 * conquest. */
274 return utype_can_do_action_result(punittype, ACTRES_CONQUER_CITY);
275}
276
277/**********************************************************************/
282bool utype_can_freely_load(const struct unit_type *pcargotype,
283 const struct unit_type *ptranstype)
284{
285 return BV_ISSET(pcargotype->embarks,
286 uclass_index(utype_class(ptranstype)));
287}
288
289/**********************************************************************/
294bool utype_can_freely_unload(const struct unit_type *pcargotype,
295 const struct unit_type *ptranstype)
296{
297 return BV_ISSET(pcargotype->disembarks,
298 uclass_index(utype_class(ptranstype)));
299}
300
301/**********************************************************************/
304static bool action_is_hostile(action_id act_id)
305{
306 struct action *paction = action_by_number(act_id);
307
308 switch (paction->result) {
309 case ACTRES_SPY_INVESTIGATE_CITY:
310 case ACTRES_SPY_POISON:
311 case ACTRES_SPY_STEAL_GOLD:
312 case ACTRES_SPY_SABOTAGE_CITY:
313 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
314 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
315 case ACTRES_SPY_STEAL_TECH:
316 case ACTRES_SPY_TARGETED_STEAL_TECH:
317 case ACTRES_SPY_INCITE_CITY:
318 case ACTRES_SPY_BRIBE_UNIT:
319 case ACTRES_SPY_SABOTAGE_UNIT:
320 case ACTRES_CAPTURE_UNITS:
321 case ACTRES_STEAL_MAPS:
322 case ACTRES_BOMBARD:
323 case ACTRES_SPY_NUKE:
324 case ACTRES_NUKE:
325 case ACTRES_NUKE_UNITS:
326 case ACTRES_DESTROY_CITY:
327 case ACTRES_EXPEL_UNIT:
328 case ACTRES_STRIKE_BUILDING:
329 case ACTRES_STRIKE_PRODUCTION:
330 case ACTRES_ATTACK:
331 case ACTRES_CONQUER_CITY:
332 case ACTRES_PILLAGE:
333 case ACTRES_SPY_ATTACK:
334 case ACTRES_SPY_SPREAD_PLAGUE:
335 case ACTRES_CONQUER_EXTRAS:
336 return TRUE;
337 case ACTRES_ESTABLISH_EMBASSY:
338 case ACTRES_TRADE_ROUTE:
339 case ACTRES_MARKETPLACE:
340 case ACTRES_HELP_WONDER:
341 case ACTRES_FOUND_CITY:
342 case ACTRES_JOIN_CITY:
343 case ACTRES_DISBAND_UNIT_RECOVER:
344 case ACTRES_DISBAND_UNIT:
345 case ACTRES_HOME_CITY:
346 case ACTRES_HOMELESS:
347 case ACTRES_UPGRADE_UNIT:
348 case ACTRES_PARADROP:
349 case ACTRES_PARADROP_CONQUER: /* TODO: should this be hostile? */
350 case ACTRES_AIRLIFT:
351 case ACTRES_HEAL_UNIT:
352 case ACTRES_TRANSFORM_TERRAIN:
353 case ACTRES_CULTIVATE:
354 case ACTRES_PLANT:
355 case ACTRES_CLEAN_POLLUTION:
356 case ACTRES_CLEAN_FALLOUT:
357 case ACTRES_FORTIFY:
358 case ACTRES_ROAD:
359 case ACTRES_CONVERT:
360 case ACTRES_BASE:
361 case ACTRES_MINE:
362 case ACTRES_IRRIGATE:
363 case ACTRES_TRANSPORT_ALIGHT:
364 case ACTRES_TRANSPORT_UNLOAD:
365 case ACTRES_TRANSPORT_DISEMBARK:
366 case ACTRES_TRANSPORT_BOARD:
367 case ACTRES_TRANSPORT_EMBARK:
368 case ACTRES_HUT_ENTER:
369 case ACTRES_HUT_FRIGHTEN:
370 case ACTRES_UNIT_MOVE:
371 return FALSE;
372 case ACTRES_NONE:
373 /* Assume they are up to something. */
374 return TRUE;
375 }
376
377 /* Should not be reached. */
379 return FALSE;
380}
381
382/* Fake action id representing any hostile action. */
383#define ACTION_HOSTILE ACTION_COUNT + 1
384
385/* Number of real and fake actions. */
386#define ACTION_AND_FAKES ACTION_HOSTILE + 1
387
388/* Cache of what generalized (ruleset defined) action enabler controlled
389 * actions units of each type can perform. Checking if any action can be
390 * done at all is done via the fake action id ACTION_ANY. If any hostile
391 * action can be performed is done via ACTION_HOSTILE. */
393
394/**********************************************************************/
398static void unit_can_act_cache_set(struct unit_type *putype)
399{
400 /* Clear old values. */
401 action_iterate(act_id) {
402 BV_CLR(unit_can_act_cache[act_id], utype_index(putype));
406
407 /* See if the unit type can do an action controlled by generalized action
408 * enablers */
409 action_enablers_iterate(enabler) {
410 const struct action *paction = action_by_number(enabler->action);
411 if (action_id_get_actor_kind(enabler->action) == AAK_UNIT
412 && action_actor_utype_hard_reqs_ok(paction, putype)
414 &(enabler->actor_reqs))) {
415 log_debug("act_cache: %s can %s",
416 utype_rule_name(putype),
417 action_id_rule_name(enabler->action));
418 BV_SET(unit_can_act_cache[enabler->action], utype_index(putype));
420 if (action_is_hostile(enabler->action)) {
422 }
423 }
425}
426
427/**********************************************************************/
431bool utype_may_act_at_all(const struct unit_type *putype)
432{
433 return utype_can_do_action(putype, ACTION_ANY);
434}
435
436/**********************************************************************/
443bool utype_can_do_action(const struct unit_type *putype,
444 const action_id act_id)
445{
446 fc_assert_ret_val(putype, FALSE);
447 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
448
449 return BV_ISSET(unit_can_act_cache[act_id], utype_index(putype));
450}
451
452/**********************************************************************/
459bool utype_can_do_action_result(const struct unit_type *putype,
460 enum action_result result)
461{
462 fc_assert_ret_val(putype, FALSE);
463
465 if (utype_can_do_action(putype, paction->id)) {
466 return TRUE;
467 }
469
470 return FALSE;
471}
472
473/**********************************************************************/
481 enum action_sub_result sub_result)
482{
483 fc_assert_ret_val(putype, FALSE);
484
485 action_iterate(act_id) {
486 struct action *paction = action_by_number(act_id);
487
488 if (!BV_ISSET(paction->sub_results, sub_result)) {
489 /* Not relevant */
490 continue;
491 }
492
493 if (utype_can_do_action(putype, paction->id)) {
494 return TRUE;
495 }
497
498 return FALSE;
499}
500
501/**********************************************************************/
505static bool utype_can_do_action_role(const struct unit_type *putype,
506 const int role)
507{
508 return utype_can_do_action(putype, role - L_LAST);
509}
510
511/**********************************************************************/
515bool utype_acts_hostile(const struct unit_type *putype)
516{
517 return utype_can_do_action(putype, ACTION_HOSTILE);
518}
519
520/* Cache of if a generalized (ruleset defined) action enabler controlled
521 * action always spends all remaining movement of a unit of the specified
522 * unit type. */
523static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT];
524
525/**********************************************************************/
530{
531 action_iterate(act_id) {
532 /* See if the unit type has all remaining MP spent by the specified
533 * action. */
534
535 struct action *paction = action_by_number(act_id);
536 struct universal unis[] = {
537 { .kind = VUT_ACTION, .value = {.action = (paction)} },
538 { .kind = VUT_UTYPE, .value = {.utype = (putype)} }
539 };
540
541 if (!utype_can_do_action(putype, paction->id)) {
542 /* Not relevant. */
543 continue;
544 }
545
546 if (effect_universals_value_never_below(EFT_ACTION_SUCCESS_MOVE_COST,
547 unis, ARRAY_SIZE(unis),
549 /* Guaranteed to always consume all remaining MP of an actor unit of
550 * this type. */
551 log_debug("unit_act_takes_all_mp_cache_set: %s takes all MP from %s",
552 utype_rule_name(putype), action_rule_name(paction));
554 } else {
555 /* Clear old value in case it was set. */
557 }
559}
560
561/* Cache of if a generalized (ruleset defined) action enabler controlled
562 * action always spends all remaining movement of a unit of the specified
563 * unit type given the specified unit state property. */
564static bv_unit_types
565utype_act_takes_all_mp_ustate_cache[ACTION_COUNT][USP_COUNT];
566
567/**********************************************************************/
573{
574 action_iterate(act_id) {
575 /* See if the unit type has all remaining MP spent by the specified
576 * action given the specified unit state property. */
577
578 enum ustate_prop prop = ustate_prop_begin();
579 struct action *paction = action_by_number(act_id);
580 struct universal unis[] = {
581 { .kind = VUT_ACTION, .value = {.action = (paction)} },
582 { .kind = VUT_UTYPE, .value = {.utype = (putype)} },
583 { .kind = VUT_UNITSTATE, .value = {.unit_state = (prop)} }
584 };
585
586 if (!utype_can_do_action(putype, paction->id)) {
587 /* Not relevant. */
588 continue;
589 }
590
591 for (prop = ustate_prop_begin(); prop != ustate_prop_end();
592 prop = ustate_prop_next(prop)) {
593 unis[2].value.unit_state = prop;
594 if (effect_universals_value_never_below(EFT_ACTION_SUCCESS_MOVE_COST,
595 unis, ARRAY_SIZE(unis),
597 /* Guaranteed to always consume all remaining MP of an actor unit of
598 * this type given the specified unit state property. */
599 log_debug("unit_act_takes_all_mp_cache_set: %s takes all MP from %s"
600 " when unit state is %s",
601 utype_rule_name(putype), action_rule_name(paction),
602 ustate_prop_name(prop));
604 utype_index(putype));
605 } else {
606 /* Clear old value in case it was set. */
608 utype_index(putype));
609 }
610 }
612}
613
614/* Cache if any action at all may be possible when the actor unit's state
615 * is...
616 * bit 0 to USP_COUNT - 1: Possible when the corresponding property is TRUE
617 * bit USP_COUNT to ((USP_COUNT * 2) - 1): Possible when the corresponding
618 * property is FALSE
619 */
620BV_DEFINE(bv_ustate_act_cache, USP_COUNT * 2);
621
622/* Cache what actions may be possible when the target's local citytile state
623 * is
624 * bit 0 to CITYT_LAST - 1: Possible when the corresponding property is TRUE
625 * bit USP_COUNT to ((CITYT_LAST * 2) - 1): Possible when the corresponding
626 * property is FALSE
627 */
628BV_DEFINE(bv_citytile_cache, CITYT_LAST * 2);
629
630/* Cache position lookup functions */
631#define requirement_unit_state_ereq(_id_, _present_) \
632 requirement_kind_ereq(_id_, REQ_RANGE_LOCAL, _present_, USP_COUNT)
633#define requirement_citytile_ereq(_id_, _present_) \
634 requirement_kind_ereq(_id_, REQ_RANGE_LOCAL, _present_, CITYT_LAST)
635
636/* Caches for each unit type */
637static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES];
638static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES];
639static bv_diplrel_all_reqs
641static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES];
642
643/**********************************************************************/
648static void unit_state_action_cache_set(struct unit_type *putype)
649{
650 struct requirement req;
651 int uidx = utype_index(putype);
652
653 /* The unit is not yet known to be allowed to perform any actions no
654 * matter what its unit state is. */
655 action_iterate(act_id) {
656 BV_CLR_ALL(ustate_act_cache[uidx][act_id]);
660
661 if (!utype_may_act_at_all(putype)) {
662 /* Not an actor unit. */
663 return;
664 }
665
666 /* Common for every situation */
667 req.range = REQ_RANGE_LOCAL;
668 req.survives = FALSE;
669 req.source.kind = VUT_UNITSTATE;
670
671 for (req.source.value.unit_state = ustate_prop_begin();
672 req.source.value.unit_state != ustate_prop_end();
673 req.source.value.unit_state = ustate_prop_next(
674 req.source.value.unit_state)) {
675
676 /* No action will ever be possible in a specific unit state if the
677 * opposite unit state is required in all action enablers.
678 * No unit state except present and !present of the same property
679 * implies or conflicts with another so the tests can be simple. */
680 action_enablers_iterate(enabler) {
682 &(enabler->actor_reqs))
683 && action_id_get_actor_kind(enabler->action) == AAK_UNIT) {
684 bool present = TRUE;
685 do {
686 /* OK if not mentioned */
687 req.present = present;
688 if (!is_req_in_vec(&req, &(enabler->actor_reqs))) {
689 BV_SET(ustate_act_cache[utype_index(putype)][enabler->action],
691 !req.present));
692 if (action_is_hostile(enabler->action)) {
695 !req.present));
696 }
699 !req.present));
700 }
701 present = !present;
702 } while (!present);
703 }
705 }
706}
707
708/**********************************************************************/
717{
718 struct requirement req;
719 struct requirement tile_is_claimed;
720 int uidx = utype_index(putype);
721
722 /* The unit is not yet known to be allowed to perform any actions no
723 * matter what the diplomatic state is. */
724 action_iterate(act_id) {
725 BV_CLR_ALL(dipl_rel_action_cache[uidx][act_id]);
729
730 if (!utype_may_act_at_all(putype)) {
731 /* Not an actor unit. */
732 return;
733 }
734
735 /* Tile is claimed as a requirement. */
736 tile_is_claimed.range = REQ_RANGE_LOCAL;
737 tile_is_claimed.survives = FALSE;
738 tile_is_claimed.source.kind = VUT_CITYTILE;
739 tile_is_claimed.present = TRUE;
740 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
741
742 /* Common for every situation */
743 req.range = REQ_RANGE_LOCAL;
744 req.survives = FALSE;
745 req.source.kind = VUT_DIPLREL;
746
747 /* DiplRel starts with diplstate_type and ends with diplrel_other */
748 for (req.source.value.diplrel = diplstate_type_begin();
749 req.source.value.diplrel != DRO_LAST;
750 req.source.value.diplrel++) {
751
752 /* No action will ever be possible in a specific diplomatic relation if
753 * its presence contradicts all action enablers.
754 * Everything was set to false above. It is therefore OK to only change
755 * the cache when units can do an action given a certain diplomatic
756 * relationship property value. */
757 action_enablers_iterate(enabler) {
759 &(enabler->actor_reqs))
760 && action_id_get_actor_kind(enabler->action) == AAK_UNIT
761 && ((action_id_get_target_kind(enabler->action) != ATK_TILE
762 && action_id_get_target_kind(enabler->action) != ATK_EXTRAS)
763 /* No diplomatic relation to Nature */
764 || !does_req_contradicts_reqs(&tile_is_claimed,
765 &enabler->target_reqs))) {
766 bool present = TRUE;
767 do {
768 req.present = present;
769 if (!does_req_contradicts_reqs(&req, &(enabler->actor_reqs))) {
770 BV_SET(dipl_rel_action_cache[uidx][enabler->action],
772 REQ_RANGE_LOCAL, req.present));
773 if (action_is_hostile(enabler->action)) {
776 REQ_RANGE_LOCAL,
777 req.present));
778 }
781 REQ_RANGE_LOCAL, req.present));
782 }
783 present = !present;
784 } while (!present);
785 }
787 }
788}
789
790/**********************************************************************/
795static void
797{
798 struct requirement req;
799 struct requirement tile_is_claimed;
800 int uidx = utype_index(putype);
801
802 /* The unit is not yet known to be allowed to perform any actions no
803 * matter what the diplomatic state is. */
804 action_iterate(act_id) {
809
810 /* Tile is claimed as a requirement. */
811 tile_is_claimed.range = REQ_RANGE_LOCAL;
812 tile_is_claimed.survives = FALSE;
813 tile_is_claimed.source.kind = VUT_CITYTILE;
814 tile_is_claimed.present = TRUE;
815 tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
816
817 /* Common for every situation */
818 req.range = REQ_RANGE_LOCAL;
819 req.survives = FALSE;
820 req.source.kind = VUT_DIPLREL_TILE_O;
821
822 /* DiplRel starts with diplstate_type and ends with diplrel_other */
823 for (req.source.value.diplrel = diplstate_type_begin();
824 req.source.value.diplrel != DRO_LAST;
825 req.source.value.diplrel++) {
826
827 /* No action will ever be possible in a specific diplomatic relation if
828 * its presence contradicts all action enablers.
829 * Everything was set to false above. It is therefore OK to only change
830 * the cache when units can do an action given a certain diplomatic
831 * relationship property value. */
832 action_enablers_iterate(enabler) {
834 &(enabler->actor_reqs))
835 && action_id_get_actor_kind(enabler->action) == AAK_UNIT
836 /* No diplomatic relation to Nature */
837 && !does_req_contradicts_reqs(&tile_is_claimed,
838 &enabler->target_reqs)) {
839 bool present = TRUE;
840 do {
841 req.present = present;
842 if (!does_req_contradicts_reqs(&req, &(enabler->target_reqs))) {
843 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][enabler->action],
845 REQ_RANGE_LOCAL, req.present));
846 if (action_is_hostile(enabler->action)) {
849 REQ_RANGE_LOCAL,
850 req.present));
851 }
854 REQ_RANGE_LOCAL, req.present));
855 }
856 present = !present;
857 } while (!present);
858 }
860 }
861}
862
863/**********************************************************************/
868static void tgt_citytile_act_cache_set(struct unit_type *putype)
869{
870 struct requirement req;
871 int uidx = utype_index(putype);
872
873 /* The unit is not yet known to be allowed to perform any actions no
874 * matter what its target's CityTile state is. */
875 action_iterate(act_id) {
876 BV_CLR_ALL(ctile_tgt_act_cache[uidx][act_id]);
880
881 if (!utype_may_act_at_all(putype)) {
882 /* Not an actor unit. */
883 return;
884 }
885
886 /* Common for every situation */
887 req.range = REQ_RANGE_LOCAL;
888 req.survives = FALSE;
889 req.source.kind = VUT_CITYTILE;
890
891 for (req.source.value.citytile = citytile_type_begin();
892 req.source.value.citytile != citytile_type_end();
893 req.source.value.citytile = citytile_type_next(
894 req.source.value.citytile)) {
895
896 /* No action will ever be possible in a target CityTile state if the
897 * opposite target CityTile state is required in all action enablers.
898 * No CityTile property state except present and !present of the same
899 * property implies or conflicts with another so the tests can be
900 * simple. */
901 action_enablers_iterate(enabler) {
903 &(enabler->target_reqs))
904 && action_id_get_actor_kind(enabler->action) == AAK_UNIT) {
905 bool present = TRUE;
906 do {
907 /* OK if not mentioned */
908 req.present = present;
909 if (!is_req_in_vec(&req, &(enabler->target_reqs))) {
910 BV_SET(
911 ctile_tgt_act_cache[utype_index(putype)][enabler->action],
913 !req.present));
914 if (action_is_hostile(enabler->action)) {
915 BV_SET(
918 !req.present));
919 }
922 !req.present));
923 }
924 present = !present;
925 } while (!present);
926 }
928 }
929}
930
931struct range {
932 int min;
933 int max;
934};
935
936#define MOVES_LEFT_INFINITY -1
937
938/**********************************************************************/
942static struct range *moves_left_range(struct requirement_vector *reqs)
943{
944 struct range *prange = fc_malloc(sizeof(prange));
945
946 prange->min = 0;
947 prange->max = MOVES_LEFT_INFINITY;
948
950 if (preq->source.kind == VUT_MINMOVES) {
951 if (preq->present) {
952 prange->min = preq->source.value.minmoves;
953 } else {
954 prange->max = preq->source.value.minmoves;
955 }
956 }
958
959 return prange;
960}
961
962/**********************************************************************/
978
979/**********************************************************************/
989
990/**********************************************************************/
995bool can_unit_act_when_ustate_is(const struct unit_type *punit_type,
996 const enum ustate_prop prop,
997 const bool is_there)
998{
999 return utype_can_do_act_when_ustate(punit_type, ACTION_ANY, prop, is_there);
1000}
1001
1002/**********************************************************************/
1007bool utype_can_do_act_when_ustate(const struct unit_type *punit_type,
1008 const action_id act_id,
1009 const enum ustate_prop prop,
1010 const bool is_there)
1011{
1012 fc_assert_ret_val(punit_type, FALSE);
1013 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1014
1015 return BV_ISSET(ustate_act_cache[utype_index(punit_type)][act_id],
1016 requirement_unit_state_ereq(prop, is_there));
1017}
1018
1019/**********************************************************************/
1028 enum action_result result,
1029 const enum ustate_prop prop,
1030 const bool is_there)
1031{
1032 fc_assert_ret_val(putype, FALSE);
1033
1034 action_by_result_iterate(paction, result) {
1035 if (utype_can_do_act_when_ustate(putype, paction->id, prop, is_there)) {
1036 return TRUE;
1037 }
1039
1040 return FALSE;
1041}
1042
1043/**********************************************************************/
1048bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type,
1049 const action_id act_id,
1050 const enum citytile_type prop,
1051 const bool is_there)
1052{
1053 fc_assert_ret_val(punit_type, FALSE);
1054 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1055
1056 return BV_ISSET(ctile_tgt_act_cache[utype_index(punit_type)][act_id],
1057 requirement_citytile_ereq(prop, is_there));
1058}
1059
1060/**********************************************************************/
1069bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type,
1070 const action_id act_id,
1071 const int prop,
1072 const bool is_there)
1073{
1074 fc_assert_ret_val(punit_type, FALSE);
1075 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1076
1077 return BV_ISSET(dipl_rel_action_cache[utype_index(punit_type)][act_id],
1078 requirement_diplrel_ereq(prop, REQ_RANGE_LOCAL, is_there));
1079}
1080
1081/**********************************************************************/
1087bool
1089 const action_id act_id,
1090 const int prop,
1091 const bool is_there)
1092{
1093 fc_assert_ret_val(punit_type, FALSE);
1094 fc_assert_ret_val(act_id >= 0 && act_id < ACTION_AND_FAKES, FALSE);
1095
1096 return BV_ISSET(
1097 dipl_rel_tile_other_tgt_a_cache[utype_index(punit_type)][act_id],
1098 requirement_diplrel_ereq(prop, REQ_RANGE_LOCAL, is_there));
1099}
1100
1101/**********************************************************************/
1110bool utype_may_act_move_frags(const struct unit_type *punit_type,
1111 const action_id act_id,
1112 const int move_fragments)
1113{
1114 struct range *ml_range;
1115
1116 fc_assert(action_id_exists(act_id) || act_id == ACTION_ANY);
1117
1118 if (!utype_may_act_at_all(punit_type)) {
1119 /* Not an actor unit. */
1120 return FALSE;
1121 }
1122
1123 if (act_id == ACTION_ANY) {
1124 /* Any action is OK. */
1125 action_iterate(alt_act) {
1126 if (utype_may_act_move_frags(punit_type, alt_act,
1127 move_fragments)) {
1128 /* It only has to be true for one action. */
1129 return TRUE;
1130 }
1132
1133 /* No action enabled. */
1134 return FALSE;
1135 }
1136
1137 if (action_id_get_actor_kind(act_id) != AAK_UNIT) {
1138 /* This action isn't performed by any unit at all so this unit type
1139 * can't do it. */
1140 return FALSE;
1141 }
1142
1144 enabler) {
1145 if (!requirement_fulfilled_by_unit_type(punit_type,
1146 &(enabler->actor_reqs))) {
1147 /* This action enabler isn't for this unit type at all. */
1148 continue;
1149 }
1150
1151 ml_range = moves_left_range(&(enabler->actor_reqs));
1152 if (ml_range->min <= move_fragments
1153 && (ml_range->max == MOVES_LEFT_INFINITY
1154 || ml_range->max > move_fragments)) {
1155 /* The number of move fragments is in range of the action enabler. */
1156
1157 free(ml_range);
1158
1159 return TRUE;
1160 }
1161
1162 free(ml_range);
1164
1165 return FALSE;
1166}
1167
1168/**********************************************************************/
1176bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type,
1177 const action_id act_id,
1178 const enum citytile_type prop,
1179 const bool is_there)
1180{
1181 struct requirement req;
1182
1183 if (!utype_may_act_at_all(punit_type)) {
1184 /* Not an actor unit. */
1185 return FALSE;
1186 }
1187
1188 if (act_id == ACTION_ANY) {
1189 /* Any action is OK. */
1190 action_iterate(alt_act) {
1191 if (utype_may_act_tgt_city_tile(punit_type, alt_act,
1192 prop, is_there)) {
1193 /* It only has to be true for one action. */
1194 return TRUE;
1195 }
1197
1198 /* No action enabled. */
1199 return FALSE;
1200 }
1201
1202 if (action_id_get_actor_kind(act_id) != AAK_UNIT) {
1203 /* This action isn't performed by any unit at all so this unit type
1204 * can't do it. */
1205 return FALSE;
1206 }
1207
1208 /* Common for every situation */
1209 req.range = REQ_RANGE_LOCAL;
1210 req.survives = FALSE;
1211 req.source.kind = VUT_CITYTILE;
1212
1213 /* Will only check for the specified is_there */
1214 req.present = is_there;
1215
1216 /* Will only check the specified property */
1217 req.source.value.citytile = prop;
1218
1220 enabler) {
1221 if (!requirement_fulfilled_by_unit_type(punit_type,
1222 &(enabler->actor_reqs))) {
1223 /* This action enabler isn't for this unit type at all. */
1224 continue;
1225 }
1226
1227 if (!does_req_contradicts_reqs(&req, &(enabler->target_reqs))) {
1228 /* This action isn't blocked by the given target tile property. */
1229 return TRUE;
1230 }
1232
1233 return FALSE;
1234}
1235
1236/**********************************************************************/
1243bool utype_action_takes_all_mp(const struct unit_type *putype,
1244 struct action *paction)
1245{
1246 return BV_ISSET(utype_act_takes_all_mp_cache[paction->id],
1247 utype_index(putype));
1248}
1249
1250/**********************************************************************/
1260 struct action *paction,
1261 const enum ustate_prop prop)
1262{
1263 return BV_ISSET(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
1264 utype_index(putype));
1265}
1266
1267/**********************************************************************/
1271bool utype_is_consumed_by_action(const struct action *paction,
1272 const struct unit_type *utype)
1273{
1274 return paction->actor_consuming_always;
1275}
1276
1277/**********************************************************************/
1281bool utype_is_consumed_by_action_result(enum action_result result,
1282 const struct unit_type *utype)
1283{
1284 action_by_result_iterate(paction, result) {
1285 if (!utype_can_do_action(utype, paction->id)) {
1286 continue;
1287 }
1288
1289 if (utype_is_consumed_by_action(paction, utype)) {
1290 return TRUE;
1291 }
1293
1294 return FALSE;
1295}
1296
1297/**********************************************************************/
1301bool utype_is_moved_to_tgt_by_action(const struct action *paction,
1302 const struct unit_type *utype)
1303{
1304 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
1305
1306 if (paction->actor_consuming_always) {
1307 return FALSE;
1308 }
1309
1310 switch (paction->actor.is_unit.moves_actor) {
1311 case MAK_STAYS:
1312 /* Stays at the tile were it was. */
1313 return FALSE;
1314 case MAK_REGULAR:
1315 /* A "regular" move. Does it charge the move cost of a regular move?
1316 * Update utype_pays_for_regular_move_to_tgt() if yes. */
1317 return TRUE;
1318 case MAK_TELEPORT:
1319 /* A teleporting move. */
1320 return TRUE;
1321 case MAK_FORCED:
1322 /* Tries a forced move under certain conditions. */
1323 return FALSE;
1324 case MAK_ESCAPE:
1325 /* May die, may be teleported to a safe city. */
1326 return FALSE;
1327 case MAK_UNREPRESENTABLE:
1328 /* Too complex to determine. */
1329 return FALSE;
1330 }
1331
1332 fc_assert_msg(FALSE, "Should not reach this code.");
1333 return FALSE;
1334}
1335
1336/**********************************************************************/
1340bool utype_is_unmoved_by_action(const struct action *paction,
1341 const struct unit_type *utype)
1342{
1343 fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
1344
1345 if (paction->actor_consuming_always) {
1346 /* Dead counts as moved off the board */
1347 return FALSE;
1348 }
1349
1350 switch (paction->actor.is_unit.moves_actor) {
1351 case MAK_STAYS:
1352 /* Stays at the tile were it was. */
1353 return TRUE;
1354 case MAK_REGULAR:
1355 /* A "regular" move. Does it charge the move cost of a regular move?
1356 * Update utype_pays_for_regular_move_to_tgt() if yes. */
1357 return FALSE;
1358 case MAK_TELEPORT:
1359 /* A teleporting move. */
1360 return FALSE;
1361 case MAK_FORCED:
1362 /* Tries a forced move under certain conditions. */
1363 return FALSE;
1364 case MAK_ESCAPE:
1365 /* May die, may be teleported to a safe city. */
1366 return FALSE;
1367 case MAK_UNREPRESENTABLE:
1368 /* Too complex to determine. */
1369 return FALSE;
1370 }
1371
1372 fc_assert_msg(FALSE, "Should not reach this code.");
1373 return FALSE;
1374}
1375
1376/**********************************************************************/
1383 const struct unit_type *utype)
1384{
1385 if (!utype_is_moved_to_tgt_by_action(paction, utype)) {
1386 /* Not even a move. */
1387 return FALSE;
1388 }
1389
1390 if (action_has_result(paction, ACTRES_CONQUER_CITY)) {
1391 /* Moves into the city to occupy it. */
1392 return TRUE;
1393 }
1394
1395 if (action_has_result(paction, ACTRES_CONQUER_EXTRAS)) {
1396 /* Moves into the tile with the extras to capture them. */
1397 return TRUE;
1398 }
1399
1400 if (action_has_result(paction, ACTRES_HUT_ENTER)) {
1401 /* Moves into the tile with the hut to enter it. */
1402 return TRUE;
1403 }
1404
1405 if (action_has_result(paction, ACTRES_HUT_FRIGHTEN)) {
1406 /* Moves into the tile with the hut to frighten it. */
1407 return TRUE;
1408 }
1409
1410 if (action_has_result(paction, ACTRES_TRANSPORT_DISEMBARK)) {
1411 /* Moves out of the transport to disembark. */
1412 return TRUE;
1413 }
1414
1415 if (action_has_result(paction, ACTRES_TRANSPORT_EMBARK)) {
1416 /* Moves into the transport to embark. */
1417 return TRUE;
1418 }
1419
1420 if (action_has_result(paction, ACTRES_UNIT_MOVE)) {
1421 /* Is a regular move. */
1422 return TRUE;
1423 }
1424
1425 return FALSE;
1426}
1427
1428/**********************************************************************/
1433int utype_pays_mp_for_action_base(const struct action *paction,
1434 const struct unit_type *putype)
1435{
1436 int mpco = 0;
1437
1438 return mpco;
1439}
1440
1441/**********************************************************************/
1446 const struct action *paction,
1447 const struct unit_type *putype,
1448 const struct player *act_player,
1449 const struct tile *act_tile,
1450 const struct tile *tgt_tile)
1451{
1452 const struct tile *post_action_tile;
1453 int mpco = utype_pays_mp_for_action_base(paction, putype);
1454
1455 if (utype_is_moved_to_tgt_by_action(paction, putype)) {
1456 post_action_tile = tgt_tile;
1457 } else {
1458 /* FIXME: Not 100% true. May escape, have a probability for moving to
1459 * target tile etc. */
1460 post_action_tile = act_tile;
1461 }
1462
1463 if (utype_pays_for_regular_move_to_tgt(paction, putype)) {
1464 /* Add the cost from the move. */
1465 mpco += map_move_cost(nmap, act_player, putype,
1466 act_tile, tgt_tile);
1467 }
1468
1469 /* FIXME: Probably wrong result if the effect
1470 * EFT_ACTION_SUCCESS_MOVE_COST depends on unit state. Add unit state
1471 * parameters? */
1472 mpco += get_target_bonus_effects(NULL,
1473 &(const struct req_context) {
1474 .player = act_player,
1475 .city = tile_city(post_action_tile),
1476 .tile = tgt_tile,
1477 .unittype = putype,
1478 .action = paction,
1479 },
1480 NULL,
1481 EFT_ACTION_SUCCESS_MOVE_COST);
1482
1483 return mpco;
1484}
1485
1486/**********************************************************************/
1490int utype_build_shield_cost(const struct city *pcity,
1491 const struct player *pplayer,
1492 const struct unit_type *punittype)
1493{
1494 int base;
1495 const struct player *owner;
1496 const struct tile *ptile;
1497
1498 if (pcity != NULL) {
1499 owner = city_owner(pcity);
1500 ptile = city_tile(pcity);
1501 } else {
1502 owner = NULL;
1503 ptile = NULL;
1504 }
1505 if (pplayer != NULL) {
1506 /* Override city owner. */
1507 owner = pplayer;
1508 }
1509
1510 base = punittype->build_cost
1511 * (100 + get_unittype_bonus(owner, ptile, punittype, NULL,
1512 EFT_UNIT_BUILD_COST_PCT)) / 100;
1513
1514 return MAX(base * game.info.shieldbox / 100, 1);
1515}
1516
1517/**********************************************************************/
1520int utype_build_shield_cost_base(const struct unit_type *punittype)
1521{
1522 return MAX(punittype->build_cost * game.info.shieldbox / 100, 1);
1523}
1524
1525/**********************************************************************/
1528int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
1529{
1530 return utype_build_shield_cost(pcity, NULL, unit_type_get(punit));
1531}
1532
1533/**********************************************************************/
1540
1541/**********************************************************************/
1544int utype_buy_gold_cost(const struct city *pcity,
1545 const struct unit_type *punittype,
1546 int shields_in_stock)
1547{
1548 int cost = 0;
1549 const int missing = utype_build_shield_cost(pcity, NULL, punittype) - shields_in_stock;
1550 struct player *owner;
1551 struct tile *ptile;
1552
1553 if (missing > 0) {
1554 cost = 2 * missing + (missing * missing) / 20;
1555 }
1556
1557 if (shields_in_stock == 0) {
1558 cost *= 2;
1559 }
1560
1561 if (pcity != NULL) {
1562 owner = city_owner(pcity);
1563 ptile = city_tile(pcity);
1564 } else {
1565 owner = NULL;
1566 ptile = NULL;
1567 }
1568
1569 cost = cost
1570 * (100 + get_unittype_bonus(owner, ptile, punittype, NULL,
1571 EFT_UNIT_BUY_COST_PCT))
1572 / 100;
1573
1574 return cost;
1575}
1576
1577/**********************************************************************/
1580int utype_pop_value(const struct unit_type *punittype, const struct city *pcity)
1581{
1582 int pop_cost = punittype->pop_cost;
1583
1584 pop_cost -= get_unittype_bonus(city_owner(pcity), city_tile(pcity),
1585 punittype, NULL, EFT_POPCOST_FREE);
1586
1587 return MAX(0, pop_cost);
1588}
1589
1590/**********************************************************************/
1595int unit_pop_value(const struct unit *punit)
1596{
1597 return unit_type_get(punit)->pop_cost;
1598}
1599
1600/**********************************************************************/
1603enum unit_move_type utype_move_type(const struct unit_type *punittype)
1604{
1605 return utype_class(punittype)->move_type;
1606}
1607
1608/**********************************************************************/
1612const char *utype_name_translation(const struct unit_type *punittype)
1613{
1614 return name_translation_get(&punittype->name);
1615}
1616
1617/**********************************************************************/
1621const char *unit_name_translation(const struct unit *punit)
1622{
1624}
1625
1626/**********************************************************************/
1630const char *utype_rule_name(const struct unit_type *punittype)
1631{
1632 return rule_name_get(&punittype->name);
1633}
1634
1635/**********************************************************************/
1639const char *unit_rule_name(const struct unit *punit)
1640{
1642}
1643
1644/**********************************************************************/
1648const char *utype_values_string(const struct unit_type *punittype)
1649{
1650 static char buffer[256];
1651
1652 /* Print in two parts as move_points_text() returns a static buffer */
1653 fc_snprintf(buffer, sizeof(buffer), "%d/%d/%s",
1654 punittype->attack_strength,
1655 punittype->defense_strength,
1656 move_points_text(punittype->move_rate, TRUE));
1657 if (utype_fuel(punittype)) {
1658 cat_snprintf(buffer, sizeof(buffer), "(%s)",
1659 move_points_text(punittype->move_rate * utype_fuel(punittype),
1660 TRUE));
1661 }
1662 return buffer;
1663}
1664
1665/**********************************************************************/
1669const char *utype_values_translation(const struct unit_type *punittype)
1670{
1671 static char buffer[256];
1672
1673 fc_snprintf(buffer, sizeof(buffer),
1674 "%s [%s]",
1675 utype_name_translation(punittype),
1676 utype_values_string(punittype));
1677 return buffer;
1678}
1679
1680/**********************************************************************/
1684const char *uclass_name_translation(const struct unit_class *pclass)
1685{
1686 return name_translation_get(&pclass->name);
1687}
1688
1689/**********************************************************************/
1693const char *uclass_rule_name(const struct unit_class *pclass)
1694{
1695 return rule_name_get(&pclass->name);
1696}
1697
1698/**********************************************************************/
1701bool unit_has_class_flag(const struct unit *punit, enum unit_class_flag_id flag)
1702{
1703 return uclass_has_flag(unit_class_get(punit), flag);
1704}
1705
1706/**********************************************************************/
1709bool utype_has_class_flag(const struct unit_type *ptype,
1710 enum unit_class_flag_id flag)
1711{
1712 return uclass_has_flag(utype_class(ptype), flag);
1713}
1714
1715/**********************************************************************/
1720bool role_units_translations(struct astring *astr, int flag, bool alts)
1721{
1722 const int count = num_role_units(flag);
1723
1724 if (4 < count) {
1725 if (alts) {
1726 astr_set(astr, _("%s or similar units"),
1728 } else {
1729 astr_set(astr, _("%s and similar units"),
1731 }
1732 return TRUE;
1733 } else if (0 < count) {
1734 const char *vec[count];
1735 int i;
1736
1737 for (i = 0; i < count; i++) {
1738 vec[i] = utype_name_translation(get_role_unit(flag, i));
1739 }
1740
1741 if (alts) {
1742 astr_build_or_list(astr, vec, count);
1743 } else {
1744 astr_build_and_list(astr, vec, count);
1745 }
1746 return TRUE;
1747 }
1748 return FALSE;
1749}
1750
1751/**********************************************************************/
1755const struct unit_type *can_upgrade_unittype(const struct player *pplayer,
1756 const struct unit_type *punittype)
1757{
1758 const struct unit_type *upgrade = punittype;
1759 const struct unit_type *best_upgrade = NULL;
1760
1761 /* For some reason this used to check
1762 * can_player_build_unit_direct() for the unittype
1763 * we're updating from.
1764 * That check is now removed as it prevented legal updates
1765 * of units player had acquired via bribing, capturing,
1766 * diplomatic treaties, or lua script. */
1767
1768 while ((upgrade = upgrade->obsoleted_by) != U_NOT_OBSOLETED) {
1769 if (can_player_build_unit_direct(pplayer, upgrade)) {
1770 best_upgrade = upgrade;
1771 }
1772 }
1773
1774 return best_upgrade;
1775}
1776
1777/**********************************************************************/
1783int unit_upgrade_price(const struct player *pplayer,
1784 const struct unit_type *from,
1785 const struct unit_type *to)
1786{
1787 /* Upgrade price is only paid for "Upgrade Unit" so it is safe to hard
1788 * code the action ID for now. paction will have to become a parameter
1789 * before generalized actions appears. */
1790 const struct action *paction = action_by_number(ACTION_UPGRADE_UNIT);
1791 int missing = (utype_build_shield_cost_base(to)
1792 - unit_shield_value(NULL, from, paction));
1793 int base_cost = 2 * missing + (missing * missing) / 20;
1794
1795 return base_cost
1796 * (100 + get_player_bonus(pplayer, EFT_UPGRADE_PRICE_PCT))
1797 / 100;
1798}
1799
1800/**********************************************************************/
1805{
1806 unit_type_iterate(punittype) {
1807 if (0 == strcmp(utype_name_translation(punittype), name)) {
1808 return punittype;
1809 }
1811
1812 return NULL;
1813}
1814
1815/**********************************************************************/
1820{
1821 const char *qname = Qn_(name);
1822
1823 unit_type_iterate(punittype) {
1824 if (0 == fc_strcasecmp(utype_rule_name(punittype), qname)) {
1825 return punittype;
1826 }
1828
1829 return NULL;
1830}
1831
1832/**********************************************************************/
1837{
1838 const char *qs = Qn_(s);
1839
1840 unit_class_iterate(pclass) {
1841 if (0 == fc_strcasecmp(uclass_rule_name(pclass), qs)) {
1842 return pclass;
1843 }
1845
1846 return NULL;
1847}
1848
1849/**********************************************************************/
1853{
1854 int i;
1855
1856 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
1858 }
1859}
1860
1861/**********************************************************************/
1864void set_user_unit_class_flag_name(enum unit_class_flag_id id,
1865 const char *name,
1866 const char *helptxt)
1867{
1868 int ufid = id - UCF_USER_FLAG_1;
1869
1870 fc_assert_ret(id >= UCF_USER_FLAG_1 && id <= UCF_LAST_USER_FLAG);
1871
1872 if (user_class_flags[ufid].name != NULL) {
1874 user_class_flags[ufid].name = NULL;
1875 }
1876
1877 if (name && name[0] != '\0') {
1879 }
1880
1881 if (user_class_flags[ufid].helptxt != NULL) {
1882 free(user_class_flags[ufid].helptxt);
1883 user_class_flags[ufid].helptxt = NULL;
1884 }
1885
1886 if (helptxt && helptxt[0] != '\0') {
1887 user_class_flags[ufid].helptxt = fc_strdup(helptxt);
1888 }
1889}
1890
1891/**********************************************************************/
1894const char *unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
1895{
1896 if (flag < UCF_USER_FLAG_1 || flag > UCF_LAST_USER_FLAG) {
1897 return NULL;
1898 }
1899
1900 return user_class_flags[flag - UCF_USER_FLAG_1].name;
1901}
1902
1903/**********************************************************************/
1906const char *unit_class_flag_helptxt(enum unit_class_flag_id id)
1907{
1908 fc_assert(id >= UCF_USER_FLAG_1 && id <= UCF_LAST_USER_FLAG);
1909
1910 return user_class_flags[id - UCF_USER_FLAG_1].helptxt;
1911}
1912
1913/**********************************************************************/
1917{
1918 int i;
1919
1920 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
1922 }
1923}
1924
1925/**********************************************************************/
1928void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name,
1929 const char *helptxt)
1930{
1931 int ufid = id - UTYF_USER_FLAG_1;
1932
1933 fc_assert_ret(id >= UTYF_USER_FLAG_1 && id <= UTYF_LAST_USER_FLAG);
1934
1935 if (user_type_flags[ufid].name != NULL) {
1937 user_type_flags[ufid].name = NULL;
1938 }
1939
1940 if (name && name[0] != '\0') {
1942 }
1943
1944 if (user_type_flags[ufid].helptxt != NULL) {
1945 free(user_type_flags[ufid].helptxt);
1946 user_type_flags[ufid].helptxt = NULL;
1947 }
1948
1949 if (helptxt && helptxt[0] != '\0') {
1950 user_type_flags[ufid].helptxt = fc_strdup(helptxt);
1951 }
1952}
1953
1954/**********************************************************************/
1957const char *unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
1958{
1959 if (flag < UTYF_USER_FLAG_1 || flag > UTYF_LAST_USER_FLAG) {
1960 return NULL;
1961 }
1962
1963 return user_type_flags[flag - UTYF_USER_FLAG_1].name;
1964}
1965
1966/**********************************************************************/
1969const char *unit_type_flag_helptxt(enum unit_type_flag_id id)
1970{
1971 fc_assert(id >= UTYF_USER_FLAG_1 && id <= UTYF_LAST_USER_FLAG);
1972
1973 return user_type_flags[id - UTYF_USER_FLAG_1].helptxt;
1974}
1975
1976/**********************************************************************/
1980 const struct unit_type *putype)
1981{
1982 if (!utype_has_flag(putype, UTYF_UNIQUE)) {
1983 /* This isn't a unique unit type. */
1984 return FALSE;
1985 }
1986
1987 return utype_player_already_has_this(pplayer, putype);
1988}
1989
1990/**********************************************************************/
1993bool utype_player_already_has_this(const struct player *pplayer,
1994 const struct unit_type *putype)
1995{
1996 unit_list_iterate(pplayer->units, existing_unit) {
1997 if (putype == unit_type_get(existing_unit)) {
1998 /* FIXME: This could be slow if we have lots of units. We could
1999 * consider keeping an array of unittypes updated with this info
2000 * instead. */
2001
2002 return TRUE;
2003 }
2005
2006 /* The player doesn't already have one. */
2007 return FALSE;
2008}
2009
2010/**********************************************************************/
2016 const struct unit_type *punittype)
2017{
2018 const struct req_context context = { .player = p, .unittype = punittype };
2019
2020 fc_assert_ret_val(NULL != punittype, FALSE);
2021
2022 if (is_barbarian(p)
2023 && !utype_has_role(punittype, L_BARBARIAN_BUILD)
2024 && !utype_has_role(punittype, L_BARBARIAN_BUILD_TECH)) {
2025 /* Barbarians can build only role units */
2026 return FALSE;
2027 }
2028
2029 if ((utype_can_do_action_result(punittype, ACTRES_NUKE_UNITS)
2030 || utype_can_do_action_result(punittype, ACTRES_NUKE))
2031 && get_player_bonus(p, EFT_ENABLE_NUKE) <= 0) {
2032 return FALSE;
2033 }
2034 if (utype_has_flag(punittype, UTYF_NOBUILD)) {
2035 return FALSE;
2036 }
2037
2038 if (utype_has_flag(punittype, UTYF_BARBARIAN_ONLY)
2039 && !is_barbarian(p)) {
2040 /* Unit can be built by barbarians only and this player is
2041 * not barbarian */
2042 return FALSE;
2043 }
2044
2045 if (utype_has_flag(punittype, UTYF_NEWCITY_GAMES_ONLY)
2047 /* Unit is usable only in games where founding of new cities is allowed. */
2048 return FALSE;
2049 }
2050
2051 requirement_vector_iterate(&punittype->build_reqs, preq) {
2052 if (preq->source.kind == VUT_IMPROVEMENT
2053 && preq->range == REQ_RANGE_CITY && preq->present) {
2054 /* If the unit has a building requirement, we check to see if the
2055 * player can build that building. Note that individual cities may
2056 * not have that building, so they still may not be able to build the
2057 * unit. */
2058 if (is_great_wonder(preq->source.value.building)
2059 && (great_wonder_is_built(preq->source.value.building)
2060 || great_wonder_is_destroyed(preq->source.value.building))) {
2061 /* It's already built great wonder */
2062 if (great_wonder_owner(preq->source.value.building) != p) {
2063 /* Not owned by this player. Either destroyed or owned by somebody
2064 * else. */
2065 return FALSE;
2066 }
2067 } else if (is_small_wonder(preq->source.value.building)) {
2068 if (!city_from_wonder(p, preq->source.value.building)
2069 && !can_player_build_improvement_direct(p, preq->source.value.building)) {
2070 return FALSE;
2071 }
2072 } else {
2074 p, preq->source.value.building)) {
2075 return FALSE;
2076 }
2077 }
2078 }
2079 if (preq->range < REQ_RANGE_PLAYER) {
2080 /* The question *here* is if the *player* can build this unit */
2081 continue;
2082 }
2083 if (!is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
2084 return FALSE;
2085 }
2087
2089 advance_number(punittype->require_advance))
2090 != TECH_KNOWN) {
2091 if (!is_barbarian(p)) {
2092 /* Normal players can never build units without knowing tech
2093 * requirements. */
2094 return FALSE;
2095 }
2096 if (!utype_has_role(punittype, L_BARBARIAN_BUILD)) {
2097 /* Even barbarian cannot build this unit without tech */
2098
2099 /* Unit has to have L_BARBARIAN_BUILD_TECH role
2100 * In the beginning of this function we checked that
2101 * barbarian player tries to build only role
2102 * L_BARBARIAN_BUILD or L_BARBARIAN_BUILD_TECH units. */
2103 fc_assert_ret_val(utype_has_role(punittype, L_BARBARIAN_BUILD_TECH),
2104 FALSE);
2105
2106 /* Client does not know all the advances other players have
2107 * got. So following gives wrong answer in the client.
2108 * This is called at the client when received create_city
2109 * packet for a barbarian city. City initialization tries
2110 * to find L_FIRSTBUILD unit. */
2111
2113 /* Nobody knows required tech */
2114 return FALSE;
2115 }
2116 }
2117 }
2118
2119 if (utype_player_already_has_this_unique(p, punittype)) {
2120 /* A player can only have one unit of each unique unit type. */
2121 return FALSE;
2122 }
2123
2124 return TRUE;
2125}
2126
2127/**********************************************************************/
2132 const struct unit_type *punittype)
2133{
2134 if (!can_player_build_unit_direct(p, punittype)) {
2135 return FALSE;
2136 }
2137 while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
2138 if (can_player_build_unit_direct(p, punittype)) {
2139 return FALSE;
2140 }
2141 }
2142 return TRUE;
2143}
2144
2145/**********************************************************************/
2151 const struct unit_type *punittype)
2152{
2153 fc_assert_ret_val(NULL != punittype, FALSE);
2154 if (utype_has_flag(punittype, UTYF_NOBUILD)) {
2155 return FALSE;
2156 }
2157 while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
2158 if (can_player_build_unit_direct(p, punittype)) {
2159 return FALSE;
2160 }
2161 }
2162 return TRUE;
2163}
2164
2165/**************************************************************************
2166 The following functions use static variables so we can quickly look up
2167 which unit types have given flag or role.
2168 For these functions flags and roles are considered to be in the same "space",
2169 and any "role" argument can also be a "flag".
2170 Unit order is in terms of the order in the units ruleset.
2171**************************************************************************/
2172static bool first_init = TRUE;
2175
2176/**********************************************************************/
2180static void precalc_one(int i,
2181 bool (*func_has)(const struct unit_type *, int))
2182{
2183 int j;
2184
2185 /* Count: */
2186 fc_assert(n_with_role[i] == 0);
2188 if (func_has(u, i)) {
2189 n_with_role[i]++;
2190 }
2192
2193 if (n_with_role[i] > 0) {
2194 with_role[i] = fc_malloc(n_with_role[i] * sizeof(*with_role[i]));
2195 j = 0;
2197 if (func_has(u, i)) {
2198 with_role[i][j++] = u;
2199 }
2201 fc_assert(j == n_with_role[i]);
2202 }
2203}
2204
2205/**********************************************************************/
2209{
2210 int i;
2211
2212 for (i = 0; i < MAX_UNIT_ROLES; i++) {
2213 free(with_role[i]);
2214 with_role[i] = NULL;
2215 n_with_role[i] = 0;
2216 }
2217}
2218
2219/**********************************************************************/
2224{
2225 int i;
2226
2227 if (first_init) {
2228 for (i = 0; i < MAX_UNIT_ROLES; i++) {
2229 with_role[i] = NULL;
2230 n_with_role[i] = 0;
2231 }
2232 } else {
2234 }
2235
2236 for (i = 0; i <= UTYF_LAST_USER_FLAG; i++) {
2238 }
2239 for (i = L_FIRST; i < L_LAST; i++) {
2241 }
2242 for (i = L_LAST; i < MAX_UNIT_ROLES; i++) {
2244 }
2245 first_init = FALSE;
2246}
2247
2248/**********************************************************************/
2251int num_role_units(int role)
2252{
2253 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2254 || (role >= L_FIRST && role < L_LAST)
2255 || (role >= L_LAST && role < MAX_UNIT_ROLES), -1);
2257 return n_with_role[role];
2258}
2259
2260/**********************************************************************/
2265struct unit_type *role_units_iterate(int role, role_unit_callback cb, void *data)
2266{
2267 int i;
2268
2269 for (i = 0; i < n_with_role[role]; i++) {
2270 if (cb(with_role[role][i], data)) {
2271 return with_role[role][i];
2272 }
2273 }
2274
2275 return NULL;
2276}
2277
2278/**********************************************************************/
2285{
2286 int i;
2287
2288 for (i = n_with_role[role] - 1; i >= 0; i--) {
2289 if (cb(with_role[role][i], data)) {
2290 return with_role[role][i];
2291 }
2292 }
2293
2294 return NULL;
2295}
2296
2297/**********************************************************************/
2301struct unit_type *get_role_unit(int role, int role_index)
2302{
2303 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2304 || (role >= L_FIRST && role < L_LAST)
2305 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2307 if (role_index == -1) {
2308 role_index = n_with_role[role] - 1;
2309 }
2310 fc_assert_ret_val(role_index >= 0 && role_index < n_with_role[role], NULL);
2311
2312 return with_role[role][role_index];
2313}
2314
2315/**********************************************************************/
2319struct unit_type *best_role_unit(const struct city *pcity, int role)
2320{
2321 struct unit_type *u;
2322 int j;
2323
2324 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2325 || (role >= L_FIRST && role < L_LAST)
2326 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2328
2329 for (j = n_with_role[role] - 1; j >= 0; j--) {
2330 u = with_role[role][j];
2331 if (can_city_build_unit_now(pcity, u)) {
2332 return u;
2333 }
2334 }
2335
2336 return NULL;
2337}
2338
2339/**********************************************************************/
2345struct unit_type *best_role_unit_for_player(const struct player *pplayer,
2346 int role)
2347{
2348 int j;
2349
2350 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2351 || (role >= L_FIRST && role < L_LAST)
2352 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2354
2355 for (j = n_with_role[role] - 1; j >= 0; j--) {
2356 struct unit_type *utype = with_role[role][j];
2357
2358 if (can_player_build_unit_now(pplayer, utype)) {
2359 return utype;
2360 }
2361 }
2362
2363 return NULL;
2364}
2365
2366/**********************************************************************/
2370struct unit_type *first_role_unit_for_player(const struct player *pplayer,
2371 int role)
2372{
2373 int j;
2374
2375 fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
2376 || (role >= L_FIRST && role < L_LAST)
2377 || (role >= L_LAST && role < MAX_UNIT_ROLES), NULL);
2379
2380 for (j = 0; j < n_with_role[role]; j++) {
2381 struct unit_type *utype = with_role[role][j];
2382
2383 if (can_player_build_unit_now(pplayer, utype)) {
2384 return utype;
2385 }
2386 }
2387
2388 return NULL;
2389}
2390
2391/**********************************************************************/
2395{
2396 int i;
2397
2398 /* Can't use unit_type_iterate or utype_by_number here because
2399 * num_unit_types isn't known yet. */
2400 for (i = 0; i < ARRAY_SIZE(unit_types); i++) {
2401 unit_types[i].item_number = i;
2402 requirement_vector_init(&(unit_types[i].build_reqs));
2403 unit_types[i].helptext = NULL;
2404 unit_types[i].veteran = NULL;
2405 unit_types[i].bonuses = combat_bonus_list_new();
2407 unit_types[i].ruledit_dlg = NULL;
2408 }
2409}
2410
2411/**********************************************************************/
2414static void unit_type_free(struct unit_type *punittype)
2415{
2416 if (NULL != punittype->helptext) {
2417 strvec_destroy(punittype->helptext);
2418 punittype->helptext = NULL;
2419 }
2420
2421 requirement_vector_free(&(punittype->build_reqs));
2422
2423 veteran_system_destroy(punittype->veteran);
2424 combat_bonus_list_iterate(punittype->bonuses, pbonus) {
2425 FC_FREE(pbonus);
2427 combat_bonus_list_destroy(punittype->bonuses);
2428}
2429
2430/**********************************************************************/
2434{
2435 int i;
2436
2437 /* Can't use unit_type_iterate or utype_by_number here because
2438 * we want to free what unit_types_init() has allocated. */
2439 for (i = 0; i < ARRAY_SIZE(unit_types); i++) {
2441 }
2442}
2443
2444/**********************************************************************/
2448{
2449 int i;
2450
2451 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
2453 }
2454}
2455
2456/**********************************************************************/
2460{
2461 int i;
2462
2463 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
2465 }
2466}
2467
2468/**********************************************************************/
2472{
2473 if (game.control.num_unit_classes > 0) {
2474 return unit_classes;
2475 }
2476 return NULL;
2477}
2478
2479/**********************************************************************/
2483{
2484 if (game.control.num_unit_classes > 0) {
2486 }
2487 return NULL;
2488}
2489
2490/**********************************************************************/
2497
2498#ifndef uclass_index
2499/**********************************************************************/
2505Unit_Class_id uclass_index(const struct unit_class *pclass)
2506{
2507 fc_assert_ret_val(pclass, -1);
2508 return pclass - unit_classes;
2509}
2510#endif /* uclass_index */
2511
2512/**********************************************************************/
2516{
2517 fc_assert_ret_val(pclass, -1);
2518 return pclass->item_number;
2519}
2520
2521/**********************************************************************/
2525{
2526 if (id < 0 || id >= game.control.num_unit_classes) {
2527 return NULL;
2528 }
2529 return &unit_classes[id];
2530}
2531
2532#ifndef utype_class
2533/**********************************************************************/
2536struct unit_class *utype_class(const struct unit_type *punittype)
2537{
2538 fc_assert(NULL != punittype->uclass);
2539 return punittype->uclass;
2540}
2541#endif /* utype_class */
2542
2543/**********************************************************************/
2546struct unit_class *unit_class_get(const struct unit *punit)
2547{
2549}
2550
2551/**********************************************************************/
2555{
2556 int i;
2557
2558 /* Can't use unit_class_iterate or uclass_by_number here because
2559 * num_unit_classes isn't known yet. */
2560 for (i = 0; i < ARRAY_SIZE(unit_classes); i++) {
2565 unit_classes[i].cache.bonus_roads = NULL;
2568 unit_classes[i].helptext = NULL;
2570 }
2571}
2572
2573/**********************************************************************/
2577{
2578 int i;
2579
2580 for (i = 0; i < ARRAY_SIZE(unit_classes); i++) {
2581 if (unit_classes[i].cache.refuel_extras != NULL) {
2582 extra_type_list_destroy(unit_classes[i].cache.refuel_extras);
2584 }
2585 if (unit_classes[i].cache.native_tile_extras != NULL) {
2586 extra_type_list_destroy(unit_classes[i].cache.native_tile_extras);
2588 }
2589 if (unit_classes[i].cache.native_bases != NULL) {
2590 extra_type_list_destroy(unit_classes[i].cache.native_bases);
2592 }
2593 if (unit_classes[i].cache.bonus_roads != NULL) {
2594 extra_type_list_destroy(unit_classes[i].cache.bonus_roads);
2595 unit_classes[i].cache.bonus_roads = NULL;
2596 }
2597 if (unit_classes[i].cache.hiding_extras != NULL) {
2598 extra_type_list_destroy(unit_classes[i].cache.hiding_extras);
2600 }
2601 if (unit_classes[i].cache.subset_movers != NULL) {
2602 unit_class_list_destroy(unit_classes[i].cache.subset_movers);
2603 }
2604 if (unit_classes[i].helptext != NULL) {
2606 unit_classes[i].helptext = NULL;
2607 }
2608 }
2609}
2610
2611/**********************************************************************/
2614const struct veteran_system *
2615 utype_veteran_system(const struct unit_type *punittype)
2616{
2617 fc_assert_ret_val(punittype != NULL, NULL);
2618
2619 if (punittype->veteran) {
2620 return punittype->veteran;
2621 }
2622
2623 fc_assert_ret_val(game.veteran != NULL, NULL);
2624 return game.veteran;
2625}
2626
2627/**********************************************************************/
2630const struct veteran_level *
2631 utype_veteran_level(const struct unit_type *punittype, int level)
2632{
2633 const struct veteran_system *vsystem = utype_veteran_system(punittype);
2634
2635 fc_assert_ret_val(vsystem != NULL, NULL);
2636 fc_assert_ret_val(vsystem->definitions != NULL, NULL);
2637 fc_assert_ret_val(vsystem->levels > level, NULL);
2638
2639 return (vsystem->definitions + level);
2640}
2641
2642/**********************************************************************/
2646const char *utype_veteran_name_translation(const struct unit_type *punittype,
2647 int level)
2648{
2649 if (utype_veteran_levels(punittype) <= 1) {
2650 return NULL;
2651 } else {
2652 const struct veteran_level *vlvl = utype_veteran_level(punittype, level);
2653
2654 return name_translation_get(&vlvl->name);
2655 }
2656}
2657
2658/**********************************************************************/
2661int utype_veteran_levels(const struct unit_type *punittype)
2662{
2663 const struct veteran_system *vsystem = utype_veteran_system(punittype);
2664
2665 fc_assert_ret_val(vsystem != NULL, 1);
2666
2667 return vsystem->levels;
2668}
2669
2670/**********************************************************************/
2674bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
2675{
2676 int i, initial_power_fact = utype_veteran_level(punittype, 0)->power_fact;
2677 for (i = 1; i < utype_veteran_levels(punittype); i++) {
2678 if (utype_veteran_level(punittype, i)->power_fact > initial_power_fact) {
2679 return TRUE;
2680 }
2681 }
2682 return FALSE;
2683}
2684
2685/**********************************************************************/
2689{
2690 struct veteran_system *vsystem;
2691
2692 /* There must be at least one level. */
2693 fc_assert_ret_val(count > 0, NULL);
2694
2695 vsystem = fc_calloc(1, sizeof(*vsystem));
2696 vsystem->levels = count;
2697 vsystem->definitions = fc_calloc(vsystem->levels,
2698 sizeof(*vsystem->definitions));
2699
2700 return vsystem;
2701}
2702
2703/**********************************************************************/
2707{
2708 if (vsystem) {
2709 if (vsystem->definitions) {
2710 free(vsystem->definitions);
2711 }
2712 free(vsystem);
2713 }
2714}
2715
2716/**********************************************************************/
2720 const char *vlist_name, int vlist_power,
2721 int vlist_move, int vlist_raise,
2722 int vlist_wraise)
2723{
2724 struct veteran_level *vlevel;
2725
2726 fc_assert_ret(vsystem != NULL);
2727 fc_assert_ret(vsystem->levels > level);
2728
2729 vlevel = vsystem->definitions + level;
2730
2731 names_set(&vlevel->name, NULL, vlist_name, NULL);
2732 vlevel->power_fact = vlist_power;
2733 vlevel->move_bonus = vlist_move;
2734 vlevel->base_raise_chance = vlist_raise;
2735 vlevel->work_raise_chance = vlist_wraise;
2736}
2737
2738/**********************************************************************/
2741void *utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
2742{
2743 return ptype->ais[ai_type_number(ai)];
2744}
2745
2746/**********************************************************************/
2749void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai,
2750 void *data)
2751{
2752 ptype->ais[ai_type_number(ai)] = data;
2753}
2754
2755/**********************************************************************/
2759{
2760 pclass->cache.refuel_extras = extra_type_list_new();
2761 pclass->cache.native_tile_extras = extra_type_list_new();
2762 pclass->cache.native_bases = extra_type_list_new();
2763 pclass->cache.bonus_roads = extra_type_list_new();
2764 pclass->cache.hiding_extras = extra_type_list_new();
2765 pclass->cache.subset_movers = unit_class_list_new();
2766
2767 extra_type_iterate(pextra) {
2768 if (is_native_extra_to_uclass(pextra, pclass)) {
2769 struct road_type *proad = extra_road_get(pextra);
2770
2771 if (extra_has_flag(pextra, EF_REFUEL)) {
2772 extra_type_list_append(pclass->cache.refuel_extras, pextra);
2773 }
2774 if (extra_has_flag(pextra, EF_NATIVE_TILE)) {
2775 extra_type_list_append(pclass->cache.native_tile_extras, pextra);
2776 }
2777 if (is_extra_caused_by(pextra, EC_BASE)) {
2778 extra_type_list_append(pclass->cache.native_bases, pextra);
2779 }
2780 if (proad != NULL && road_provides_move_bonus(proad)) {
2781 extra_type_list_append(pclass->cache.bonus_roads, pextra);
2782 }
2783 if (pextra->eus == EUS_HIDDEN) {
2784 extra_type_list_append(pclass->cache.hiding_extras, pextra);
2785 }
2786 }
2788
2789 unit_class_iterate(pcharge) {
2790 bool subset_mover = TRUE;
2791
2792 terrain_type_iterate(pterrain) {
2793 if (BV_ISSET(pterrain->native_to, uclass_index(pcharge))
2794 && !BV_ISSET(pterrain->native_to, uclass_index(pclass))) {
2795 subset_mover = FALSE;
2796 }
2798
2799 if (subset_mover) {
2800 extra_type_iterate(pextra) {
2801 if (is_native_extra_to_uclass(pextra, pcharge)
2802 && !is_native_extra_to_uclass(pextra, pclass)) {
2803 subset_mover = FALSE;
2804 }
2806 }
2807
2808 if (subset_mover) {
2809 unit_class_list_append(pclass->cache.subset_movers, pcharge);
2810 }
2812}
2813
2814/**********************************************************************/
2818{
2820
2821 unit_type_iterate(utype) {
2822 int idx = utype_index(utype);
2823 int bonus = combat_bonus_against(
2824 ptype->bonuses, utype, CBONUS_DEFENSE_MULTIPLIER_PCT)
2825 + 100 * combat_bonus_against(ptype->bonuses, utype,
2826 CBONUS_DEFENSE_MULTIPLIER);
2827 int scramble_bonus =
2828 combat_bonus_against(ptype->bonuses, utype,
2829 CBONUS_SCRAMBLES_PCT);
2830
2831 ptype->cache.defense_mp_bonuses_pct[idx] = bonus;
2832 /* max value is for city defenders, so it considers scrambling */
2833 /* FIXME: if the unit's fuel != 1, scrambling is not so useful */
2834 if (scramble_bonus) {
2835 /* Guess about city defense effect value */
2836 struct universal u
2837 = { .kind = VUT_UTYPE, .value = {.utype = utype} };
2838 int emax = effect_cumulative_max(EFT_DEFEND_BONUS, &u, 1);
2839
2840 emax = CLIP(0, emax, 300); /* Likely sth wrong if more */
2841 emax -= emax >> 2; /* Might be no such building yet */
2842 bonus
2843 = (ptype->cache.scramble_coeff[idx]
2844 = (bonus + 100) * (scramble_bonus + 100)
2845 ) / (100 + emax) - 100;
2846 bonus = MAX(bonus, 1); /* to look better in assess_danger() */
2847 } else {
2848 ptype->cache.scramble_coeff[idx] = 0;
2849 }
2850 if (bonus > ptype->cache.max_defense_mp_bonus_pct) {
2851 ptype->cache.max_defense_mp_bonus_pct = bonus;
2852 }
2854}
2855
2856/**********************************************************************/
2859static enum unit_move_type move_type_from_extra(struct extra_type *pextra,
2860 struct unit_class *puc)
2861{
2862 bool land_allowed = TRUE;
2863 bool sea_allowed = TRUE;
2864
2865 if (!extra_has_flag(pextra, EF_NATIVE_TILE)) {
2866 return unit_move_type_invalid();
2867 }
2868 if (!is_native_extra_to_uclass(pextra, puc)) {
2869 return unit_move_type_invalid();
2870 }
2871
2872 if (is_extra_caused_by(pextra, EC_ROAD)
2873 && road_has_flag(extra_road_get(pextra), RF_RIVER)) {
2874 /* Natural rivers are created to land only */
2875 sea_allowed = FALSE;
2876 }
2877
2878 requirement_vector_iterate(&pextra->reqs, preq) {
2879 if (preq->source.kind == VUT_TERRAINCLASS) {
2880 if (!preq->present) {
2881 if (preq->source.value.terrainclass == TC_LAND) {
2882 land_allowed = FALSE;
2883 } else if (preq->source.value.terrainclass == TC_OCEAN) {
2884 sea_allowed = FALSE;
2885 }
2886 } else {
2887 if (preq->source.value.terrainclass == TC_LAND) {
2888 sea_allowed = FALSE;
2889 } else if (preq->source.value.terrainclass == TC_OCEAN) {
2890 land_allowed = FALSE;
2891 }
2892 }
2893 } else if (preq->source.kind == VUT_TERRAIN) {
2894 if (!preq->present) {
2895 if (preq->source.value.terrain->tclass == TC_LAND) {
2896 land_allowed = FALSE;
2897 } else if (preq->source.value.terrain->tclass == TC_OCEAN) {
2898 sea_allowed = FALSE;
2899 }
2900 } else {
2901 if (preq->source.value.terrain->tclass == TC_LAND) {
2902 sea_allowed = FALSE;
2903 } else if (preq->source.value.terrain->tclass == TC_OCEAN) {
2904 land_allowed = FALSE;
2905 }
2906 }
2907 }
2909
2910 if (land_allowed && sea_allowed) {
2911 return UMT_BOTH;
2912 }
2913 if (land_allowed && !sea_allowed) {
2914 return UMT_LAND;
2915 }
2916 if (!land_allowed && sea_allowed) {
2917 return UMT_SEA;
2918 }
2919
2920 return unit_move_type_invalid();
2921}
2922
2923/**********************************************************************/
2926void set_unit_move_type(struct unit_class *puclass)
2927{
2928 bool land_moving = FALSE;
2929 bool sea_moving = FALSE;
2930
2931 extra_type_iterate(pextra) {
2932 enum unit_move_type eut = move_type_from_extra(pextra, puclass);
2933
2934 if (eut == UMT_BOTH) {
2935 land_moving = TRUE;
2936 sea_moving = TRUE;
2937 } else if (eut == UMT_LAND) {
2938 land_moving = TRUE;
2939 } else if (eut == UMT_SEA) {
2940 sea_moving = TRUE;
2941 }
2943
2944 terrain_type_iterate(pterrain) {
2945 if (is_native_to_class(puclass, pterrain, NULL)) {
2946 if (is_ocean(pterrain)) {
2947 sea_moving = TRUE;
2948 } else {
2949 land_moving = TRUE;
2950 }
2951 }
2953
2954 if (land_moving && sea_moving) {
2955 puclass->move_type = UMT_BOTH;
2956 } else if (sea_moving) {
2957 puclass->move_type = UMT_SEA;
2958 } else {
2959 /* If unit has no native terrains, it is considered land moving */
2960 puclass->move_type = UMT_LAND;
2961 }
2962}
2963
2964/**********************************************************************/
2967bool utype_is_cityfounder(const struct unit_type *utype)
2968{
2970 /* No unit is allowed to found new cities */
2971 return FALSE;
2972 }
2973
2974 return utype_can_do_action_result(utype, ACTRES_FOUND_CITY);
2975}
2976
2977/**********************************************************************/
2983bool uclass_flag_is_in_use(enum unit_class_flag_id ucflag)
2984{
2985 unit_class_iterate(uclass) {
2986 if (uclass_has_flag(uclass, ucflag)) {
2987 /* Found a user. */
2988 return TRUE;
2989 }
2991
2992 /* No users detected. */
2993 return FALSE;
2994}
2995
2996/**********************************************************************/
3002bool utype_flag_is_in_use(enum unit_type_flag_id uflag)
3003{
3004 unit_type_iterate(putype) {
3005 if (utype_has_flag(putype, uflag)) {
3006 /* Found a user. */
3007 return TRUE;
3008 }
3010
3011 /* No users detected. */
3012 return FALSE;
3013}
bool action_removes_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2312
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3520
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
bool action_creates_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2224
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:488
#define action_enablers_iterate_end
Definition actions.h:526
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_has_result(_act_, _res_)
Definition actions.h:448
#define action_enabler_list_iterate_end
Definition actions.h:457
#define action_by_result_iterate_end
Definition actions.h:492
#define action_iterate_end
Definition actions.h:472
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
#define action_iterate(_act_)
Definition actions.h:467
#define ACTION_ANY
Definition actions.h:290
#define action_id_get_target_kind(act_id)
Definition actions.h:655
int ai_type_number(const struct ai_type *ai)
Definition ai.c:272
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:329
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:367
#define BV_DEFINE(name, bits)
Definition bitvector.h:132
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_CLR(bv, bit)
Definition bitvector.h:86
struct output_type * get_output_type(Output_type_id output)
Definition city.c:633
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Definition city.c:928
#define city_tile(_pcity_)
Definition city.h:544
#define city_owner(_pcity_)
Definition city.h:543
int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, enum combat_bonus_type type)
Definition combat.c:941
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2839
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city 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:73
int int id
Definition editgui_g.h:28
bool effect_universals_value_never_below(enum effect_type type, struct universal *unis, size_t n_unis, int min_value)
Definition effects.c:488
struct @21::@22 reqs
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:883
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:331
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:957
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:810
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:792
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_type_iterate_end
Definition extras.h:297
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_type_list_iterate_end
Definition extras.h:161
#define extra_road_get(_e_)
Definition extras.h:185
@ RPT_CERTAIN
Definition fc_types.h:586
int Unit_Class_id
Definition fc_types.h:388
int action_id
Definition fc_types.h:359
int Unit_type_id
Definition fc_types.h:352
@ O_SHIELD
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
#define UCL_LAST
Definition fc_types.h:387
enum output_type_id Output_type_id
Definition fc_types.h:348
#define _(String)
Definition fcintl.h:67
#define Qn_(String)
Definition fcintl.h:89
void user_flag_init(struct user_flag *flag)
Definition game.c:804
void user_flag_free(struct user_flag *flag)
Definition game.c:813
struct civ_game game
Definition game.c:57
struct city * owner
Definition citydlg.c:219
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
bool great_wonder_is_built(const struct impr_type *pimprove)
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool is_small_wonder(const struct impr_type *pimprove)
struct player * great_wonder_owner(const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
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:299
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
Definition movement.c:327
#define MAX_MOVE_FRAGS
Definition movement.h:27
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * name_translation_get(const struct name_translation *ptrans)
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
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)
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
#define requirement_diplrel_ereq(_id_, _range_, _present_)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:499
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
void strvec_destroy(struct strvec *psv)
action_id id
Definition actions.h:380
bool actor_consuming_always
Definition actions.h:412
enum moves_actor_kind moves_actor
Definition actions.h:432
struct action::@12::@13 is_unit
enum action_result result
Definition actions.h:382
bv_action_sub_results sub_results
Definition actions.h:383
union action::@12 actor
Definition ai.h:50
Definition city.h:309
struct tile * tile
Definition city.h:311
struct packet_ruleset_control control
Definition game.h:83
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
struct veteran_system * veteran
Definition game.h:100
struct requirement_vector reqs
Definition extras.h:102
bool global_advances[A_LAST]
struct unit_list * units
Definition player.h:282
int max
Definition unittype.c:933
int min
Definition unittype.c:932
const struct player * player
enum req_range range
struct universal source
Definition tile.h:49
Unit_Class_id item_number
Definition unittype.h:137
enum unit_move_type move_type
Definition unittype.h:140
struct unit_class_list * subset_movers
Definition unittype.h:160
struct unit_class::@85 cache
struct extra_type_list * refuel_extras
Definition unittype.h:155
struct extra_type_list * native_tile_extras
Definition unittype.h:156
struct extra_type_list * native_bases
Definition unittype.h:157
struct extra_type_list * bonus_roads
Definition unittype.h:158
struct name_translation name
Definition unittype.h:138
struct strvec * helptext
Definition unittype.h:146
bool ruledit_disabled
Definition unittype.h:139
struct extra_type_list * hiding_extras
Definition unittype.h:159
int max_defense_mp_bonus_pct
Definition unittype.h:560
struct unit_class * uclass
Definition unittype.h:537
int pop_cost
Definition unittype.h:493
void * ais[FREECIV_AI_MOD_LAST]
Definition unittype.h:575
struct requirement_vector build_reqs
Definition unittype.h:501
Unit_type_id item_number
Definition unittype.h:482
int defense_strength
Definition unittype.h:496
int build_cost
Definition unittype.h:492
struct veteran_system * veteran
Definition unittype.h:525
const struct unit_type * obsoleted_by
Definition unittype.h:510
int move_rate
Definition unittype.h:497
struct advance * require_advance
Definition unittype.h:500
struct strvec * helptext
Definition unittype.h:552
int scramble_coeff[U_LAST]
Definition unittype.h:564
struct unit_type::@88 cache
struct name_translation name
Definition unittype.h:483
bv_unit_type_roles roles
Definition unittype.h:516
int upkeep[O_LAST]
Definition unittype.h:519
bv_unit_classes disembarks
Definition unittype.h:548
bv_unit_type_flags flags
Definition unittype.h:515
bool ruledit_disabled
Definition unittype.h:484
bv_unit_classes embarks
Definition unittype.h:545
int attack_strength
Definition unittype.h:495
int happy_cost
Definition unittype.h:518
int defense_mp_bonuses_pct[U_LAST]
Definition unittype.h:563
struct combat_bonus_list * bonuses
Definition unittype.h:507
void * ruledit_dlg
Definition unittype.h:485
Definition unit.h:138
const struct unit_type * utype
Definition unit.h:139
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
char * name
Definition game.h:74
char * helptxt
Definition game.h:75
int base_raise_chance
Definition unittype.h:471
struct name_translation name
Definition unittype.h:468
int work_raise_chance
Definition unittype.h:472
struct veteran_level * definitions
Definition unittype.h:478
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:995
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define terrain_type_iterate(_p)
Definition terrain.h:358
#define is_ocean(pterrain)
Definition terrain.h:287
#define terrain_type_iterate_end
Definition terrain.h:364
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
enum citytile_type citytile
Definition fc_types.h:613
enum ustate_prop unit_state
Definition fc_types.h:631
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:219
#define unit_owner(_pu)
Definition unit.h:387
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
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:1176
int utype_buy_gold_cost(const struct city *pcity, const struct unit_type *punittype, int shields_in_stock)
Definition unittype.c:1544
void unit_types_init(void)
Definition unittype.c:2394
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:995
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1684
void set_unit_class_caches(struct unit_class *pclass)
Definition unittype.c:2758
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2319
static struct unit_type unit_types[U_LAST]
Definition unittype.c:44
struct unit_type * role_units_iterate(int role, role_unit_callback cb, void *data)
Definition unittype.c:2265
bool utype_action_takes_all_mp(const struct unit_type *putype, struct action *paction)
Definition unittype.c:1243
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2646
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool utype_has_class_flag(const struct unit_type *ptype, enum unit_class_flag_id flag)
Definition unittype.c:1709
void user_unit_type_flags_init(void)
Definition unittype.c:1916
int utype_pays_mp_for_action_base(const struct action *paction, const struct unit_type *putype)
Definition unittype.c:1433
bool utype_player_already_has_this(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1993
static struct range * moves_left_range(struct requirement_vector *reqs)
Definition unittype.c:942
bool utype_can_freely_unload(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:294
#define ACTION_HOSTILE
Definition unittype.c:383
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1906
bool utype_pays_for_regular_move_to_tgt(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1382
static void unit_type_free(struct unit_type *punittype)
Definition unittype.c:2414
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Definition unittype.c:2284
static void precalc_one(int i, bool(*func_has)(const struct unit_type *, int))
Definition unittype.c:2180
static struct user_flag user_class_flags[MAX_NUM_USER_UCLASS_FLAGS]
Definition unittype.c:53
static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:638
bool utype_can_remove_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:235
int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
Definition unittype.c:1528
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
static bv_unit_types utype_act_takes_all_mp_ustate_cache[ACTION_COUNT][USP_COUNT]
Definition unittype.c:565
bool unit_has_class_flag(const struct unit *punit, enum unit_class_flag_id flag)
Definition unittype.c:1701
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1301
static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:641
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
enum unit_move_type utype_move_type(const struct unit_type *punittype)
Definition unittype.c:1603
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2370
Unit_Class_id uclass_count(void)
Definition unittype.c:2493
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2967
const struct unit_class * unit_class_array_last(void)
Definition unittype.c:2482
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1819
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
struct unit_type * unit_type_array_first(void)
Definition unittype.c:58
void unit_class_flags_free(void)
Definition unittype.c:2459
bool uclass_flag_is_in_use(enum unit_class_flag_id ucflag)
Definition unittype.c:2983
#define MAX_UNIT_ROLES
Definition unittype.c:42
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:193
static enum unit_move_type move_type_from_extra(struct extra_type *pextra, struct unit_class *puc)
Definition unittype.c:2859
void set_unit_move_type(struct unit_class *puclass)
Definition unittype.c:2926
static bool action_is_hostile(action_id act_id)
Definition unittype.c:304
static bv_diplrel_all_reqs dipl_rel_tile_other_tgt_a_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:640
void unit_type_action_cache_init(void)
Definition unittype.c:983
static void local_dipl_rel_tile_other_tgt_action_cache_set(struct unit_type *putype)
Definition unittype.c:796
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
void set_unit_type_caches(struct unit_type *ptype)
Definition unittype.c:2817
bool utype_may_act_move_frags(const struct unit_type *punit_type, const action_id act_id, const int move_fragments)
Definition unittype.c:1110
const struct veteran_system * utype_veteran_system(const struct unit_type *punittype)
Definition unittype.c:2615
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Definition unittype.c:1281
int num_role_units(int role)
Definition unittype.c:2251
static bool first_init
Definition unittype.c:2172
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT]
Definition unittype.c:523
static bool utype_can_do_action_role(const struct unit_type *putype, const int role)
Definition unittype.c:505
void unit_types_free(void)
Definition unittype.c:2433
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:431
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2345
void role_unit_precalcs(void)
Definition unittype.c:2223
struct unit_class * uclass_by_number(const Unit_Class_id id)
Definition unittype.c:2524
bool utype_can_create_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:211
static void local_dipl_rel_action_cache_set(struct unit_type *putype)
Definition unittype.c:716
static void tgt_citytile_act_cache_set(struct unit_type *putype)
Definition unittype.c:868
bool utype_can_freely_load(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:282
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:2719
#define MOVES_LEFT_INFINITY
Definition unittype.c:936
#define requirement_citytile_ereq(_id_, _present_)
Definition unittype.c:633
Unit_type_id utype_count(void)
Definition unittype.c:80
bool can_player_build_unit_direct(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2015
static void unit_state_action_cache_set(struct unit_type *putype)
Definition unittype.c:648
static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:637
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2661
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:1445
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:1007
void veteran_system_destroy(struct veteran_system *vsystem)
Definition unittype.c:2706
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2546
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:1027
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:202
static void unit_can_act_cache_set(struct unit_type *putype)
Definition unittype.c:398
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:1259
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2631
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:258
static bv_unit_types unit_can_act_cache[ACTION_AND_FAKES]
Definition unittype.c:392
void unit_classes_free(void)
Definition unittype.c:2576
void unit_type_action_cache_set(struct unit_type *ptype)
Definition unittype.c:967
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1693
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1894
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1271
void unit_type_flags_free(void)
Definition unittype.c:2447
static void utype_act_takes_all_mp_cache_set(struct unit_type *putype)
Definition unittype.c:529
static void utype_act_takes_all_mp_ustate_cache_set(struct unit_type *putype)
Definition unittype.c:572
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1957
bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
Definition unittype.c:2674
void user_unit_class_flags_init(void)
Definition unittype.c:1852
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:1088
struct unit_class * unit_class_by_rule_name(const char *s)
Definition unittype.c:1836
struct unit_type * unit_type_by_translated_name(const char *name)
Definition unittype.c:1804
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1969
const char * utype_values_string(const struct unit_type *punittype)
Definition unittype.c:1648
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2741
struct unit_class * unit_class_array_first(void)
Definition unittype.c:2471
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
void unit_classes_init(void)
Definition unittype.c:2554
bool utype_flag_is_in_use(enum unit_type_flag_id uflag)
Definition unittype.c:3002
#define ACTION_AND_FAKES
Definition unittype.c:386
static struct user_flag user_type_flags[MAX_NUM_USER_UNIT_FLAGS]
Definition unittype.c:51
int utype_pop_value(const struct unit_type *punittype, const struct city *pcity)
Definition unittype.c:1580
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:270
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2749
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1864
bool can_player_build_unit_later(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2150
static struct unit_class unit_classes[UCL_LAST]
Definition unittype.c:45
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1595
#define requirement_unit_state_ereq(_id_, _present_)
Definition unittype.c:631
void role_unit_precalcs_free(void)
Definition unittype.c:2208
struct veteran_system * veteran_system_new(int count)
Definition unittype.c:2688
Unit_Class_id uclass_number(const struct unit_class *pclass)
Definition unittype.c:2515
bool can_player_build_unit_now(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2131
bool utype_can_do_action_sub_result(const struct unit_type *putype, enum action_sub_result sub_result)
Definition unittype.c:480
static struct unit_type ** with_role[MAX_UNIT_ROLES]
Definition unittype.c:2174
bool utype_is_unmoved_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1340
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:515
bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1048
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
static int n_with_role[MAX_UNIT_ROLES]
Definition unittype.c:2173
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:1069
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1928
int utype_happy_cost(const struct unit_type *ut, const struct player *pplayer)
Definition unittype.c:175
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1720
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1669
const struct unit_type * unit_type_array_last(void)
Definition unittype.c:69
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1783
#define UCF_LAST_USER_FLAG
Definition unittype.h:112
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:822
#define combat_bonus_list_iterate_end
Definition unittype.h:463
#define L_FIRST
Definition unittype.h:333
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:461
#define unit_class_iterate(_p)
Definition unittype.h:876
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:316
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define UTYF_LAST_USER_FLAG
Definition unittype.h:315
#define L_LAST
Definition unittype.h:420
bool(* role_unit_callback)(struct unit_type *ptype, void *data)
Definition unittype.h:709
#define unit_type_iterate(_p)
Definition unittype.h:838
#define U_LAST
Definition unittype.h:40
#define uclass_index(_c_)
Definition unittype.h:729
#define unit_class_iterate_end
Definition unittype.h:883
#define unit_type_iterate_end
Definition unittype.h:845
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:113
#define U_NOT_OBSOLETED
Definition unittype.h:509