Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/unittype.c Source File

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
44 static struct unit_type unit_types[U_LAST];
45 static struct unit_class unit_classes[UCL_LAST];
46/* the unit_types and unit_classes arrays are now setup in:
47 server/ruleset.c (for the server)
48 client/packhand.c (for the client)
49*/
50
51 static struct user_flag user_type_flags[MAX_NUM_USER_UNIT_FLAGS];
52
53 static struct user_flag user_class_flags[MAX_NUM_USER_UCLASS_FLAGS];
54
55/**********************************************************************/
58 struct unit_type *unit_type_array_first(void)
59{
60 if (game.control.num_unit_types > 0) {
61 return unit_types;
62 }
63 return NULL;
64}
65
66/**********************************************************************/
69 const struct unit_type *unit_type_array_last(void)
70{
71 if (game.control.num_unit_types > 0) {
72 return &unit_types[game.control.num_unit_types - 1];
73 }
74 return NULL;
75}
76
77/**********************************************************************/
80 Unit_type_id utype_count(void)
81{
82 return game.control.num_unit_types;
83}
84
85/**********************************************************************/
91 Unit_type_id utype_index(const struct unit_type *punittype)
92{
93 fc_assert_ret_val(punittype, -1);
94 return punittype - unit_types;
95}
96
97/**********************************************************************/
100 Unit_type_id utype_number(const struct unit_type *punittype)
101{
102 fc_assert_ret_val(punittype, -1);
103 return punittype->item_number;
104}
105
106/**********************************************************************/
112 struct unit_type *utype_by_number(const Unit_type_id id)
113{
114 if (id < 0 || id >= game.control.num_unit_types) {
115 return NULL;
116 }
117 return &unit_types[id];
118}
119
120/**********************************************************************/
123 const struct unit_type *unit_type_get(const struct unit *punit)
124{
125 fc_assert_ret_val(NULL != punit, NULL);
126 return punit->utype;
127}
128
129/**********************************************************************/
132 int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer,
133 Output_type_id otype)
134{
135 int val = ut->upkeep[otype], gold_upkeep_factor;
136
137 if (BV_ISSET(ut->flags, UTYF_FANATIC)
138 && get_player_bonus(pplayer, EFT_FANATICS) > 0) {
139 /* Special case: fanatics have no upkeep under fanaticism. */
140 return 0;
141 }
142
143 /* switch shield upkeep to gold upkeep if
144 - the effect 'EFT_SHIELD2GOLD_FACTOR' is non-zero (it gives the
145 conversion factor in percent) and
146 - the unit has the corresponding flag set (UTYF_SHIELD2GOLD)
147 FIXME: Should the ai know about this? */
148 if (utype_has_flag(ut, UTYF_SHIELD2GOLD)
149 && (otype == O_GOLD || otype == O_SHIELD)) {
150 gold_upkeep_factor = get_player_bonus(pplayer, EFT_SHIELD2GOLD_FACTOR);
151 if (gold_upkeep_factor > 0) {
152 switch (otype) {
153 case O_GOLD:
154 val = ceil((0.01 * gold_upkeep_factor) * ut->upkeep[O_SHIELD]);
155 break;
156 case O_SHIELD:
157 val = 0;
158 break;
159 default:
160 fc_assert(otype == O_GOLD || otype == O_SHIELD);
161 break;
162 }
163 }
164 }
165
166 val *= get_player_output_bonus(pplayer, get_output_type(otype),
167 EFT_UPKEEP_FACTOR);
168 return val;
169}
170
171/**********************************************************************/
175 int 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/**********************************************************************/
184 bool 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/**********************************************************************/
193 bool 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/**********************************************************************/
202 bool 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/**********************************************************************/
211 bool 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 }
226 } action_iterate_end;
227
228 return FALSE;
229}
230
231/**********************************************************************/
235 bool 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 }
250 } action_iterate_end;
251
252 return FALSE;
253}
254
255/**********************************************************************/
258 bool 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
264 && utype_can_take_over(unit_type_get(punit));
265}
266
267/**********************************************************************/
270 bool 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/**********************************************************************/
282 bool 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/**********************************************************************/
294 bool 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/**********************************************************************/
304 static 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. */
378 fc_assert(FALSE);
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. */
392 static bv_unit_types unit_can_act_cache[ACTION_AND_FAKES];
393
394/**********************************************************************/
398 static 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));
403 } action_iterate_end;
404 BV_CLR(unit_can_act_cache[ACTION_ANY], utype_index(putype));
405 BV_CLR(unit_can_act_cache[ACTION_HOSTILE], 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)
413 && requirement_fulfilled_by_unit_type(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));
419 BV_SET(unit_can_act_cache[ACTION_ANY], utype_index(putype));
420 if (action_is_hostile(enabler->action)) {
421 BV_SET(unit_can_act_cache[ACTION_HOSTILE], utype_index(putype));
422 }
423 }
424 } action_enablers_iterate_end;
425}
426
427/**********************************************************************/
431 bool utype_may_act_at_all(const struct unit_type *putype)
432{
433 return utype_can_do_action(putype, ACTION_ANY);
434}
435
436/**********************************************************************/
443 bool 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/**********************************************************************/
459 bool utype_can_do_action_result(const struct unit_type *putype,
460 enum action_result result)
461{
462 fc_assert_ret_val(putype, FALSE);
463
464 action_by_result_iterate(paction, result) {
465 if (utype_can_do_action(putype, paction->id)) {
466 return TRUE;
467 }
468 } action_by_result_iterate_end;
469
470 return FALSE;
471}
472
473/**********************************************************************/
480 bool utype_can_do_action_sub_result(const struct unit_type *putype,
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 }
496 } action_iterate_end;
497
498 return FALSE;
499}
500
501/**********************************************************************/
505 static 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/**********************************************************************/
515 bool 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. */
523 static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT];
524
525/**********************************************************************/
529 static void utype_act_takes_all_mp_cache_set(struct unit_type *putype)
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),
548 MAX_MOVE_FRAGS)) {
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));
553 BV_SET(utype_act_takes_all_mp_cache[paction->id], utype_index(putype));
554 } else {
555 /* Clear old value in case it was set. */
556 BV_CLR(utype_act_takes_all_mp_cache[paction->id], utype_index(putype));
557 }
558 } action_iterate_end;
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/**********************************************************************/
572 static void utype_act_takes_all_mp_ustate_cache_set(struct unit_type *putype)
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),
596 MAX_MOVE_FRAGS)) {
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));
603 BV_SET(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
604 utype_index(putype));
605 } else {
606 /* Clear old value in case it was set. */
607 BV_CLR(utype_act_takes_all_mp_ustate_cache[paction->id][prop],
608 utype_index(putype));
609 }
610 }
611 } action_iterate_end;
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 */
620 BV_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 */
628 BV_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 */
637 static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES];
638 static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES];
639static bv_diplrel_all_reqs
640dipl_rel_tile_other_tgt_a_cache[U_LAST][ACTION_AND_FAKES];
641 static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES];
642
643/**********************************************************************/
648 static 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]);
657 } action_iterate_end;
658 BV_CLR_ALL(ustate_act_cache[uidx][ACTION_ANY]);
659 BV_CLR_ALL(ustate_act_cache[uidx][ACTION_HOSTILE]);
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) {
681 if (requirement_fulfilled_by_unit_type(putype,
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],
690 requirement_unit_state_ereq(req.source.value.unit_state,
691 !req.present));
692 if (action_is_hostile(enabler->action)) {
693 BV_SET(ustate_act_cache[utype_index(putype)][ACTION_HOSTILE],
694 requirement_unit_state_ereq(req.source.value.unit_state,
695 !req.present));
696 }
697 BV_SET(ustate_act_cache[utype_index(putype)][ACTION_ANY],
698 requirement_unit_state_ereq(req.source.value.unit_state,
699 !req.present));
700 }
701 present = !present;
702 } while (!present);
703 }
704 } action_enablers_iterate_end;
705 }
706}
707
708/**********************************************************************/
716 static void local_dipl_rel_action_cache_set(struct unit_type *putype)
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]);
726 } action_iterate_end;
727 BV_CLR_ALL(dipl_rel_action_cache[uidx][ACTION_ANY]);
728 BV_CLR_ALL(dipl_rel_action_cache[uidx][ACTION_HOSTILE]);
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) {
758 if (requirement_fulfilled_by_unit_type(putype,
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],
771 requirement_diplrel_ereq(req.source.value.diplrel,
772 REQ_RANGE_LOCAL, req.present));
773 if (action_is_hostile(enabler->action)) {
774 BV_SET(dipl_rel_action_cache[uidx][ACTION_HOSTILE],
775 requirement_diplrel_ereq(req.source.value.diplrel,
776 REQ_RANGE_LOCAL,
777 req.present));
778 }
779 BV_SET(dipl_rel_action_cache[uidx][ACTION_ANY],
780 requirement_diplrel_ereq(req.source.value.diplrel,
781 REQ_RANGE_LOCAL, req.present));
782 }
783 present = !present;
784 } while (!present);
785 }
786 } action_enablers_iterate_end;
787 }
788}
789
790/**********************************************************************/
795static void
796local_dipl_rel_tile_other_tgt_action_cache_set(struct unit_type *putype)
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) {
805 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][act_id]);
806 } action_iterate_end;
807 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_ANY]);
808 BV_CLR_ALL(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_HOSTILE]);
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) {
833 if (requirement_fulfilled_by_unit_type(putype,
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],
844 requirement_diplrel_ereq(req.source.value.diplrel,
845 REQ_RANGE_LOCAL, req.present));
846 if (action_is_hostile(enabler->action)) {
847 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_HOSTILE],
848 requirement_diplrel_ereq(req.source.value.diplrel,
849 REQ_RANGE_LOCAL,
850 req.present));
851 }
852 BV_SET(dipl_rel_tile_other_tgt_a_cache[uidx][ACTION_ANY],
853 requirement_diplrel_ereq(req.source.value.diplrel,
854 REQ_RANGE_LOCAL, req.present));
855 }
856 present = !present;
857 } while (!present);
858 }
859 } action_enablers_iterate_end;
860 }
861}
862
863/**********************************************************************/
868 static 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]);
877 } action_iterate_end;
878 BV_CLR_ALL(ctile_tgt_act_cache[uidx][ACTION_ANY]);
879 BV_CLR_ALL(ctile_tgt_act_cache[uidx][ACTION_HOSTILE]);
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) {
902 if (requirement_fulfilled_by_unit_type(putype,
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],
912 requirement_citytile_ereq(req.source.value.citytile,
913 !req.present));
914 if (action_is_hostile(enabler->action)) {
915 BV_SET(
916 ctile_tgt_act_cache[utype_index(putype)][ACTION_HOSTILE],
917 requirement_citytile_ereq(req.source.value.citytile,
918 !req.present));
919 }
920 BV_SET(ctile_tgt_act_cache[utype_index(putype)][ACTION_ANY],
921 requirement_citytile_ereq(req.source.value.citytile,
922 !req.present));
923 }
924 present = !present;
925 } while (!present);
926 }
927 } action_enablers_iterate_end;
928 }
929}
930
931 struct range {
932 int min;
933 int max;
934};
935
936#define MOVES_LEFT_INFINITY -1
937
938/**********************************************************************/
942 static 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
949 requirement_vector_iterate(reqs, preq) {
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 }
957 } requirement_vector_iterate_end;
958
959 return prange;
960}
961
962/**********************************************************************/
967 void unit_type_action_cache_set(struct unit_type *ptype)
968{
969 unit_can_act_cache_set(ptype);
970 unit_state_action_cache_set(ptype);
971 local_dipl_rel_action_cache_set(ptype);
972 local_dipl_rel_tile_other_tgt_action_cache_set(ptype);
973 tgt_citytile_act_cache_set(ptype);
974
975 utype_act_takes_all_mp_cache_set(ptype);
976 utype_act_takes_all_mp_ustate_cache_set(ptype);
977}
978
979/**********************************************************************/
983 void unit_type_action_cache_init(void)
984{
985 unit_type_iterate(u) {
986 unit_type_action_cache_set(u);
987 } unit_type_iterate_end;
988}
989
990/**********************************************************************/
995 bool 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/**********************************************************************/
1007 bool 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/**********************************************************************/
1027 bool utype_can_do_action_result_when_ustate(const struct unit_type *putype,
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 }
1038 } action_by_result_iterate_end;
1039
1040 return FALSE;
1041}
1042
1043/**********************************************************************/
1048 bool 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/**********************************************************************/
1069 bool 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
1088utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type,
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/**********************************************************************/
1110 bool 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 }
1131 } action_iterate_end;
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
1143 action_enabler_list_iterate(action_enablers_for_action(act_id),
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);
1163 } action_enabler_list_iterate_end;
1164
1165 return FALSE;
1166}
1167
1168/**********************************************************************/
1176 bool 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 }
1196 } action_iterate_end;
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
1219 action_enabler_list_iterate(action_enablers_for_action(act_id),
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 }
1231 } action_enabler_list_iterate_end;
1232
1233 return FALSE;
1234}
1235
1236/**********************************************************************/
1243 bool 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/**********************************************************************/
1259 bool utype_action_takes_all_mp_if_ustate_is(const struct unit_type *putype,
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/**********************************************************************/
1271 bool 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/**********************************************************************/
1281 bool 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 }
1292 } action_by_result_iterate_end;
1293
1294 return FALSE;
1295}
1296
1297/**********************************************************************/
1301 bool 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/**********************************************************************/
1340 bool 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/**********************************************************************/
1382 bool utype_pays_for_regular_move_to_tgt(const struct action *paction,
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/**********************************************************************/
1433 int 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/**********************************************************************/
1445 int utype_pays_mp_for_action_estimate(const struct civ_map *nmap,
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/**********************************************************************/
1490 int 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/**********************************************************************/
1520 int 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/**********************************************************************/
1528 int 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/**********************************************************************/
1536 int unit_build_shield_cost_base(const struct unit *punit)
1537{
1538 return utype_build_shield_cost_base(unit_type_get(punit));
1539}
1540
1541/**********************************************************************/
1544 int 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/**********************************************************************/
1580 int 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/**********************************************************************/
1595 int unit_pop_value(const struct unit *punit)
1596{
1597 return unit_type_get(punit)->pop_cost;
1598}
1599
1600/**********************************************************************/
1603 enum unit_move_type utype_move_type(const struct unit_type *punittype)
1604{
1605 return utype_class(punittype)->move_type;
1606}
1607
1608/**********************************************************************/
1612 const char *utype_name_translation(const struct unit_type *punittype)
1613{
1614 return name_translation_get(&punittype->name);
1615}
1616
1617/**********************************************************************/
1621 const char *unit_name_translation(const struct unit *punit)
1622{
1623 return utype_name_translation(unit_type_get(punit));
1624}
1625
1626/**********************************************************************/
1630 const char *utype_rule_name(const struct unit_type *punittype)
1631{
1632 return rule_name_get(&punittype->name);
1633}
1634
1635/**********************************************************************/
1639 const char *unit_rule_name(const struct unit *punit)
1640{
1641 return utype_rule_name(unit_type_get(punit));
1642}
1643
1644/**********************************************************************/
1648 const 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/**********************************************************************/
1669 const 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/**********************************************************************/
1684 const char *uclass_name_translation(const struct unit_class *pclass)
1685{
1686 return name_translation_get(&pclass->name);
1687}
1688
1689/**********************************************************************/
1693 const char *uclass_rule_name(const struct unit_class *pclass)
1694{
1695 return rule_name_get(&pclass->name);
1696}
1697
1698/**********************************************************************/
1701 bool 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/**********************************************************************/
1709 bool 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/**********************************************************************/
1720 bool 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"),
1727 utype_name_translation(get_role_unit(flag, 0)));
1728 } else {
1729 astr_set(astr, _("%s and similar units"),
1730 utype_name_translation(get_role_unit(flag, 0)));
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/**********************************************************************/
1755 const 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/**********************************************************************/
1783 int 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/**********************************************************************/
1804 struct unit_type *unit_type_by_translated_name(const char *name)
1805{
1806 unit_type_iterate(punittype) {
1807 if (0 == strcmp(utype_name_translation(punittype), name)) {
1808 return punittype;
1809 }
1810 } unit_type_iterate_end;
1811
1812 return NULL;
1813}
1814
1815/**********************************************************************/
1819 struct unit_type *unit_type_by_rule_name(const char *name)
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 }
1827 } unit_type_iterate_end;
1828
1829 return NULL;
1830}
1831
1832/**********************************************************************/
1836 struct unit_class *unit_class_by_rule_name(const char *s)
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 }
1844 } unit_class_iterate_end;
1845
1846 return NULL;
1847}
1848
1849/**********************************************************************/
1852 void user_unit_class_flags_init(void)
1853{
1854 int i;
1855
1856 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
1857 user_flag_init(&user_class_flags[i]);
1858 }
1859}
1860
1861/**********************************************************************/
1864 void 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) {
1873 FC_FREE(user_class_flags[ufid].name);
1874 user_class_flags[ufid].name = NULL;
1875 }
1876
1877 if (name && name[0] != '\0') {
1878 user_class_flags[ufid].name = fc_strdup(name);
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/**********************************************************************/
1894 const 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/**********************************************************************/
1906 const 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/**********************************************************************/
1916 void user_unit_type_flags_init(void)
1917{
1918 int i;
1919
1920 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
1921 user_flag_init(&user_type_flags[i]);
1922 }
1923}
1924
1925/**********************************************************************/
1928 void 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) {
1936 FC_FREE(user_type_flags[ufid].name);
1937 user_type_flags[ufid].name = NULL;
1938 }
1939
1940 if (name && name[0] != '\0') {
1941 user_type_flags[ufid].name = fc_strdup(name);
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/**********************************************************************/
1957 const 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/**********************************************************************/
1969 const 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/**********************************************************************/
1979 bool utype_player_already_has_this_unique(const struct player *pplayer,
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/**********************************************************************/
1993 bool 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 }
2004 } unit_list_iterate_end;
2005
2006 /* The player doesn't already have one. */
2007 return FALSE;
2008}
2009
2010/**********************************************************************/
2015 bool can_player_build_unit_direct(const struct player *p,
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)
2046 && game.scenario.prevent_new_cities) {
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 {
2073 if (!can_player_build_improvement_direct(
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 }
2086 } requirement_vector_iterate_end;
2087
2088 if (research_invention_state(research_get(p),
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
2112 if (!game.info.global_advances[advance_index(punittype->require_advance)]) {
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/**********************************************************************/
2131 bool can_player_build_unit_now(const struct player *p,
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/**********************************************************************/
2150 bool can_player_build_unit_later(const struct player *p,
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**************************************************************************/
2172 static bool first_init = TRUE;
2173 static int n_with_role[MAX_UNIT_ROLES];
2174 static struct unit_type **with_role[MAX_UNIT_ROLES];
2175
2176/**********************************************************************/
2180 static 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);
2187 unit_type_iterate(u) {
2188 if (func_has(u, i)) {
2189 n_with_role[i]++;
2190 }
2191 } unit_type_iterate_end;
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;
2196 unit_type_iterate(u) {
2197 if (func_has(u, i)) {
2198 with_role[i][j++] = u;
2199 }
2200 } unit_type_iterate_end;
2201 fc_assert(j == n_with_role[i]);
2202 }
2203}
2204
2205/**********************************************************************/
2208 void role_unit_precalcs_free(void)
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/**********************************************************************/
2223 void role_unit_precalcs(void)
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 {
2233 role_unit_precalcs_free();
2234 }
2235
2236 for (i = 0; i <= UTYF_LAST_USER_FLAG; i++) {
2237 precalc_one(i, utype_has_flag);
2238 }
2239 for (i = L_FIRST; i < L_LAST; i++) {
2240 precalc_one(i, utype_has_role);
2241 }
2242 for (i = L_LAST; i < MAX_UNIT_ROLES; i++) {
2243 precalc_one(i, utype_can_do_action_role);
2244 }
2245 first_init = FALSE;
2246}
2247
2248/**********************************************************************/
2251 int 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);
2256 fc_assert_ret_val(!first_init, -1);
2257 return n_with_role[role];
2258}
2259
2260/**********************************************************************/
2265 struct 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/**********************************************************************/
2284 struct unit_type *role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
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/**********************************************************************/
2301 struct 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);
2306 fc_assert_ret_val(!first_init, 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/**********************************************************************/
2319 struct 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);
2327 fc_assert_ret_val(!first_init, 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/**********************************************************************/
2345 struct 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);
2353 fc_assert_ret_val(!first_init, 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/**********************************************************************/
2370 struct 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);
2378 fc_assert_ret_val(!first_init, 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/**********************************************************************/
2394 void unit_types_init(void)
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();
2406 unit_types[i].ruledit_disabled = FALSE;
2407 unit_types[i].ruledit_dlg = NULL;
2408 }
2409}
2410
2411/**********************************************************************/
2414 static 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);
2426 } combat_bonus_list_iterate_end;
2427 combat_bonus_list_destroy(punittype->bonuses);
2428}
2429
2430/**********************************************************************/
2433 void unit_types_free(void)
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++) {
2440 unit_type_free(unit_types + i);
2441 }
2442}
2443
2444/**********************************************************************/
2447 void unit_type_flags_free(void)
2448{
2449 int i;
2450
2451 for (i = 0; i < MAX_NUM_USER_UNIT_FLAGS; i++) {
2452 user_flag_free(&user_type_flags[i]);
2453 }
2454}
2455
2456/**********************************************************************/
2459 void unit_class_flags_free(void)
2460{
2461 int i;
2462
2463 for (i = 0; i < MAX_NUM_USER_UCLASS_FLAGS; i++) {
2464 user_flag_free(&user_class_flags[i]);
2465 }
2466}
2467
2468/**********************************************************************/
2471 struct unit_class *unit_class_array_first(void)
2472{
2473 if (game.control.num_unit_classes > 0) {
2474 return unit_classes;
2475 }
2476 return NULL;
2477}
2478
2479/**********************************************************************/
2482 const struct unit_class *unit_class_array_last(void)
2483{
2484 if (game.control.num_unit_classes > 0) {
2485 return &unit_classes[game.control.num_unit_classes - 1];
2486 }
2487 return NULL;
2488}
2489
2490/**********************************************************************/
2493 Unit_Class_id uclass_count(void)
2494{
2495 return game.control.num_unit_classes;
2496}
2497
2498#ifndef uclass_index
2499/**********************************************************************/
2505 Unit_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/**********************************************************************/
2515 Unit_Class_id uclass_number(const struct unit_class *pclass)
2516{
2517 fc_assert_ret_val(pclass, -1);
2518 return pclass->item_number;
2519}
2520
2521/**********************************************************************/
2524 struct unit_class *uclass_by_number(const Unit_Class_id id)
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/**********************************************************************/
2546 struct unit_class *unit_class_get(const struct unit *punit)
2547{
2548 return utype_class(unit_type_get(punit));
2549}
2550
2551/**********************************************************************/
2554 void unit_classes_init(void)
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++) {
2561 unit_classes[i].item_number = i;
2562 unit_classes[i].cache.refuel_extras = NULL;
2563 unit_classes[i].cache.native_tile_extras = NULL;
2564 unit_classes[i].cache.native_bases = NULL;
2565 unit_classes[i].cache.bonus_roads = NULL;
2566 unit_classes[i].cache.hiding_extras = NULL;
2567 unit_classes[i].cache.subset_movers = NULL;
2568 unit_classes[i].helptext = NULL;
2569 unit_classes[i].ruledit_disabled = FALSE;
2570 }
2571}
2572
2573/**********************************************************************/
2576 void unit_classes_free(void)
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);
2583 unit_classes[i].cache.refuel_extras = NULL;
2584 }
2585 if (unit_classes[i].cache.native_tile_extras != NULL) {
2586 extra_type_list_destroy(unit_classes[i].cache.native_tile_extras);
2587 unit_classes[i].cache.native_tile_extras = NULL;
2588 }
2589 if (unit_classes[i].cache.native_bases != NULL) {
2590 extra_type_list_destroy(unit_classes[i].cache.native_bases);
2591 unit_classes[i].cache.native_bases = NULL;
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);
2599 unit_classes[i].cache.hiding_extras = NULL;
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) {
2605 strvec_destroy(unit_classes[i].helptext);
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/**********************************************************************/
2646 const 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/**********************************************************************/
2661 int 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/**********************************************************************/
2674 bool 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/**********************************************************************/
2688 struct veteran_system *veteran_system_new(int count)
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/**********************************************************************/
2706 void veteran_system_destroy(struct veteran_system *vsystem)
2707{
2708 if (vsystem) {
2709 if (vsystem->definitions) {
2710 free(vsystem->definitions);
2711 }
2712 free(vsystem);
2713 }
2714}
2715
2716/**********************************************************************/
2719 void veteran_system_definition(struct veteran_system *vsystem, int level,
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/**********************************************************************/
2741 void *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/**********************************************************************/
2749 void 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/**********************************************************************/
2758 void set_unit_class_caches(struct unit_class *pclass)
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 }
2787 } extra_type_iterate_end;
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 }
2797 } terrain_type_iterate_end;
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 }
2805 } extra_type_list_iterate_end;
2806 }
2807
2808 if (subset_mover) {
2809 unit_class_list_append(pclass->cache.subset_movers, pcharge);
2810 }
2811 } unit_class_iterate_end;
2812}
2813
2814/**********************************************************************/
2817 void set_unit_type_caches(struct unit_type *ptype)
2818{
2819 ptype->cache.max_defense_mp_bonus_pct = -FC_INFINITY;
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 }
2853 } unit_type_iterate_end;
2854}
2855
2856/**********************************************************************/
2859 static 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 }
2908 } requirement_vector_iterate_end;
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/**********************************************************************/
2926 void 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 }
2942 } extra_type_iterate_end;
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 }
2952 } terrain_type_iterate_end;
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/**********************************************************************/
2967 bool utype_is_cityfounder(const struct unit_type *utype)
2968{
2969 if (game.scenario.prevent_new_cities) {
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/**********************************************************************/
2983 bool 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 }
2990 } unit_class_iterate_end;
2991
2992 /* No users detected. */
2993 return FALSE;
2994}
2995
2996/**********************************************************************/
3002 bool 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 }
3009 } unit_type_iterate_end;
3010
3011 /* No users detected. */
3012 return FALSE;
3013}
action_removes_extra
bool action_removes_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2312
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
action_actor_utype_hard_reqs_ok
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3520
action_rule_name
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
action_id_rule_name
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
action_creates_extra
bool action_creates_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2224
action_enablers_for_action
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:488
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:526
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:448
action_enabler_list_iterate_end
#define action_enabler_list_iterate_end
Definition actions.h:457
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:492
action_iterate_end
#define action_iterate_end
Definition actions.h:472
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
action_enabler_list_iterate
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
action_iterate
#define action_iterate(_act_)
Definition actions.h:467
ACTION_ANY
#define ACTION_ANY
Definition actions.h:290
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:655
ai_type_number
int ai_type_number(const struct ai_type *ai)
Definition ai.c:272
ai.h
astr_build_or_list
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:329
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
astr_build_and_list
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:367
astring.h
BV_DEFINE
#define BV_DEFINE(name, bits)
Definition bitvector.h:132
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_CLR
#define BV_CLR(bv, bit)
Definition bitvector.h:86
get_output_type
struct output_type * get_output_type(Output_type_id output)
Definition city.c:632
can_city_build_unit_now
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Definition city.c:925
city_tile
#define city_tile(_pcity_)
Definition city.h:544
city_owner
#define city_owner(_pcity_)
Definition city.h:543
combat_bonus_against
int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, enum combat_bonus_type type)
Definition combat.c:941
combat.h
base
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2839
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
id
int int id
Definition editgui_g.h:28
effect_universals_value_never_below
bool effect_universals_value_never_below(enum effect_type type, struct universal *unis, size_t n_unis, int min_value)
Definition effects.c:488
reqs
struct @21::@22 reqs
get_player_output_bonus
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:883
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
effect_cumulative_max
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:331
get_unittype_bonus
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:957
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
extra_has_flag
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:810
is_native_extra_to_uclass
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:792
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:291
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:297
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:196
extra_type_list_iterate_end
#define extra_type_list_iterate_end
Definition extras.h:161
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:185
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:586
Unit_Class_id
int Unit_Class_id
Definition fc_types.h:388
action_id
int action_id
Definition fc_types.h:359
Unit_type_id
int Unit_type_id
Definition fc_types.h:352
O_SHIELD
@ O_SHIELD
Definition fc_types.h:91
O_GOLD
@ O_GOLD
Definition fc_types.h:91
UCL_LAST
#define UCL_LAST
Definition fc_types.h:387
Output_type_id
enum output_type_id Output_type_id
Definition fc_types.h:348
fcintl.h
_
#define _(String)
Definition fcintl.h:67
Qn_
#define Qn_(String)
Definition fcintl.h:89
user_flag_init
void user_flag_init(struct user_flag *flag)
Definition game.c:804
user_flag_free
void user_flag_free(struct user_flag *flag)
Definition game.c:813
game
struct civ_game game
Definition game.c:57
game.h
government.h
owner
struct city * owner
Definition citydlg.c:219
can_player_build_improvement_direct
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
Definition improvement.c:659
great_wonder_is_built
bool great_wonder_is_built(const struct impr_type *pimprove)
Definition improvement.c:955
great_wonder_is_destroyed
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
Definition improvement.c:966
city_from_wonder
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:872
is_great_wonder
bool is_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:767
is_small_wonder
bool is_small_wonder(const struct impr_type *pimprove)
Definition improvement.c:775
great_wonder_owner
struct player * great_wonder_owner(const struct impr_type *pimprove)
Definition improvement.c:1021
name
const char * name
Definition inputfile.c:127
log.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
map_move_cost
static int map_move_cost(const struct civ_map *nmap, const struct player *pplayer, const struct unit_type *punittype, const struct tile *src_tile, const struct tile *dst_tile)
Definition map.h:299
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
move_points_text
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
is_native_to_class
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
Definition movement.c:327
movement.h
MAX_MOVE_FRAGS
#define MAX_MOVE_FRAGS
Definition movement.h:27
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
name_translation_get
static const char * name_translation_get(const struct name_translation *ptrans)
Definition name_translation.h:121
names_set
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
Definition name_translation.h:60
player.h
is_barbarian
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
is_req_in_vec
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:4649
is_req_active
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
Definition requirements.c:4268
does_req_contradicts_reqs
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Definition requirements.c:1539
requirement_fulfilled_by_unit_type
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition requirements.h:418
requirement_diplrel_ereq
#define requirement_diplrel_ereq(_id_, _range_, _present_)
Definition requirements.h:441
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:126
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
research.h
road_has_flag
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
road_provides_move_bonus
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:499
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
shared.h
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:71
string_vector.h
action
Definition actions.h:379
action::id
action_id id
Definition actions.h:380
action::actor_consuming_always
bool actor_consuming_always
Definition actions.h:412
action::moves_actor
enum moves_actor_kind moves_actor
Definition actions.h:432
action::is_unit
struct action::@12::@13 is_unit
action::result
enum action_result result
Definition actions.h:382
action::sub_results
bv_action_sub_results sub_results
Definition actions.h:383
action::actor
union action::@12 actor
ai_type
Definition ai.h:50
astring
Definition astring.h:36
city
Definition city.h:309
city::tile
struct tile * tile
Definition city.h:311
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::scenario
struct packet_scenario_info scenario
Definition game.h:87
civ_game::veteran
struct veteran_system * veteran
Definition game.h:100
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:85
extra_type::reqs
struct requirement_vector reqs
Definition extras.h:102
packet_game_info::shieldbox
int shieldbox
Definition packets_gen.h:221
packet_game_info::global_advances
bool global_advances[A_LAST]
Definition packets_gen.h:163
packet_ruleset_control::num_unit_types
int num_unit_types
Definition packets_gen.h:1456
packet_ruleset_control::num_unit_classes
int num_unit_classes
Definition packets_gen.h:1455
packet_scenario_info::prevent_new_cities
bool prevent_new_cities
Definition packets_gen.h:1611
player
Definition player.h:249
player::units
struct unit_list * units
Definition player.h:282
range
Definition unittype.c:931
range::max
int max
Definition unittype.c:933
range::min
int min
Definition unittype.c:932
req_context
Definition requirements.h:99
req_context::player
const struct player * player
Definition requirements.h:100
requirement
Definition requirements.h:80
requirement::survives
bool survives
Definition requirements.h:83
requirement::present
bool present
Definition requirements.h:84
requirement::range
enum req_range range
Definition requirements.h:82
requirement::source
struct universal source
Definition requirements.h:81
road_type
Definition road.h:75
tile
Definition tile.h:49
unit_class
Definition unittype.h:136
unit_class::item_number
Unit_Class_id item_number
Definition unittype.h:137
unit_class::move_type
enum unit_move_type move_type
Definition unittype.h:140
unit_class::subset_movers
struct unit_class_list * subset_movers
Definition unittype.h:160
unit_class::cache
struct unit_class::@85 cache
unit_class::refuel_extras
struct extra_type_list * refuel_extras
Definition unittype.h:155
unit_class::native_tile_extras
struct extra_type_list * native_tile_extras
Definition unittype.h:156
unit_class::native_bases
struct extra_type_list * native_bases
Definition unittype.h:157
unit_class::bonus_roads
struct extra_type_list * bonus_roads
Definition unittype.h:158
unit_class::name
struct name_translation name
Definition unittype.h:138
unit_class::helptext
struct strvec * helptext
Definition unittype.h:146
unit_class::ruledit_disabled
bool ruledit_disabled
Definition unittype.h:139
unit_class::hiding_extras
struct extra_type_list * hiding_extras
Definition unittype.h:159
unit_type
Definition unittype.h:481
unit_type::max_defense_mp_bonus_pct
int max_defense_mp_bonus_pct
Definition unittype.h:560
unit_type::uclass
struct unit_class * uclass
Definition unittype.h:537
unit_type::pop_cost
int pop_cost
Definition unittype.h:493
unit_type::ais
void * ais[FREECIV_AI_MOD_LAST]
Definition unittype.h:575
unit_type::build_reqs
struct requirement_vector build_reqs
Definition unittype.h:501
unit_type::item_number
Unit_type_id item_number
Definition unittype.h:482
unit_type::defense_strength
int defense_strength
Definition unittype.h:496
unit_type::build_cost
int build_cost
Definition unittype.h:492
unit_type::veteran
struct veteran_system * veteran
Definition unittype.h:525
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:510
unit_type::move_rate
int move_rate
Definition unittype.h:497
unit_type::require_advance
struct advance * require_advance
Definition unittype.h:500
unit_type::helptext
struct strvec * helptext
Definition unittype.h:552
unit_type::scramble_coeff
int scramble_coeff[U_LAST]
Definition unittype.h:564
unit_type::cache
struct unit_type::@88 cache
unit_type::name
struct name_translation name
Definition unittype.h:483
unit_type::roles
bv_unit_type_roles roles
Definition unittype.h:516
unit_type::upkeep
int upkeep[O_LAST]
Definition unittype.h:519
unit_type::disembarks
bv_unit_classes disembarks
Definition unittype.h:548
unit_type::flags
bv_unit_type_flags flags
Definition unittype.h:515
unit_type::ruledit_disabled
bool ruledit_disabled
Definition unittype.h:484
unit_type::embarks
bv_unit_classes embarks
Definition unittype.h:545
unit_type::attack_strength
int attack_strength
Definition unittype.h:495
unit_type::happy_cost
int happy_cost
Definition unittype.h:518
unit_type::defense_mp_bonuses_pct
int defense_mp_bonuses_pct[U_LAST]
Definition unittype.h:563
unit_type::bonuses
struct combat_bonus_list * bonuses
Definition unittype.h:507
unit_type::ruledit_dlg
void * ruledit_dlg
Definition unittype.h:485
unit
Definition unit.h:138
unit::utype
const struct unit_type * utype
Definition unit.h:139
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
universal::value
universals_u value
Definition fc_types.h:757
user_flag
Definition game.h:73
user_flag::name
char * name
Definition game.h:74
user_flag::helptxt
char * helptxt
Definition game.h:75
veteran_level
Definition unittype.h:467
veteran_level::power_fact
int power_fact
Definition unittype.h:469
veteran_level::base_raise_chance
int base_raise_chance
Definition unittype.h:471
veteran_level::name
struct name_translation name
Definition unittype.h:468
veteran_level::move_bonus
int move_bonus
Definition unittype.h:470
veteran_level::work_raise_chance
int work_raise_chance
Definition unittype.h:472
veteran_system
Definition unittype.h:475
veteran_system::definitions
struct veteran_level * definitions
Definition unittype.h:478
veteran_system::levels
int levels
Definition unittype.h:476
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:995
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
advance_index
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:358
is_ocean
#define is_ocean(pterrain)
Definition terrain.h:287
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:364
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
universals_u::diplrel
int diplrel
Definition fc_types.h:629
universals_u::citytile
enum citytile_type citytile
Definition fc_types.h:613
universals_u::unit_state
enum ustate_prop unit_state
Definition fc_types.h:631
unit_shield_value
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:219
unit_owner
#define unit_owner(_pu)
Definition unit.h:387
unitlist.h
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
utype_may_act_tgt_city_tile
bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1176
utype_buy_gold_cost
int utype_buy_gold_cost(const struct city *pcity, const struct unit_type *punittype, int shields_in_stock)
Definition unittype.c:1544
unit_types_init
void unit_types_init(void)
Definition unittype.c:2394
can_unit_act_when_ustate_is
bool can_unit_act_when_ustate_is(const struct unit_type *punit_type, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:995
uclass_name_translation
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1684
set_unit_class_caches
void set_unit_class_caches(struct unit_class *pclass)
Definition unittype.c:2758
best_role_unit
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2319
unit_types
static struct unit_type unit_types[U_LAST]
Definition unittype.c:44
role_units_iterate
struct unit_type * role_units_iterate(int role, role_unit_callback cb, void *data)
Definition unittype.c:2265
utype_action_takes_all_mp
bool utype_action_takes_all_mp(const struct unit_type *putype, struct action *paction)
Definition unittype.c:1243
utype_veteran_name_translation
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2646
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
utype_has_class_flag
bool utype_has_class_flag(const struct unit_type *ptype, enum unit_class_flag_id flag)
Definition unittype.c:1709
user_unit_type_flags_init
void user_unit_type_flags_init(void)
Definition unittype.c:1916
utype_pays_mp_for_action_base
int utype_pays_mp_for_action_base(const struct action *paction, const struct unit_type *putype)
Definition unittype.c:1433
utype_player_already_has_this
bool utype_player_already_has_this(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1993
moves_left_range
static struct range * moves_left_range(struct requirement_vector *reqs)
Definition unittype.c:942
utype_can_freely_unload
bool utype_can_freely_unload(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:294
ACTION_HOSTILE
#define ACTION_HOSTILE
Definition unittype.c:383
unit_class_flag_helptxt
const char * unit_class_flag_helptxt(enum unit_class_flag_id id)
Definition unittype.c:1906
utype_pays_for_regular_move_to_tgt
bool utype_pays_for_regular_move_to_tgt(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1382
unit_type_free
static void unit_type_free(struct unit_type *punittype)
Definition unittype.c:2414
role_units_iterate_backwards
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Definition unittype.c:2284
precalc_one
static void precalc_one(int i, bool(*func_has)(const struct unit_type *, int))
Definition unittype.c:2180
user_class_flags
static struct user_flag user_class_flags[MAX_NUM_USER_UCLASS_FLAGS]
Definition unittype.c:53
dipl_rel_action_cache
static bv_diplrel_all_reqs dipl_rel_action_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:638
utype_can_remove_extra
bool utype_can_remove_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:235
unit_build_shield_cost
int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
Definition unittype.c:1528
unit_name_translation
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
utype_act_takes_all_mp_ustate_cache
static bv_unit_types utype_act_takes_all_mp_ustate_cache[ACTION_COUNT][USP_COUNT]
Definition unittype.c:565
unit_has_class_flag
bool unit_has_class_flag(const struct unit *punit, enum unit_class_flag_id flag)
Definition unittype.c:1701
utype_is_moved_to_tgt_by_action
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1301
ctile_tgt_act_cache
static bv_citytile_cache ctile_tgt_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:641
utype_upkeep_cost
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
utype_move_type
enum unit_move_type utype_move_type(const struct unit_type *punittype)
Definition unittype.c:1603
first_role_unit_for_player
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2370
uclass_count
Unit_Class_id uclass_count(void)
Definition unittype.c:2493
utype_is_cityfounder
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2967
unit_class_array_last
const struct unit_class * unit_class_array_last(void)
Definition unittype.c:2482
unit_type_by_rule_name
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1819
get_role_unit
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
unit_type_array_first
struct unit_type * unit_type_array_first(void)
Definition unittype.c:58
unit_class_flags_free
void unit_class_flags_free(void)
Definition unittype.c:2459
uclass_flag_is_in_use
bool uclass_flag_is_in_use(enum unit_class_flag_id ucflag)
Definition unittype.c:2983
MAX_UNIT_ROLES
#define MAX_UNIT_ROLES
Definition unittype.c:42
unit_rule_name
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
utype_has_role
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:193
move_type_from_extra
static enum unit_move_type move_type_from_extra(struct extra_type *pextra, struct unit_class *puc)
Definition unittype.c:2859
set_unit_move_type
void set_unit_move_type(struct unit_class *puclass)
Definition unittype.c:2926
action_is_hostile
static bool action_is_hostile(action_id act_id)
Definition unittype.c:304
dipl_rel_tile_other_tgt_a_cache
static bv_diplrel_all_reqs dipl_rel_tile_other_tgt_a_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:640
unit_type_action_cache_init
void unit_type_action_cache_init(void)
Definition unittype.c:983
local_dipl_rel_tile_other_tgt_action_cache_set
static void local_dipl_rel_tile_other_tgt_action_cache_set(struct unit_type *putype)
Definition unittype.c:796
utype_build_shield_cost_base
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
set_unit_type_caches
void set_unit_type_caches(struct unit_type *ptype)
Definition unittype.c:2817
utype_may_act_move_frags
bool utype_may_act_move_frags(const struct unit_type *punit_type, const action_id act_id, const int move_fragments)
Definition unittype.c:1110
utype_veteran_system
const struct veteran_system * utype_veteran_system(const struct unit_type *punittype)
Definition unittype.c:2615
utype_is_consumed_by_action_result
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Definition unittype.c:1281
num_role_units
int num_role_units(int role)
Definition unittype.c:2251
first_init
static bool first_init
Definition unittype.c:2172
utype_player_already_has_this_unique
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
utype_act_takes_all_mp_cache
static bv_unit_types utype_act_takes_all_mp_cache[ACTION_COUNT]
Definition unittype.c:523
utype_can_do_action_role
static bool utype_can_do_action_role(const struct unit_type *putype, const int role)
Definition unittype.c:505
unit_types_free
void unit_types_free(void)
Definition unittype.c:2433
utype_may_act_at_all
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:431
unit_build_shield_cost_base
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
can_upgrade_unittype
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
best_role_unit_for_player
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2345
role_unit_precalcs
void role_unit_precalcs(void)
Definition unittype.c:2223
uclass_by_number
struct unit_class * uclass_by_number(const Unit_Class_id id)
Definition unittype.c:2524
utype_can_create_extra
bool utype_can_create_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:211
local_dipl_rel_action_cache_set
static void local_dipl_rel_action_cache_set(struct unit_type *putype)
Definition unittype.c:716
tgt_citytile_act_cache_set
static void tgt_citytile_act_cache_set(struct unit_type *putype)
Definition unittype.c:868
utype_can_freely_load
bool utype_can_freely_load(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:282
veteran_system_definition
void veteran_system_definition(struct veteran_system *vsystem, int level, const char *vlist_name, int vlist_power, int vlist_move, int vlist_raise, int vlist_wraise)
Definition unittype.c:2719
MOVES_LEFT_INFINITY
#define MOVES_LEFT_INFINITY
Definition unittype.c:936
requirement_citytile_ereq
#define requirement_citytile_ereq(_id_, _present_)
Definition unittype.c:633
utype_count
Unit_type_id utype_count(void)
Definition unittype.c:80
can_player_build_unit_direct
bool can_player_build_unit_direct(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2015
unit_state_action_cache_set
static void unit_state_action_cache_set(struct unit_type *putype)
Definition unittype.c:648
ustate_act_cache
static bv_ustate_act_cache ustate_act_cache[U_LAST][ACTION_AND_FAKES]
Definition unittype.c:637
utype_veteran_levels
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2661
utype_pays_mp_for_action_estimate
int utype_pays_mp_for_action_estimate(const struct civ_map *nmap, const struct action *paction, const struct unit_type *putype, const struct player *act_player, const struct tile *act_tile, const struct tile *tgt_tile)
Definition unittype.c:1445
utype_can_do_act_when_ustate
bool utype_can_do_act_when_ustate(const struct unit_type *punit_type, const action_id act_id, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:1007
veteran_system_destroy
void veteran_system_destroy(struct veteran_system *vsystem)
Definition unittype.c:2706
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
unit_class_get
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2546
utype_can_do_action_result_when_ustate
bool utype_can_do_action_result_when_ustate(const struct unit_type *putype, enum action_result result, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:1027
utype_by_number
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
utype_can_do_action_result
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
unit_has_type_role
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:202
unit_can_act_cache_set
static void unit_can_act_cache_set(struct unit_type *putype)
Definition unittype.c:398
utype_action_takes_all_mp_if_ustate_is
bool utype_action_takes_all_mp_if_ustate_is(const struct unit_type *putype, struct action *paction, const enum ustate_prop prop)
Definition unittype.c:1259
utype_veteran_level
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2631
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
unit_can_take_over
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:258
unit_can_act_cache
static bv_unit_types unit_can_act_cache[ACTION_AND_FAKES]
Definition unittype.c:392
unit_classes_free
void unit_classes_free(void)
Definition unittype.c:2576
unit_type_action_cache_set
void unit_type_action_cache_set(struct unit_type *ptype)
Definition unittype.c:967
uclass_rule_name
const char * uclass_rule_name(const struct unit_class *pclass)
Definition unittype.c:1693
unit_class_flag_id_name_cb
const char * unit_class_flag_id_name_cb(enum unit_class_flag_id flag)
Definition unittype.c:1894
utype_is_consumed_by_action
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1271
unit_type_flags_free
void unit_type_flags_free(void)
Definition unittype.c:2447
utype_act_takes_all_mp_cache_set
static void utype_act_takes_all_mp_cache_set(struct unit_type *putype)
Definition unittype.c:529
utype_act_takes_all_mp_ustate_cache_set
static void utype_act_takes_all_mp_ustate_cache_set(struct unit_type *putype)
Definition unittype.c:572
utype_number
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
unit_type_flag_id_name_cb
const char * unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
Definition unittype.c:1957
utype_veteran_has_power_bonus
bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
Definition unittype.c:2674
user_unit_class_flags_init
void user_unit_class_flags_init(void)
Definition unittype.c:1852
utype_can_act_if_tgt_diplrel_tile_other
bool utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1088
unit_class_by_rule_name
struct unit_class * unit_class_by_rule_name(const char *s)
Definition unittype.c:1836
unit_type_by_translated_name
struct unit_type * unit_type_by_translated_name(const char *name)
Definition unittype.c:1804
unit_type_flag_helptxt
const char * unit_type_flag_helptxt(enum unit_type_flag_id id)
Definition unittype.c:1969
utype_values_string
const char * utype_values_string(const struct unit_type *punittype)
Definition unittype.c:1648
utype_ai_data
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2741
unit_class_array_first
struct unit_class * unit_class_array_first(void)
Definition unittype.c:2471
utype_index
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
unit_classes_init
void unit_classes_init(void)
Definition unittype.c:2554
utype_flag_is_in_use
bool utype_flag_is_in_use(enum unit_type_flag_id uflag)
Definition unittype.c:3002
ACTION_AND_FAKES
#define ACTION_AND_FAKES
Definition unittype.c:386
user_type_flags
static struct user_flag user_type_flags[MAX_NUM_USER_UNIT_FLAGS]
Definition unittype.c:51
utype_pop_value
int utype_pop_value(const struct unit_type *punittype, const struct city *pcity)
Definition unittype.c:1580
utype_can_take_over
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:270
utype_set_ai_data
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2749
set_user_unit_class_flag_name
void set_user_unit_class_flag_name(enum unit_class_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1864
can_player_build_unit_later
bool can_player_build_unit_later(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2150
unit_classes
static struct unit_class unit_classes[UCL_LAST]
Definition unittype.c:45
utype_build_shield_cost
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
unit_pop_value
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1595
requirement_unit_state_ereq
#define requirement_unit_state_ereq(_id_, _present_)
Definition unittype.c:631
role_unit_precalcs_free
void role_unit_precalcs_free(void)
Definition unittype.c:2208
veteran_system_new
struct veteran_system * veteran_system_new(int count)
Definition unittype.c:2688
uclass_number
Unit_Class_id uclass_number(const struct unit_class *pclass)
Definition unittype.c:2515
can_player_build_unit_now
bool can_player_build_unit_now(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2131
utype_can_do_action_sub_result
bool utype_can_do_action_sub_result(const struct unit_type *putype, enum action_sub_result sub_result)
Definition unittype.c:480
with_role
static struct unit_type ** with_role[MAX_UNIT_ROLES]
Definition unittype.c:2174
utype_is_unmoved_by_action
bool utype_is_unmoved_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1340
utype_acts_hostile
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:515
utype_can_do_act_if_tgt_citytile
bool utype_can_do_act_if_tgt_citytile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1048
utype_name_translation
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
n_with_role
static int n_with_role[MAX_UNIT_ROLES]
Definition unittype.c:2173
can_utype_do_act_if_tgt_diplrel
bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1069
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
set_user_unit_type_flag_name
void set_user_unit_type_flag_name(enum unit_type_flag_id id, const char *name, const char *helptxt)
Definition unittype.c:1928
utype_happy_cost
int utype_happy_cost(const struct unit_type *ut, const struct player *pplayer)
Definition unittype.c:175
role_units_translations
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1720
utype_values_translation
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1669
unit_type_array_last
const struct unit_type * unit_type_array_last(void)
Definition unittype.c:69
unit_upgrade_price
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1783
unittype.h
UCF_LAST_USER_FLAG
#define UCF_LAST_USER_FLAG
Definition unittype.h:112
uclass_has_flag
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
utype_class
#define utype_class(_t_)
Definition unittype.h:736
utype_fuel
#define utype_fuel(ptype)
Definition unittype.h:822
combat_bonus_list_iterate_end
#define combat_bonus_list_iterate_end
Definition unittype.h:463
L_FIRST
#define L_FIRST
Definition unittype.h:333
combat_bonus_list_iterate
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:461
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:876
MAX_NUM_USER_UNIT_FLAGS
#define MAX_NUM_USER_UNIT_FLAGS
Definition unittype.h:316
utype_has_flag
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
UTYF_LAST_USER_FLAG
#define UTYF_LAST_USER_FLAG
Definition unittype.h:315
L_LAST
#define L_LAST
Definition unittype.h:420
role_unit_callback
bool(* role_unit_callback)(struct unit_type *ptype, void *data)
Definition unittype.h:709
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:838
U_LAST
#define U_LAST
Definition unittype.h:40
uclass_index
#define uclass_index(_c_)
Definition unittype.h:729
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:883
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:845
MAX_NUM_USER_UCLASS_FLAGS
#define MAX_NUM_USER_UCLASS_FLAGS
Definition unittype.h:113
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:509