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)
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 ***********************************************************************/
15 #include <fc_config.h>
20 #include "bitvector.h"
39 #include "traderoutes.h"
44 static bool is_real_activity(enum unit_activity activity
);
46 Activity_type_id real_activities
[ACTIVITY_LAST
];
49 struct iterator vtable
;
50 const struct unit_list_link
*links
[GAME_TRANSPORT_MAX_RECURSIVE
];
53 #define CARGO_ITER(iter) ((struct cargo_iter *) (iter))
55 /****************************************************************************
56 Determines if punit can be airlifted to dest_city now! So punit needs
58 If pdest_city is NULL, just indicate whether it's possible for the unit
59 to be airlifted at all from its current position.
60 The 'restriction' parameter specifies which player's knowledge this is
61 based on -- one player can't see whether another's cities are currently
62 able to airlift. (Clients other than global observers should only call
63 this with a non-NULL 'restriction'.)
64 ****************************************************************************/
65 enum unit_airlift_result
66 test_unit_can_airlift_to(const struct player
*restriction
,
67 const struct unit
*punit
,
68 const struct city
*pdest_city
)
70 const struct city
*psrc_city
= tile_city(unit_tile(punit
));
71 const struct player
*punit_owner
;
72 enum unit_airlift_result ok_result
= AR_OK
;
74 if (0 == punit
->moves_left
75 && !utype_may_act_move_frags(unit_type_get(punit
),
81 if (!unit_can_do_action(punit
, ACTION_AIRLIFT
)) {
82 return AR_WRONG_UNITTYPE
;
85 if (0 < get_transporter_occupancy(punit
)) {
86 /* Units with occupants can't be airlifted currently. */
90 if (NULL
== psrc_city
) {
92 return AR_NOT_IN_CITY
;
95 if (psrc_city
== pdest_city
) {
96 /* Airlifting to our current position doesn't make sense. */
97 return AR_BAD_DST_CITY
;
101 && (NULL
== restriction
102 || (tile_get_known(city_tile(pdest_city
), restriction
)
104 && !can_unit_exist_at_tile(punit
, city_tile(pdest_city
))) {
105 /* Can't exist at the destination tile. */
106 return AR_BAD_DST_CITY
;
109 punit_owner
= unit_owner(punit
);
111 /* Check validity of both source and destination before checking capacity,
112 * to avoid misleadingly optimistic returns. */
114 if (punit_owner
!= city_owner(psrc_city
)
115 && !(game
.info
.airlifting_style
& AIRLIFTING_ALLIED_SRC
116 && pplayers_allied(punit_owner
, city_owner(psrc_city
)))) {
117 /* Not allowed to airlift from this source. */
118 return AR_BAD_SRC_CITY
;
122 punit_owner
!= city_owner(pdest_city
)
123 && !(game
.info
.airlifting_style
& AIRLIFTING_ALLIED_DEST
124 && pplayers_allied(punit_owner
, city_owner(pdest_city
)))) {
125 /* Not allowed to airlift to this destination. */
126 return AR_BAD_DST_CITY
;
129 if (NULL
== restriction
|| city_owner(psrc_city
) == restriction
) {
130 /* We know for sure whether or not src can airlift this turn. */
131 if (0 >= psrc_city
->airlift
) {
132 /* The source cannot airlift for this turn (maybe already airlifted
135 * Note that (game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)
136 * is not handled here because it always needs an airport to airlift.
137 * See also do_airline() in server/unittools.h. */
138 return AR_SRC_NO_FLIGHTS
;
139 } /* else, there is capacity; continue to other checks */
141 /* We don't have access to the 'airlift' field. Assume it's OK; can
142 * only find out for sure by trying it. */
143 ok_result
= AR_OK_SRC_UNKNOWN
;
147 if (NULL
== restriction
|| city_owner(pdest_city
) == restriction
) {
148 if (0 >= pdest_city
->airlift
149 && !(game
.info
.airlifting_style
& AIRLIFTING_UNLIMITED_DEST
)) {
150 /* The destination cannot support airlifted units for this turn
151 * (maybe already airlifed or no airport).
152 * See also do_airline() in server/unittools.h. */
153 return AR_DST_NO_FLIGHTS
;
154 } /* else continue */
156 ok_result
= AR_OK_DST_UNKNOWN
;
163 /****************************************************************************
164 Determines if punit can be airlifted to dest_city now! So punit needs
166 On the server this gives correct information; on the client it errs on the
167 side of saying airlifting is possible even if it's not certain given
169 ****************************************************************************/
170 bool unit_can_airlift_to(const struct unit
*punit
,
171 const struct city
*pdest_city
)
173 fc_assert_ret_val(pdest_city
, FALSE
);
176 return is_action_enabled_unit_on_city(ACTION_AIRLIFT
,
179 return action_prob_possible(action_prob_vs_city(punit
, ACTION_AIRLIFT
,
184 /****************************************************************************
185 Return TRUE iff the unit is following client-side orders.
186 ****************************************************************************/
187 bool unit_has_orders(const struct unit
*punit
)
189 return punit
->has_orders
;
192 /**************************************************************************
193 Return TRUE unless it is known to be imposible to disband this unit at
194 its current position to get full shields for building a wonder.
195 **************************************************************************/
196 bool unit_can_help_build_wonder_here(const struct unit
*punit
)
198 struct city
*pcity
= tile_city(unit_tile(punit
));
201 /* No city to help at this tile. */
205 if (!utype_can_do_action(unit_type_get(punit
), ACTION_HELP_WONDER
)) {
206 /* This unit can never do help wonder. */
210 /* Evaluate all action enablers for extra accuracy. */
211 /* TODO: Is it worth it? */
212 return action_prob_possible(action_prob_vs_city(punit
,
217 /**************************************************************************
218 Return TRUE iff this unit can be disbanded at its current location to
219 provide a trade route from the homecity to the target city.
220 **************************************************************************/
221 bool unit_can_est_trade_route_here(const struct unit
*punit
)
223 struct city
*phomecity
, *pdestcity
;
225 return (utype_can_do_action(unit_type_get(punit
), ACTION_TRADE_ROUTE
)
226 && (pdestcity
= tile_city(unit_tile(punit
)))
227 && (phomecity
= game_city_by_number(punit
->homecity
))
228 && can_cities_trade(phomecity
, pdestcity
));
231 /**************************************************************************
232 Return the number of units the transporter can hold (or 0).
233 **************************************************************************/
234 int get_transporter_capacity(const struct unit
*punit
)
236 return unit_type_get(punit
)->transport_capacity
;
239 /**************************************************************************
240 Is the unit capable of attacking?
241 **************************************************************************/
242 bool is_attack_unit(const struct unit
*punit
)
244 return (unit_type_get(punit
)->attack_strength
> 0);
247 /**************************************************************************
248 Military units are capable of enforcing martial law. Military ground
249 and heli units can occupy empty cities -- see unit_can_take_over(punit).
250 Some military units, like the Galleon, have no attack strength.
251 **************************************************************************/
252 bool is_military_unit(const struct unit
*punit
)
254 return !unit_has_type_flag(punit
, UTYF_CIVILIAN
);
257 /**************************************************************************
258 Return TRUE iff this unit is a diplomat (spy) unit. Diplomatic units
259 can do diplomatic actions (not to be confused with diplomacy).
260 **************************************************************************/
261 bool is_diplomat_unit(const struct unit
*punit
)
263 return (unit_has_type_flag(punit
, UTYF_DIPLOMAT
));
266 /**************************************************************************
267 Return TRUE iff this unit can do the specified generalized (ruleset
268 defined) action enabler controlled action.
269 **************************************************************************/
270 bool unit_can_do_action(const struct unit
*punit
,
273 return utype_can_do_action(unit_type_get(punit
), action_id
);
276 /**************************************************************************
277 Return TRUE iff this tile is threatened from any unit within 2 tiles.
278 **************************************************************************/
279 bool is_square_threatened(const struct player
*pplayer
,
280 const struct tile
*ptile
, bool omniscient
)
282 square_iterate(ptile
, 2, ptile1
) {
283 unit_list_iterate(ptile1
->units
, punit
) {
285 || can_player_see_unit(pplayer
, punit
))
286 && pplayers_at_war(pplayer
, unit_owner(punit
))
287 && (utype_acts_hostile(unit_type_get(punit
))
288 || (is_military_unit(punit
) && is_attack_unit(punit
)))
289 && (is_native_tile(unit_type_get(punit
), ptile
)
290 || (can_attack_non_native(unit_type_get(punit
))
291 && is_native_near_tile(unit_class_get(punit
), ptile
)))) {
294 } unit_list_iterate_end
;
295 } square_iterate_end
;
300 /**************************************************************************
301 This checks the "field unit" flag on the unit. Field units cause
302 unhappiness (under certain governments) even when they aren't abroad.
303 **************************************************************************/
304 bool is_field_unit(const struct unit
*punit
)
306 return unit_has_type_flag(punit
, UTYF_FIELDUNIT
);
310 /**************************************************************************
311 Is the unit one that is invisible on the map. A unit is invisible if
312 it has the UTYF_PARTIAL_INVIS flag or if it transported by a unit with
314 **************************************************************************/
315 bool is_hiding_unit(const struct unit
*punit
)
317 return (unit_has_type_flag(punit
, UTYF_PARTIAL_INVIS
)
318 || (unit_transported(punit
)
319 && unit_has_type_flag(unit_transport_get(punit
),
320 UTYF_PARTIAL_INVIS
)));
323 /**************************************************************************
324 Return TRUE iff an attack from this unit would kill a citizen in a city
325 (city walls protect against this).
326 **************************************************************************/
327 bool kills_citizen_after_attack(const struct unit
*punit
)
329 return game
.info
.killcitizen
330 && uclass_has_flag(unit_class_get(punit
), UCF_KILLCITIZEN
);
333 /****************************************************************************
334 Return TRUE iff this unit can add to a current city or build a new city
335 at its current location.
336 ****************************************************************************/
337 bool unit_can_add_or_build_city(const struct unit
*punit
)
339 struct city
*tgt_city
;
341 if ((tgt_city
= tile_city(unit_tile(punit
)))) {
342 return action_prob_possible(action_prob_vs_city(punit
,
343 ACTION_JOIN_CITY
, tgt_city
));
345 return action_prob_possible(action_prob_vs_tile(punit
,
346 ACTION_FOUND_CITY
, unit_tile(punit
)));
350 /**************************************************************************
351 Return TRUE iff the unit can change homecity to the given city.
352 **************************************************************************/
353 bool can_unit_change_homecity_to(const struct unit
*punit
,
354 const struct city
*pcity
)
357 /* Can't change home city to a non existing city. */
361 return action_prob_possible(action_prob_vs_city(punit
, ACTION_HOME_CITY
,
365 /**************************************************************************
366 Return TRUE iff the unit can change homecity at its current location.
367 **************************************************************************/
368 bool can_unit_change_homecity(const struct unit
*punit
)
370 return can_unit_change_homecity_to(punit
, tile_city(unit_tile(punit
)));
373 /**************************************************************************
374 Returns the speed of a unit doing an activity. This depends on the
375 veteran level and the base move_rate of the unit (regardless of HP or
376 effects). Usually this is just used for settlers but the value is also
377 used for military units doing fortify/pillage activities.
379 The speed is multiplied by ACTIVITY_FACTOR.
380 **************************************************************************/
381 int get_activity_rate(const struct unit
*punit
)
383 const struct veteran_level
*vlevel
;
385 fc_assert_ret_val(punit
!= NULL
, 0);
387 vlevel
= utype_veteran_level(unit_type_get(punit
), punit
->veteran
);
388 fc_assert_ret_val(vlevel
!= NULL
, 0);
390 /* The speed of the settler depends on its base move_rate, not on
391 * the number of moves actually remaining or the adjusted move rate.
392 * This means sea formers won't have their activity rate increased by
393 * Magellan's, and it means injured units work just as fast as
394 * uninjured ones. Note the value is never less than SINGLE_MOVE. */
395 int move_rate
= unit_type_get(punit
)->move_rate
;
397 /* All settler actions are multiplied by ACTIVITY_FACTOR. */
398 return ACTIVITY_FACTOR
399 * (float)vlevel
->power_fact
/ 100
400 * move_rate
/ SINGLE_MOVE
;
403 /**************************************************************************
404 Returns the amount of work a unit does (will do) on an activity this
405 turn. Units that have no MP do no work.
407 The speed is multiplied by ACTIVITY_FACTOR.
408 **************************************************************************/
409 int get_activity_rate_this_turn(const struct unit
*punit
)
411 /* This logic is also coded in client/goto.c. */
412 if (punit
->moves_left
> 0) {
413 return get_activity_rate(punit
);
419 /**************************************************************************
420 Return the estimated number of turns for the worker unit to start and
421 complete the activity at the given location. This assumes no other
422 worker units are helping out, and doesn't take account of any work
423 already done by this unit.
424 **************************************************************************/
425 int get_turns_for_activity_at(const struct unit
*punit
,
426 enum unit_activity activity
,
427 const struct tile
*ptile
,
428 struct extra_type
*tgt
)
430 /* FIXME: This is just an approximation since we don't account for
431 * get_activity_rate_this_turn. */
432 int speed
= get_activity_rate(punit
);
433 int points_needed
= tile_activity_time(activity
, ptile
, tgt
);
435 if (points_needed
>= 0 && speed
>= 0) {
436 return (points_needed
- 1) / speed
+ 1; /* round up */
442 /**************************************************************************
443 Return TRUE if activity requires some sort of target to be specified.
444 **************************************************************************/
445 bool activity_requires_target(enum unit_activity activity
)
448 case ACTIVITY_PILLAGE
:
450 case ACTIVITY_GEN_ROAD
:
451 case ACTIVITY_IRRIGATE
:
453 case ACTIVITY_POLLUTION
:
454 case ACTIVITY_FALLOUT
:
457 case ACTIVITY_FORTIFIED
:
458 case ACTIVITY_SENTRY
:
460 case ACTIVITY_EXPLORE
:
461 case ACTIVITY_TRANSFORM
:
462 case ACTIVITY_FORTIFYING
:
463 case ACTIVITY_CONVERT
:
465 /* These shouldn't be kicking around internally. */
466 case ACTIVITY_FORTRESS
:
467 case ACTIVITY_AIRBASE
:
468 case ACTIVITY_PATROL_UNUSED
:
470 fc_assert_ret_val(FALSE
, FALSE
);
476 /**************************************************************************
477 Return whether the unit can be put in auto-settler mode.
479 NOTE: we used to have "auto" mode including autosettlers and auto-attack.
480 This was bad because the two were indestinguishable even though they
481 are very different. Now auto-attack is done differently so we just have
482 auto-settlers. If any new auto modes are introduced they should be
484 **************************************************************************/
485 bool can_unit_do_autosettlers(const struct unit
*punit
)
487 return unit_has_type_flag(punit
, UTYF_SETTLERS
);
490 /**************************************************************************
491 Setup array of real activities
492 **************************************************************************/
493 void setup_real_activities_array(void)
495 Activity_type_id act
;
498 for (act
= 0; act
< ACTIVITY_LAST
; act
++) {
499 if (is_real_activity(act
)) {
500 real_activities
[i
++] = act
;
504 real_activities
[i
] = ACTIVITY_LAST
;
507 /**************************************************************************
508 Return if given activity really is in game. For savegame compatibility
509 activity enum cannot be reordered and there is holes in it.
510 **************************************************************************/
511 static bool is_real_activity(enum unit_activity activity
)
513 /* ACTIVITY_FORTRESS, ACTIVITY_AIRBASE, ACTIVITY_OLD_ROAD, and
514 * ACTIVITY_OLD_RAILROAD are deprecated */
515 return (0 <= activity
&& activity
< ACTIVITY_LAST
)
516 && activity
!= ACTIVITY_FORTRESS
517 && activity
!= ACTIVITY_AIRBASE
518 && activity
!= ACTIVITY_OLD_ROAD
519 && activity
!= ACTIVITY_OLD_RAILROAD
520 && activity
!= ACTIVITY_UNKNOWN
521 && activity
!= ACTIVITY_PATROL_UNUSED
;
524 /**************************************************************************
525 Return the name of the activity in a static buffer.
526 **************************************************************************/
527 const char *get_activity_text(enum unit_activity activity
)
529 /* The switch statement has just the activities listed with no "default"
530 * handling. This enables the compiler to detect missing entries
531 * automatically, and still handles everything correctly. */
535 case ACTIVITY_POLLUTION
:
536 return _("Pollution");
538 /* TRANS: Activity name, verb in English */
540 case ACTIVITY_IRRIGATE
:
541 return _("Irrigate");
542 case ACTIVITY_FORTIFYING
:
543 return _("Fortifying");
544 case ACTIVITY_FORTIFIED
:
545 return _("Fortified");
546 case ACTIVITY_SENTRY
:
548 case ACTIVITY_PILLAGE
:
552 case ACTIVITY_EXPLORE
:
554 case ACTIVITY_TRANSFORM
:
555 return _("Transform");
556 case ACTIVITY_FALLOUT
:
560 case ACTIVITY_GEN_ROAD
:
562 case ACTIVITY_CONVERT
:
564 case ACTIVITY_OLD_ROAD
:
565 case ACTIVITY_OLD_RAILROAD
:
566 case ACTIVITY_FORTRESS
:
567 case ACTIVITY_AIRBASE
:
568 case ACTIVITY_UNKNOWN
:
569 case ACTIVITY_PATROL_UNUSED
:
578 /****************************************************************************
579 Return TRUE iff the given unit could be loaded into the transporter
581 ****************************************************************************/
582 bool could_unit_load(const struct unit
*pcargo
, const struct unit
*ptrans
)
584 if (!pcargo
|| !ptrans
|| pcargo
== ptrans
) {
588 /* Double-check ownership of the units: you can load into an allied unit
589 * (of course only allied units can be on the same tile). */
590 if (!pplayers_allied(unit_owner(pcargo
), unit_owner(ptrans
))) {
594 /* Make sure this transporter can carry this type of unit. */
595 if (!can_unit_transport(ptrans
, pcargo
)) {
599 /* Un-embarkable transport must be in city or base to load cargo. */
600 if (!utype_can_freely_load(unit_type_get(pcargo
), unit_type_get(ptrans
))
601 && !tile_city(unit_tile(ptrans
))
602 && !tile_has_native_base(unit_tile(ptrans
), unit_type_get(ptrans
))) {
606 /* Make sure there's room in the transporter. */
607 if (get_transporter_occupancy(ptrans
)
608 >= get_transporter_capacity(ptrans
)) {
612 /* Check iff this is a valid transport. */
613 if (!unit_transport_check(pcargo
, ptrans
)) {
617 /* Check transport depth. */
618 if (GAME_TRANSPORT_MAX_RECURSIVE
619 < 1 + unit_transport_depth(ptrans
) + unit_cargo_depth(pcargo
)) {
626 /****************************************************************************
627 Return TRUE iff the given unit can be loaded into the transporter.
628 ****************************************************************************/
629 bool can_unit_load(const struct unit
*pcargo
, const struct unit
*ptrans
)
631 /* This function needs to check EVERYTHING. */
633 /* Check positions of the units. Of course you can't load a unit onto
634 * a transporter on a different tile... */
635 if (!same_pos(unit_tile(pcargo
), unit_tile(ptrans
))) {
639 /* Cannot load if cargo is already loaded onto something else. */
640 if (unit_transported(pcargo
)) {
644 return could_unit_load(pcargo
, ptrans
);
647 /****************************************************************************
648 Return TRUE iff the given unit can be unloaded from its current
651 This function checks everything *except* the legality of the position
652 after the unloading. The caller may also want to call
653 can_unit_exist_at_tile() to check this, unless the unit is unloading and
654 moving at the same time.
655 ****************************************************************************/
656 bool can_unit_unload(const struct unit
*pcargo
, const struct unit
*ptrans
)
658 if (!pcargo
|| !ptrans
) {
662 /* Make sure the unit's transporter exists and is known. */
663 if (unit_transport_get(pcargo
) != ptrans
) {
667 /* Un-disembarkable transport must be in city or base to unload cargo. */
668 if (!utype_can_freely_unload(unit_type_get(pcargo
), unit_type_get(ptrans
))
669 && !tile_city(unit_tile(ptrans
))
670 && !tile_has_native_base(unit_tile(ptrans
), unit_type_get(ptrans
))) {
677 /**************************************************************************
678 Return whether the unit can be paradropped - that is, if the unit is in
679 a friendly city or on an airbase special, has enough movepoints left, and
680 has not paradropped yet this turn.
681 **************************************************************************/
682 bool can_unit_paradrop(const struct unit
*punit
)
684 return action_maybe_possible_actor_unit(ACTION_PARADROP
, punit
);
687 /**************************************************************************
688 Check if the unit's current activity is actually legal.
689 **************************************************************************/
690 bool can_unit_continue_current_activity(struct unit
*punit
)
692 enum unit_activity current
= punit
->activity
;
693 struct extra_type
*target
= punit
->activity_target
;
694 enum unit_activity current2
=
695 (current
== ACTIVITY_FORTIFIED
) ? ACTIVITY_FORTIFYING
: current
;
698 punit
->activity
= ACTIVITY_IDLE
;
699 punit
->activity_target
= NULL
;
701 result
= can_unit_do_activity_targeted(punit
, current2
, target
);
703 punit
->activity
= current
;
704 punit
->activity_target
= target
;
709 /**************************************************************************
710 Return TRUE iff the unit can do the given untargeted activity at its
713 Note that some activities must be targeted; see
714 can_unit_do_activity_targeted.
715 **************************************************************************/
716 bool can_unit_do_activity(const struct unit
*punit
,
717 enum unit_activity activity
)
719 struct extra_type
*target
= NULL
;
721 /* FIXME: lots of callers (usually client real_menus_update()) rely on
722 * being able to find out whether an activity is in general possible.
723 * Find one for them, but when they come to do the activity, they will
724 * have to determine the target themselves */
726 struct tile
*ptile
= unit_tile(punit
);
727 struct terrain
*pterrain
= tile_terrain(ptile
);
729 if (activity
== ACTIVITY_IRRIGATE
730 && pterrain
->irrigation_result
== pterrain
) {
731 target
= next_extra_for_tile(ptile
,
735 if (NULL
== target
) {
736 return FALSE
; /* No more irrigation extras available. */
738 } else if (activity
== ACTIVITY_MINE
739 && pterrain
->mining_result
== pterrain
) {
740 target
= next_extra_for_tile(ptile
,
744 if (NULL
== target
) {
745 return FALSE
; /* No more mine extras available. */
750 return can_unit_do_activity_targeted(punit
, activity
, target
);
753 /**************************************************************************
754 Return whether the unit can do the targeted activity at its current
756 **************************************************************************/
757 bool can_unit_do_activity_targeted(const struct unit
*punit
,
758 enum unit_activity activity
,
759 struct extra_type
*target
)
761 return can_unit_do_activity_targeted_at(punit
, activity
, target
,
765 /**************************************************************************
766 Return TRUE if the unit can do the targeted activity at the given
768 **************************************************************************/
769 bool can_unit_do_activity_targeted_at(const struct unit
*punit
,
770 enum unit_activity activity
,
771 struct extra_type
*target
,
772 const struct tile
*ptile
)
774 struct terrain
*pterrain
= tile_terrain(ptile
);
775 struct unit_class
*pclass
= unit_class_get(punit
);
777 /* Check that no build activity conflicting with one already in progress
779 /* FIXME: Should check also the cases where one of the activities is terrain
780 * change that destroys the target of the other activity */
781 if (target
!= NULL
&& is_build_activity(activity
, ptile
)) {
782 unit_list_iterate(ptile
->units
, tunit
) {
783 if (is_build_activity(tunit
->activity
, ptile
)
784 && !can_extras_coexist(target
, tunit
->activity_target
)) {
787 } unit_list_iterate_end
;
795 case ACTIVITY_POLLUTION
:
797 struct extra_type
*pextra
;
799 if (pterrain
->clean_pollution_time
== 0) {
803 if (target
!= NULL
) {
806 /* TODO: Make sure that all callers set target so that
807 * we don't need this fallback. */
808 pextra
= prev_extra_in_tile(ptile
,
812 if (pextra
== NULL
) {
813 /* No available pollution extras */
818 if (!is_extra_removed_by(pextra
, ERM_CLEANPOLLUTION
)) {
822 if (!unit_has_type_flag(punit
, UTYF_SETTLERS
)
823 || !can_remove_extra(pextra
, punit
, ptile
)) {
827 if (tile_has_extra(ptile
, pextra
)) {
834 case ACTIVITY_FALLOUT
:
836 struct extra_type
*pextra
;
838 if (pterrain
->clean_fallout_time
== 0) {
842 if (target
!= NULL
) {
845 /* TODO: Make sure that all callers set target so that
846 * we don't need this fallback. */
847 pextra
= prev_extra_in_tile(ptile
,
851 if (pextra
== NULL
) {
852 /* No available pollution extras */
857 if (!is_extra_removed_by(pextra
, ERM_CLEANFALLOUT
)) {
861 if (!unit_has_type_flag(punit
, UTYF_SETTLERS
)
862 || !can_remove_extra(pextra
, punit
, ptile
)) {
866 if (tile_has_extra(ptile
, pextra
)) {
874 if (pterrain
->mining_result
== pterrain
) {
875 if (target
== NULL
) {
879 if (pterrain
->mining_time
== 0) {
883 if (!is_extra_caused_by(target
, EC_MINE
)) {
888 if (unit_has_type_flag(punit
, UTYF_SETTLERS
)
889 && ((pterrain
== pterrain
->mining_result
890 && can_build_extra(target
, punit
, ptile
)
891 && get_tile_bonus(ptile
, punit
, EFT_MINING_POSSIBLE
) > 0)
892 || (pterrain
!= pterrain
->mining_result
893 && pterrain
->mining_result
!= T_NONE
894 && get_tile_bonus(ptile
, punit
, EFT_MINING_TF_POSSIBLE
) > 0
896 && terrain_surroundings_allow_change(ptile
,
897 pterrain
->mining_result
)
898 && (!terrain_has_flag(pterrain
->mining_result
, TER_NO_CITIES
)
899 || !tile_city(ptile
))))) {
905 case ACTIVITY_IRRIGATE
:
906 if (pterrain
->irrigation_result
== pterrain
) {
907 if (target
== NULL
) {
911 if (pterrain
->irrigation_time
== 0) {
915 if (!is_extra_caused_by(target
, EC_IRRIGATION
)) {
920 if (unit_has_type_flag(punit
, UTYF_SETTLERS
)
921 && ((pterrain
== pterrain
->irrigation_result
922 && can_build_extra(target
, punit
, ptile
)
923 && can_be_irrigated(ptile
, punit
))
924 || (pterrain
!= pterrain
->irrigation_result
925 && pterrain
->irrigation_result
!= T_NONE
926 && get_tile_bonus(ptile
, punit
, EFT_IRRIG_TF_POSSIBLE
) > 0
928 && terrain_surroundings_allow_change(ptile
,
929 pterrain
->irrigation_result
)
930 && (!terrain_has_flag(pterrain
->irrigation_result
, TER_NO_CITIES
)
931 || !tile_city(ptile
))))) {
937 case ACTIVITY_FORTIFYING
:
938 return (uclass_has_flag(pclass
, UCF_CAN_FORTIFY
)
939 && !unit_has_type_flag(punit
, UTYF_CANT_FORTIFY
)
940 && punit
->activity
!= ACTIVITY_FORTIFIED
941 && (!terrain_has_flag(pterrain
, TER_NO_FORTIFY
) || tile_city(ptile
)));
943 case ACTIVITY_FORTIFIED
:
947 if (target
== NULL
) {
950 return can_build_base(punit
, extra_base_get(target
), ptile
);
952 case ACTIVITY_GEN_ROAD
:
953 if (target
== NULL
) {
956 return can_build_road(extra_road_get(target
), punit
, ptile
);
958 case ACTIVITY_SENTRY
:
959 if (!can_unit_survive_at_tile(punit
, unit_tile(punit
))
960 && !unit_transported(punit
)) {
961 /* Don't let units sentry on tiles they will die on. */
966 case ACTIVITY_PILLAGE
:
968 if (pterrain
->pillage_time
== 0) {
972 if (uclass_has_flag(pclass
, UCF_CAN_PILLAGE
)) {
973 bv_extras pspresent
= get_tile_infrastructure_set(ptile
, NULL
);
974 bv_extras psworking
= get_unit_tile_pillage_set(ptile
);
976 bv_extras pspossible
;
978 BV_CLR_ALL(pspossible
);
979 extra_type_iterate(pextra
) {
980 int idx
= extra_index(pextra
);
982 /* Only one unit can pillage a given improvement at a time */
983 if (BV_ISSET(pspresent
, idx
) && !BV_ISSET(psworking
, idx
)
984 && can_remove_extra(pextra
, punit
, ptile
)) {
985 bool required
= FALSE
;
987 extra_type_iterate(pdepending
) {
988 if (BV_ISSET(pspresent
, extra_index(pdepending
))) {
989 extra_deps_iterate(&(pdepending
->reqs
), pdep
) {
990 if (pdep
== pextra
) {
994 } extra_deps_iterate_end
;
999 } extra_type_iterate_end
;
1002 BV_SET(pspossible
, idx
);
1005 } extra_type_iterate_end
;
1007 if (!BV_ISSET_ANY(pspossible
)) {
1008 /* Nothing available to pillage */
1012 if (target
== NULL
) {
1013 /* Undirected pillaging. If we've got this far, then there's
1014 * *something* we can pillage; work out what when we come to it */
1017 if (!game
.info
.pillage_select
) {
1018 /* Hobson's choice (this case mostly exists for old clients) */
1019 /* Needs to match what unit_activity_assign_target chooses */
1020 struct extra_type
*tgt
;
1022 tgt
= get_preferred_pillage(pspossible
);
1024 if (tgt
!= target
) {
1025 /* Only one target allowed, which wasn't the requested one */
1030 return BV_ISSET(pspossible
, extra_index(target
));
1033 /* Unit is not a type that can pillage at all */
1038 case ACTIVITY_EXPLORE
:
1039 return (!unit_type_get(punit
)->fuel
&& !is_losing_hp(punit
));
1041 case ACTIVITY_TRANSFORM
:
1042 return (pterrain
->transform_result
!= T_NONE
1043 && pterrain
!= pterrain
->transform_result
1044 && terrain_surroundings_allow_change(ptile
,
1045 pterrain
->transform_result
)
1046 && (!terrain_has_flag(pterrain
->transform_result
, TER_NO_CITIES
)
1047 || !(tile_city(ptile
)))
1048 && get_tile_bonus(ptile
, punit
, EFT_TRANSFORM_POSSIBLE
) > 0);
1050 case ACTIVITY_CONVERT
:
1051 return unit_can_convert(punit
);
1053 case ACTIVITY_OLD_ROAD
:
1054 case ACTIVITY_OLD_RAILROAD
:
1055 case ACTIVITY_FORTRESS
:
1056 case ACTIVITY_AIRBASE
:
1057 case ACTIVITY_PATROL_UNUSED
:
1059 case ACTIVITY_UNKNOWN
:
1062 log_error("can_unit_do_activity_targeted_at() unknown activity %d",
1067 /**************************************************************************
1068 Assign a new task to a unit. Doesn't account for changed_from.
1069 **************************************************************************/
1070 static void set_unit_activity_internal(struct unit
*punit
,
1071 enum unit_activity new_activity
)
1073 fc_assert_ret(new_activity
!= ACTIVITY_FORTRESS
1074 && new_activity
!= ACTIVITY_AIRBASE
);
1076 punit
->activity
= new_activity
;
1077 punit
->activity_count
= 0;
1078 punit
->activity_target
= NULL
;
1079 if (new_activity
== ACTIVITY_IDLE
&& punit
->moves_left
> 0) {
1080 /* No longer done. */
1081 punit
->done_moving
= FALSE
;
1085 /**************************************************************************
1086 assign a new untargeted task to a unit.
1087 **************************************************************************/
1088 void set_unit_activity(struct unit
*punit
, enum unit_activity new_activity
)
1090 fc_assert_ret(!activity_requires_target(new_activity
));
1092 if (new_activity
== ACTIVITY_FORTIFYING
1093 && punit
->changed_from
== ACTIVITY_FORTIFIED
) {
1094 new_activity
= ACTIVITY_FORTIFIED
;
1096 set_unit_activity_internal(punit
, new_activity
);
1097 if (new_activity
== punit
->changed_from
) {
1098 punit
->activity_count
= punit
->changed_from_count
;
1102 /**************************************************************************
1103 assign a new targeted task to a unit.
1104 **************************************************************************/
1105 void set_unit_activity_targeted(struct unit
*punit
,
1106 enum unit_activity new_activity
,
1107 struct extra_type
*new_target
)
1109 fc_assert_ret(activity_requires_target(new_activity
)
1110 || new_target
== NULL
);
1112 set_unit_activity_internal(punit
, new_activity
);
1113 punit
->activity_target
= new_target
;
1114 if (new_activity
== punit
->changed_from
1115 && new_target
== punit
->changed_from_target
) {
1116 punit
->activity_count
= punit
->changed_from_count
;
1120 /**************************************************************************
1121 Assign a new base building task to unit
1122 **************************************************************************/
1123 void set_unit_activity_base(struct unit
*punit
,
1126 set_unit_activity_internal(punit
, ACTIVITY_BASE
);
1127 punit
->activity_target
= base_extra_get(base_by_number(base
));
1128 if (ACTIVITY_BASE
== punit
->changed_from
1129 && punit
->activity_target
== punit
->changed_from_target
) {
1130 punit
->activity_count
= punit
->changed_from_count
;
1134 /**************************************************************************
1135 Assign a new road building task to unit
1136 **************************************************************************/
1137 void set_unit_activity_road(struct unit
*punit
,
1140 set_unit_activity_internal(punit
, ACTIVITY_GEN_ROAD
);
1141 punit
->activity_target
= road_extra_get(road_by_number(road
));
1142 if (ACTIVITY_GEN_ROAD
== punit
->changed_from
1143 && punit
->activity_target
== punit
->changed_from_target
) {
1144 punit
->activity_count
= punit
->changed_from_count
;
1148 /**************************************************************************
1149 Return whether any units on the tile are doing this activity.
1150 **************************************************************************/
1151 bool is_unit_activity_on_tile(enum unit_activity activity
,
1152 const struct tile
*ptile
)
1154 unit_list_iterate(ptile
->units
, punit
) {
1155 if (punit
->activity
== activity
) {
1158 } unit_list_iterate_end
;
1162 /****************************************************************************
1163 Return a mask of the extras which are actively (currently) being
1164 pillaged on the given tile.
1165 ****************************************************************************/
1166 bv_extras
get_unit_tile_pillage_set(const struct tile
*ptile
)
1170 BV_CLR_ALL(tgt_ret
);
1171 unit_list_iterate(ptile
->units
, punit
) {
1172 if (punit
->activity
== ACTIVITY_PILLAGE
) {
1173 BV_SET(tgt_ret
, extra_index(punit
->activity_target
));
1175 } unit_list_iterate_end
;
1180 /**************************************************************************
1181 Return text describing the unit's current activity as a static string.
1183 FIXME: Convert all callers of this function to unit_activity_astr()
1184 because this function is not re-entrant.
1185 **************************************************************************/
1186 const char *unit_activity_text(const struct unit
*punit
) {
1187 static struct astring str
= ASTRING_INIT
;
1190 unit_activity_astr(punit
, &str
);
1192 return astr_str(&str
);
1195 /**************************************************************************
1196 Append text describing the unit's current activity to the given astring.
1197 **************************************************************************/
1198 void unit_activity_astr(const struct unit
*punit
, struct astring
*astr
)
1200 if (!punit
|| !astr
) {
1204 switch (punit
->activity
) {
1206 if (utype_fuel(unit_type_get(punit
))) {
1209 rate
= unit_type_get(punit
)->move_rate
;
1210 f
= ((punit
->fuel
) - 1);
1212 /* Add in two parts as move_points_text() returns ptr to static
1213 * End result: "Moves: (fuel)moves_left" */
1214 astr_add_line(astr
, "%s: (%s)", _("Moves"),
1215 move_points_text((rate
* f
) + punit
->moves_left
, FALSE
));
1216 astr_add(astr
, "%s",
1217 move_points_text(punit
->moves_left
, FALSE
));
1219 astr_add_line(astr
, "%s: %s", _("Moves"),
1220 move_points_text(punit
->moves_left
, FALSE
));
1223 case ACTIVITY_POLLUTION
:
1224 case ACTIVITY_FALLOUT
:
1225 case ACTIVITY_OLD_ROAD
:
1226 case ACTIVITY_OLD_RAILROAD
:
1227 case ACTIVITY_TRANSFORM
:
1228 case ACTIVITY_FORTIFYING
:
1229 case ACTIVITY_FORTIFIED
:
1230 case ACTIVITY_AIRBASE
:
1231 case ACTIVITY_FORTRESS
:
1232 case ACTIVITY_SENTRY
:
1234 case ACTIVITY_EXPLORE
:
1235 case ACTIVITY_CONVERT
:
1236 astr_add_line(astr
, "%s", get_activity_text(punit
->activity
));
1239 case ACTIVITY_IRRIGATE
:
1240 if (punit
->activity_target
== NULL
) {
1241 astr_add_line(astr
, "%s", get_activity_text(punit
->activity
));
1243 astr_add_line(astr
, "Building %s",
1244 extra_name_translation(punit
->activity_target
));
1247 case ACTIVITY_PILLAGE
:
1248 if (punit
->activity_target
!= NULL
) {
1249 astr_add_line(astr
, "%s: %s", get_activity_text(punit
->activity
),
1250 extra_name_translation(punit
->activity_target
));
1252 astr_add_line(astr
, "%s", get_activity_text(punit
->activity
));
1256 astr_add_line(astr
, "%s: %s", get_activity_text(punit
->activity
),
1257 extra_name_translation(punit
->activity_target
));
1259 case ACTIVITY_GEN_ROAD
:
1260 astr_add_line(astr
, "%s: %s", get_activity_text(punit
->activity
),
1261 extra_name_translation(punit
->activity_target
));
1263 case ACTIVITY_UNKNOWN
:
1264 case ACTIVITY_PATROL_UNUSED
:
1269 log_error("Unknown unit activity %d for %s (nb %d) in %s()",
1270 punit
->activity
, unit_rule_name(punit
), punit
->id
, __FUNCTION__
);
1273 /**************************************************************************
1274 Append a line of text describing the unit's upkeep to the astring.
1276 NB: In the client it is assumed that this information is only available
1277 for units owned by the client's player; the caller must check this.
1278 **************************************************************************/
1279 void unit_upkeep_astr(const struct unit
*punit
, struct astring
*astr
)
1281 if (!punit
|| !astr
) {
1285 astr_add_line(astr
, "%s %d/%d/%d", _("Food/Shield/Gold:"),
1286 punit
->upkeep
[O_FOOD
], punit
->upkeep
[O_SHIELD
],
1287 punit
->upkeep
[O_GOLD
]);
1290 /**************************************************************************
1291 Return the nationality of the unit.
1292 **************************************************************************/
1293 struct player
*unit_nationality(const struct unit
*punit
)
1295 fc_assert_ret_val(NULL
!= punit
, NULL
);
1296 return punit
->nationality
;
1299 /*****************************************************************************
1300 Set the tile location of the unit. Tile can be NULL (for transported units.
1301 *****************************************************************************/
1302 void unit_tile_set(struct unit
*punit
, struct tile
*ptile
)
1304 fc_assert_ret(NULL
!= punit
);
1305 punit
->tile
= ptile
;
1308 /**************************************************************************
1309 Returns true if the tile contains an allied unit and only allied units.
1310 (ie, if your nation A is allied with B, and B is allied with C, a tile
1311 containing units from B and C will return false)
1312 **************************************************************************/
1313 struct unit
*is_allied_unit_tile(const struct tile
*ptile
,
1314 const struct player
*pplayer
)
1316 struct unit
*punit
= NULL
;
1318 unit_list_iterate(ptile
->units
, cunit
) {
1319 if (pplayers_allied(pplayer
, unit_owner(cunit
)))
1324 unit_list_iterate_end
;
1329 /****************************************************************************
1330 Is there an enemy unit on this tile? Returns the unit or NULL if none.
1332 This function is likely to fail if used at the client because the client
1333 doesn't see all units. (Maybe it should be moved into the server code.)
1334 ****************************************************************************/
1335 struct unit
*is_enemy_unit_tile(const struct tile
*ptile
,
1336 const struct player
*pplayer
)
1338 unit_list_iterate(ptile
->units
, punit
) {
1339 if (pplayers_at_war(unit_owner(punit
), pplayer
))
1341 } unit_list_iterate_end
;
1346 /**************************************************************************
1347 is there an non-allied unit on this tile?
1348 **************************************************************************/
1349 struct unit
*is_non_allied_unit_tile(const struct tile
*ptile
,
1350 const struct player
*pplayer
)
1352 unit_list_iterate(ptile
->units
, punit
) {
1353 if (!pplayers_allied(unit_owner(punit
), pplayer
))
1356 unit_list_iterate_end
;
1361 /**************************************************************************
1362 is there an unit belonging to another player on this tile?
1363 **************************************************************************/
1364 struct unit
*is_other_players_unit_tile(const struct tile
*ptile
,
1365 const struct player
*pplayer
)
1367 unit_list_iterate(ptile
->units
, punit
) {
1368 if (unit_owner(punit
) != pplayer
) {
1371 } unit_list_iterate_end
;
1376 /**************************************************************************
1377 is there an unit we have peace or ceasefire with on this tile?
1378 **************************************************************************/
1379 struct unit
*is_non_attack_unit_tile(const struct tile
*ptile
,
1380 const struct player
*pplayer
)
1382 unit_list_iterate(ptile
->units
, punit
) {
1383 if (pplayers_non_attack(unit_owner(punit
), pplayer
))
1386 unit_list_iterate_end
;
1391 /****************************************************************************
1392 Is there an occupying unit on this tile?
1394 Intended for both client and server; assumes that hiding units are not
1395 sent to client. First check tile for known and seen.
1397 called by city_can_work_tile().
1398 ****************************************************************************/
1399 struct unit
*unit_occupies_tile(const struct tile
*ptile
,
1400 const struct player
*pplayer
)
1402 unit_list_iterate(ptile
->units
, punit
) {
1403 if (!is_military_unit(punit
)) {
1407 if (uclass_has_flag(unit_class_get(punit
), UCF_DOESNT_OCCUPY_TILE
)) {
1411 if (pplayers_at_war(unit_owner(punit
), pplayer
)) {
1414 } unit_list_iterate_end
;
1419 /**************************************************************************
1420 Is this square controlled by the pplayer?
1422 Here "is_my_zoc" means essentially a square which is *not* adjacent to an
1423 enemy unit (that has a ZOC) on a terrain that has zoc rules.
1425 Since this function is also used in the client, it has to deal with some
1426 client-specific features, like FoW and the fact that the client cannot
1427 see units inside enemy cities.
1428 **************************************************************************/
1429 bool is_my_zoc(const struct player
*pplayer
, const struct tile
*ptile0
)
1431 struct terrain
*pterrain
;
1433 square_iterate(ptile0
, 1, ptile
) {
1434 pterrain
= tile_terrain(ptile
);
1435 if (T_UNKNOWN
== pterrain
1436 || terrain_has_flag(pterrain
, TER_NO_ZOC
)) {
1440 /* Note: in the client, this loop will not check units
1441 inside city that might be there. */
1442 unit_list_iterate(ptile
->units
, punit
) {
1443 if (!pplayers_allied(unit_owner(punit
), pplayer
)
1444 && !unit_has_type_flag(punit
, UTYF_NOZOC
)) {
1447 } unit_list_iterate_end
;
1450 struct city
*pcity
= is_non_allied_city_tile(ptile
, pplayer
);
1453 && (pcity
->client
.occupied
1454 || TILE_KNOWN_UNSEEN
== tile_get_known(ptile
, pplayer
))) {
1455 /* If the city is fogged, we assume it's occupied */
1459 } square_iterate_end
;
1464 /**************************************************************************
1465 Takes into account unit class flag UCF_ZOC as well as IGZOC
1466 **************************************************************************/
1467 bool unit_type_really_ignores_zoc(const struct unit_type
*punittype
)
1469 return (!uclass_has_flag(utype_class(punittype
), UCF_ZOC
)
1470 || utype_has_flag(punittype
, UTYF_IGZOC
));
1473 /**************************************************************************
1474 An "aggressive" unit is a unit which may cause unhappiness
1475 under a Republic or Democracy.
1476 A unit is *not* aggressive if one or more of following is true:
1477 - zero attack strength
1479 - ground unit inside a fortress within 3 squares of a friendly city
1480 **************************************************************************/
1481 bool unit_being_aggressive(const struct unit
*punit
)
1483 if (!is_attack_unit(punit
)) {
1486 if (tile_city(unit_tile(punit
))) {
1489 if (BORDERS_DISABLED
!= game
.info
.borders
) {
1490 switch (game
.info
.happyborders
) {
1494 if (tile_owner(unit_tile(punit
)) == unit_owner(punit
)) {
1499 if (pplayers_allied(tile_owner(unit_tile(punit
)), unit_owner(punit
))) {
1505 if (tile_has_base_flag_for_unit(unit_tile(punit
),
1506 unit_type_get(punit
),
1507 BF_NOT_AGGRESSIVE
)) {
1508 return !is_unit_near_a_friendly_city(punit
);
1514 /**************************************************************************
1515 Returns true if given activity is some kind of building.
1516 **************************************************************************/
1517 bool is_build_activity(enum unit_activity activity
, const struct tile
*ptile
)
1519 struct terrain
*pterr
= NULL
;
1521 if (ptile
!= NULL
) {
1522 pterr
= tile_terrain(ptile
);
1527 if (pterr
!= NULL
&& pterr
->mining_result
!= pterr
) {
1531 case ACTIVITY_IRRIGATE
:
1532 if (pterr
!= NULL
&& pterr
->irrigation_result
!= pterr
) {
1537 case ACTIVITY_GEN_ROAD
:
1544 /**************************************************************************
1545 Returns true if given activity is some kind of cleaning.
1546 **************************************************************************/
1547 bool is_clean_activity(enum unit_activity activity
)
1550 case ACTIVITY_PILLAGE
:
1551 case ACTIVITY_POLLUTION
:
1552 case ACTIVITY_FALLOUT
:
1559 /**************************************************************************
1560 Returns true if given activity affects tile.
1561 **************************************************************************/
1562 bool is_tile_activity(enum unit_activity activity
)
1564 return is_build_activity(activity
, NULL
)
1565 || is_clean_activity(activity
)
1566 || activity
== ACTIVITY_TRANSFORM
;
1569 /**************************************************************************
1570 Create a virtual unit skeleton. pcity can be NULL, but then you need
1571 to set tile and homecity yourself.
1572 **************************************************************************/
1573 struct unit
*unit_virtual_create(struct player
*pplayer
, struct city
*pcity
,
1574 struct unit_type
*punittype
,
1577 /* Make sure that contents of unit structure are correctly initialized,
1578 * if you ever allocate it by some other mean than fc_calloc() */
1579 struct unit
*punit
= fc_calloc(1, sizeof(*punit
));
1582 /* It does not register the unit so the id is set to 0. */
1583 punit
->id
= IDENTITY_NUMBER_ZERO
;
1585 fc_assert_ret_val(NULL
!= punittype
, NULL
); /* No untyped units! */
1586 punit
->utype
= punittype
;
1588 fc_assert_ret_val(NULL
!= pplayer
, NULL
); /* No unowned units! */
1589 punit
->owner
= pplayer
;
1590 punit
->nationality
= pplayer
;
1592 punit
->facing
= rand_direction();
1595 unit_tile_set(punit
, pcity
->tile
);
1596 punit
->homecity
= pcity
->id
;
1598 unit_tile_set(punit
, NULL
);
1599 punit
->homecity
= IDENTITY_NUMBER_ZERO
;
1602 memset(punit
->upkeep
, 0, O_LAST
* sizeof(*punit
->upkeep
));
1603 punit
->goto_tile
= NULL
;
1604 max_vet_lvl
= utype_veteran_levels(punittype
) - 1;
1605 punit
->veteran
= MIN(veteran_level
, max_vet_lvl
);
1606 /* A unit new and fresh ... */
1607 punit
->fuel
= utype_fuel(unit_type_get(punit
));
1608 punit
->hp
= unit_type_get(punit
)->hp
;
1609 punit
->moves_left
= unit_move_rate(punit
);
1610 punit
->moved
= FALSE
;
1612 punit
->ai_controlled
= FALSE
;
1613 punit
->paradropped
= FALSE
;
1614 punit
->done_moving
= FALSE
;
1616 punit
->transporter
= NULL
;
1617 punit
->transporting
= unit_list_new();
1619 punit
->carrying
= NULL
;
1621 set_unit_activity(punit
, ACTIVITY_IDLE
);
1622 punit
->battlegroup
= BATTLEGROUP_NONE
;
1623 punit
->has_orders
= FALSE
;
1625 punit
->action_decision_want
= ACT_DEC_NOTHING
;
1626 punit
->action_decision_tile
= NULL
;
1629 punit
->server
.debug
= FALSE
;
1630 punit
->server
.birth_turn
= game
.info
.turn
;
1632 punit
->server
.dying
= FALSE
;
1634 punit
->server
.removal_callback
= NULL
;
1636 memset(punit
->server
.upkeep_payed
, 0,
1637 O_LAST
* sizeof(*punit
->server
.upkeep_payed
));
1639 punit
->server
.ord_map
= 0;
1640 punit
->server
.ord_city
= 0;
1642 punit
->server
.vision
= NULL
; /* No vision. */
1643 punit
->server
.action_timestamp
= 0;
1644 /* Must be an invalid turn number, and an invalid previous turn
1646 punit
->server
.action_turn
= -2;
1647 /* punit->server.moving = NULL; set by fc_calloc(). */
1649 punit
->server
.adv
= fc_calloc(1, sizeof(*punit
->server
.adv
));
1651 CALL_FUNC_EACH_AI(unit_alloc
, punit
);
1653 punit
->client
.focus_status
= FOCUS_AVAIL
;
1654 punit
->client
.transported_by
= -1;
1655 punit
->client
.colored
= FALSE
;
1656 punit
->client
.act_prob_cache
= NULL
;
1662 /**************************************************************************
1663 Free the memory used by virtual unit. By the time this function is
1664 called, you should already have unregistered it everywhere.
1665 **************************************************************************/
1666 void unit_virtual_destroy(struct unit
*punit
)
1668 free_unit_orders(punit
);
1670 /* Unload unit if transported. */
1671 unit_transport_unload(punit
);
1672 fc_assert(!unit_transported(punit
));
1674 /* Check for transported units. Use direct access to the list. */
1675 if (unit_list_size(punit
->transporting
) != 0) {
1676 /* Unload all units. */
1677 unit_list_iterate_safe(punit
->transporting
, pcargo
) {
1678 unit_transport_unload(pcargo
);
1679 } unit_list_iterate_safe_end
;
1681 fc_assert(unit_list_size(punit
->transporting
) == 0);
1683 if (punit
->transporting
) {
1684 unit_list_destroy(punit
->transporting
);
1687 CALL_FUNC_EACH_AI(unit_free
, punit
);
1689 if (is_server() && punit
->server
.adv
) {
1690 FC_FREE(punit
->server
.adv
);
1692 if (punit
->client
.act_prob_cache
) {
1693 FC_FREE(punit
->client
.act_prob_cache
);
1700 /**************************************************************************
1701 Free and reset the unit's goto route (punit->pgr). Only used by the
1703 **************************************************************************/
1704 void free_unit_orders(struct unit
*punit
)
1706 if (punit
->has_orders
) {
1707 punit
->goto_tile
= NULL
;
1708 free(punit
->orders
.list
);
1709 punit
->orders
.list
= NULL
;
1711 punit
->has_orders
= FALSE
;
1714 /****************************************************************************
1715 Return how many units are in the transport.
1716 ****************************************************************************/
1717 int get_transporter_occupancy(const struct unit
*ptrans
)
1719 fc_assert_ret_val(ptrans
, -1);
1721 return unit_list_size(ptrans
->transporting
);
1724 /****************************************************************************
1725 Helper for transporter_for_unit() and transporter_for_unit_at()
1726 ****************************************************************************/
1727 static struct unit
*base_transporter_for_unit(const struct unit
*pcargo
,
1728 const struct tile
*ptile
,
1729 bool (*unit_load_test
)
1730 (const struct unit
*pc
,
1731 const struct unit
*pt
))
1733 struct unit
*best_trans
= NULL
;
1735 bool has_orders
, is_idle
, can_freely_unload
;
1736 int depth
, outermost_moves_left
, total_moves
;
1737 } cur
, best
= { FALSE
};
1739 unit_list_iterate(ptile
->units
, ptrans
) {
1740 if (!unit_load_test(pcargo
, ptrans
)) {
1742 } else if (best_trans
== NULL
) {
1743 best_trans
= ptrans
;
1746 /* Gather data from transport stack in a single pass, for use in
1747 * various conditions below. */
1748 cur
.has_orders
= unit_has_orders(ptrans
);
1749 cur
.outermost_moves_left
= ptrans
->moves_left
;
1750 cur
.total_moves
= ptrans
->moves_left
+ unit_move_rate(ptrans
);
1751 unit_transports_iterate(ptrans
, ptranstrans
) {
1752 if (unit_has_orders(ptranstrans
)) {
1753 cur
.has_orders
= TRUE
;
1755 cur
.outermost_moves_left
= ptranstrans
->moves_left
;
1756 cur
.total_moves
+= ptranstrans
->moves_left
+ unit_move_rate(ptranstrans
);
1757 } unit_transports_iterate_end
;
1759 /* Criteria for deciding the 'best' transport to load onto.
1760 * The following tests are applied in order; earlier ones have
1761 * lexicographically greater significance than later ones. */
1763 /* Transports which have orders, or are on transports with orders,
1764 * are less preferable to transport stacks without orders (to
1765 * avoid loading on units that are just passing through). */
1766 if (best_trans
!= ptrans
) {
1767 if (!cur
.has_orders
&& best
.has_orders
) {
1768 best_trans
= ptrans
;
1769 } else if (cur
.has_orders
&& !best
.has_orders
) {
1774 /* Else, transports which are idle are preferable (giving players
1775 * some control over loading) -- this does not check transports
1777 cur
.is_idle
= (ptrans
->activity
== ACTIVITY_IDLE
);
1778 if (best_trans
!= ptrans
) {
1779 if (cur
.is_idle
&& !best
.is_idle
) {
1780 best_trans
= ptrans
;
1781 } else if (!cur
.is_idle
&& best
.is_idle
) {
1786 /* Else, transports from which the cargo could unload at any time
1787 * are preferable to those where the cargo can only disembark in
1789 cur
.can_freely_unload
= utype_can_freely_unload(unit_type_get(pcargo
),
1790 unit_type_get(ptrans
));
1791 if (best_trans
!= ptrans
) {
1792 if (cur
.can_freely_unload
&& !best
.can_freely_unload
) {
1793 best_trans
= ptrans
;
1794 } else if (!cur
.can_freely_unload
&& best
.can_freely_unload
) {
1799 /* Else, transports which are less deeply nested are preferable. */
1800 cur
.depth
= unit_transport_depth(ptrans
);
1801 if (best_trans
!= ptrans
) {
1802 if (cur
.depth
< best
.depth
) {
1803 best_trans
= ptrans
;
1804 } else if (cur
.depth
> best
.depth
) {
1809 /* Else, transport stacks where the outermost transport has more
1810 * moves left are preferable (on the assumption that it's the
1811 * outermost transport that's about to move). */
1812 if (best_trans
!= ptrans
) {
1813 if (cur
.outermost_moves_left
> best
.outermost_moves_left
) {
1814 best_trans
= ptrans
;
1815 } else if (cur
.outermost_moves_left
< best
.outermost_moves_left
) {
1820 /* All other things being equal, as a tie-breaker, compare the total
1821 * moves left (this turn) and move rate (future turns) for the whole
1822 * stack, to take into account total potential movement for both
1823 * short and long journeys (we don't know which the cargo intends to
1824 * make). Doesn't try to account for whether transports can unload,
1826 if (best_trans
!= ptrans
) {
1827 if (cur
.total_moves
> best
.total_moves
) {
1828 best_trans
= ptrans
;
1834 fc_assert(best_trans
== ptrans
);
1836 } unit_list_iterate_end
;
1841 /****************************************************************************
1842 Find the best transporter at the given location for the unit. See also
1843 unit_can_load() to test if there will be transport might be suitable
1845 ****************************************************************************/
1846 struct unit
*transporter_for_unit(const struct unit
*pcargo
)
1848 return base_transporter_for_unit(pcargo
, unit_tile(pcargo
), can_unit_load
);
1851 /****************************************************************************
1852 Find the best transporter at the given location for the unit. See also
1853 unit_could_load_at() to test if there will be transport might be suitable
1855 ****************************************************************************/
1856 struct unit
*transporter_for_unit_at(const struct unit
*pcargo
,
1857 const struct tile
*ptile
)
1859 return base_transporter_for_unit(pcargo
, ptile
, could_unit_load
);
1862 /****************************************************************************
1863 Check if unit of given type would be able to transport all of transport's
1865 ****************************************************************************/
1866 static bool can_type_transport_units_cargo(const struct unit_type
*utype
,
1867 const struct unit
*punit
)
1869 if (get_transporter_occupancy(punit
) > utype
->transport_capacity
) {
1873 unit_list_iterate(punit
->transporting
, pcargo
) {
1874 if (!can_unit_type_transport(utype
, unit_class_get(pcargo
))) {
1877 } unit_list_iterate_end
;
1882 /****************************************************************************
1883 Tests if the unit could be updated. Returns UU_OK if is this is
1886 is_free should be set if the unit upgrade is "free" (e.g., Leonardo's).
1887 Otherwise money is needed and the unit must be in an owned city.
1889 Note that this function is strongly tied to unittools.c:upgrade_unit().
1890 ****************************************************************************/
1891 enum unit_upgrade_result
unit_upgrade_test(const struct unit
*punit
,
1894 struct player
*pplayer
= unit_owner(punit
);
1895 struct unit_type
*to_unittype
= can_upgrade_unittype(pplayer
,
1896 unit_type_get(punit
));
1901 return UU_NO_UNITTYPE
;
1905 cost
= unit_upgrade_price(pplayer
, unit_type_get(punit
), to_unittype
);
1906 if (pplayer
->economic
.gold
< cost
) {
1910 pcity
= tile_city(unit_tile(punit
));
1912 return UU_NOT_IN_CITY
;
1914 if (city_owner(pcity
) != pplayer
) {
1915 /* TODO: should upgrades in allied cities be possible? */
1916 return UU_NOT_CITY_OWNER
;
1920 if (!can_type_transport_units_cargo(to_unittype
, punit
)) {
1921 /* TODO: allow transported units to be reassigned. Check here
1922 * and make changes to upgrade_unit. */
1923 return UU_NOT_ENOUGH_ROOM
;
1926 if (punit
->transporter
!= NULL
) {
1927 if (!can_unit_type_transport(unit_type_get(punit
->transporter
),
1928 unit_class_get(punit
))) {
1929 return UU_UNSUITABLE_TRANSPORT
;
1931 } else if (!can_exist_at_tile(to_unittype
, unit_tile(punit
))) {
1932 /* The new unit type can't survive on this terrain. */
1933 return UU_NOT_TERRAIN
;
1939 /**************************************************************************
1940 Tests if unit can be converted to another type.
1941 **************************************************************************/
1942 bool unit_can_convert(const struct unit
*punit
)
1944 struct unit_type
*tgt
= unit_type_get(punit
)->converted_to
;
1950 if (!can_type_transport_units_cargo(tgt
, punit
)) {
1954 if (!can_exist_at_tile(tgt
, unit_tile(punit
))) {
1961 /**************************************************************************
1962 Find the result of trying to upgrade the unit, and a message that
1963 most callers can use directly.
1964 **************************************************************************/
1965 enum unit_upgrade_result
unit_upgrade_info(const struct unit
*punit
,
1966 char *buf
, size_t bufsz
)
1968 struct player
*pplayer
= unit_owner(punit
);
1969 enum unit_upgrade_result result
= unit_upgrade_test(punit
, FALSE
);
1971 struct unit_type
*from_unittype
= unit_type_get(punit
);
1972 struct unit_type
*to_unittype
= can_upgrade_unittype(pplayer
,
1973 unit_type_get(punit
));
1974 char tbuf
[MAX_LEN_MSG
];
1976 fc_snprintf(tbuf
, ARRAY_SIZE(tbuf
), PL_("Treasury contains %d gold.",
1977 "Treasury contains %d gold.",
1978 pplayer
->economic
.gold
),
1979 pplayer
->economic
.gold
);
1983 upgrade_cost
= unit_upgrade_price(pplayer
, from_unittype
, to_unittype
);
1984 /* This message is targeted toward the GUI callers. */
1985 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1986 fc_snprintf(buf
, bufsz
, PL_("Upgrade %s to %s for %d gold?\n%s",
1987 "Upgrade %s to %s for %d gold?\n%s",
1989 utype_name_translation(from_unittype
),
1990 utype_name_translation(to_unittype
),
1991 upgrade_cost
, tbuf
);
1993 case UU_NO_UNITTYPE
:
1994 fc_snprintf(buf
, bufsz
,
1995 _("Sorry, cannot upgrade %s (yet)."),
1996 utype_name_translation(from_unittype
));
1999 upgrade_cost
= unit_upgrade_price(pplayer
, from_unittype
, to_unittype
);
2000 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
2001 fc_snprintf(buf
, bufsz
, PL_("Upgrading %s to %s costs %d gold.\n%s",
2002 "Upgrading %s to %s costs %d gold.\n%s",
2004 utype_name_translation(from_unittype
),
2005 utype_name_translation(to_unittype
),
2006 upgrade_cost
, tbuf
);
2008 case UU_NOT_IN_CITY
:
2009 case UU_NOT_CITY_OWNER
:
2010 fc_snprintf(buf
, bufsz
,
2011 _("You can only upgrade units in your cities."));
2013 case UU_NOT_ENOUGH_ROOM
:
2014 fc_snprintf(buf
, bufsz
,
2015 _("Upgrading this %s would strand units it transports."),
2016 utype_name_translation(from_unittype
));
2018 case UU_NOT_TERRAIN
:
2019 fc_snprintf(buf
, bufsz
,
2020 _("Upgrading this %s would result in a %s which can not "
2021 "survive at this place."),
2022 utype_name_translation(from_unittype
),
2023 utype_name_translation(to_unittype
));
2025 case UU_UNSUITABLE_TRANSPORT
:
2026 fc_snprintf(buf
, bufsz
,
2027 _("Upgrading this %s would result in a %s which its "
2028 "current transport, %s, could not transport."),
2029 utype_name_translation(from_unittype
),
2030 utype_name_translation(to_unittype
),
2031 unit_name_translation(punit
->transporter
));
2038 /**************************************************************************
2039 Does unit lose hitpoints each turn?
2040 **************************************************************************/
2041 bool is_losing_hp(const struct unit
*punit
)
2043 struct unit_type
*punittype
= unit_type_get(punit
);
2045 return get_unit_bonus(punit
, EFT_UNIT_RECOVER
)
2047 utype_class(punittype
)->hp_loss_pct
/ 100);
2050 /**************************************************************************
2051 Does unit lose hitpoints each turn?
2052 **************************************************************************/
2053 bool unit_type_is_losing_hp(const struct player
*pplayer
,
2054 const struct unit_type
*punittype
)
2056 return get_unittype_bonus(pplayer
, NULL
, punittype
, EFT_UNIT_RECOVER
)
2058 utype_class(punittype
)->hp_loss_pct
/ 100);
2061 /**************************************************************************
2062 Check if unit with given id is still alive. Use this before using
2063 old unit pointers when unit might have died.
2064 **************************************************************************/
2065 bool unit_is_alive(int id
)
2067 /* Check if unit exist in game */
2068 if (game_unit_by_number(id
)) {
2075 /**************************************************************************
2076 Return TRUE if this is a valid unit pointer but does not correspond to
2077 any unit that exists in the game.
2079 NB: A return value of FALSE implies that either the pointer is NULL or
2080 that the unit exists in the game.
2081 **************************************************************************/
2082 bool unit_is_virtual(const struct unit
*punit
)
2088 return punit
!= game_unit_by_number(punit
->id
);
2091 /**************************************************************************
2092 Return pointer to ai data of given unit and ai type.
2093 **************************************************************************/
2094 void *unit_ai_data(const struct unit
*punit
, const struct ai_type
*ai
)
2096 return punit
->server
.ais
[ai_type_number(ai
)];
2099 /**************************************************************************
2100 Attach ai data to unit
2101 **************************************************************************/
2102 void unit_set_ai_data(struct unit
*punit
, const struct ai_type
*ai
,
2105 punit
->server
.ais
[ai_type_number(ai
)] = data
;
2108 /*****************************************************************************
2109 Calculate how expensive it is to bribe the unit. The cost depends on the
2110 distance to the capital, the owner's treasury, and the build cost of the
2111 unit. For a damaged unit the price is reduced. For a veteran unit, it is
2114 The bribe cost for settlers are halved.
2115 **************************************************************************/
2116 int unit_bribe_cost(struct unit
*punit
, struct player
*briber
)
2118 int cost
, default_hp
, dist
= 0;
2119 struct city
*capital
;
2121 fc_assert_ret_val(punit
!= NULL
, 0);
2123 default_hp
= unit_type_get(punit
)->hp
;
2124 cost
= unit_owner(punit
)->economic
.gold
+ game
.info
.base_bribe_cost
;
2125 capital
= player_capital(unit_owner(punit
));
2127 /* Consider the distance to the capital. */
2128 if (capital
!= NULL
) {
2129 dist
= MIN(GAME_UNIT_BRIBE_DIST_MAX
,
2130 map_distance(capital
->tile
, unit_tile(punit
)));
2132 dist
= GAME_UNIT_BRIBE_DIST_MAX
;
2136 /* Consider the build cost. */
2137 cost
*= unit_build_shield_cost(punit
) / 10;
2139 /* Rule set specific cost modification */
2141 * get_target_bonus_effects(NULL
, unit_owner(punit
), briber
,
2142 game_city_by_number(punit
->homecity
),
2143 NULL
, unit_tile(punit
),
2144 punit
, unit_type_get(punit
), NULL
, NULL
,
2146 EFT_UNIT_BRIBE_COST_PCT
))
2149 /* Veterans are not cheap. */
2151 const struct veteran_level
*vlevel
2152 = utype_veteran_level(unit_type_get(punit
), punit
->veteran
);
2154 fc_assert_ret_val(vlevel
!= NULL
, 0);
2155 cost
= cost
* vlevel
->power_fact
/ 100;
2156 if (unit_type_get(punit
)->move_rate
> 0) {
2157 cost
+= cost
* vlevel
->move_bonus
/ unit_type_get(punit
)->move_rate
;
2159 cost
+= cost
* vlevel
->move_bonus
/ SINGLE_MOVE
;
2163 /* Cost now contains the basic bribe cost. We now reduce it by:
2164 * bribecost = cost/2 + cost/2 * damage/hp
2165 * = cost/2 * (1 + damage/hp) */
2166 return ((float)cost
/ 2 * (1.0 + punit
->hp
/ default_hp
));
2169 /*****************************************************************************
2170 Load pcargo onto ptrans. Returns TRUE on success.
2171 *****************************************************************************/
2172 bool unit_transport_load(struct unit
*pcargo
, struct unit
*ptrans
, bool force
)
2174 fc_assert_ret_val(ptrans
!= NULL
, FALSE
);
2175 fc_assert_ret_val(pcargo
!= NULL
, FALSE
);
2177 fc_assert_ret_val(!unit_list_search(ptrans
->transporting
, pcargo
), FALSE
);
2179 if (force
|| can_unit_load(pcargo
, ptrans
)) {
2180 pcargo
->transporter
= ptrans
;
2181 unit_list_append(ptrans
->transporting
, pcargo
);
2189 /*****************************************************************************
2190 Unload pcargo from ptrans. Returns TRUE on success.
2191 *****************************************************************************/
2192 bool unit_transport_unload(struct unit
*pcargo
)
2194 struct unit
*ptrans
;
2196 fc_assert_ret_val(pcargo
!= NULL
, FALSE
);
2198 if (!unit_transported(pcargo
)) {
2199 /* 'pcargo' is not transported. */
2203 /* Get the transporter; must not be defined on the client! */
2204 ptrans
= unit_transport_get(pcargo
);
2208 /* 'pcargo' and 'ptrans' should be on the same tile. */
2209 fc_assert(same_pos(unit_tile(pcargo
), unit_tile(ptrans
)));
2210 /* It is an error if 'pcargo' can not be removed from the 'ptrans'. */
2211 success
= unit_list_remove(ptrans
->transporting
, pcargo
);
2215 /* For the server (also safe for the client). */
2216 pcargo
->transporter
= NULL
;
2221 /*****************************************************************************
2222 Returns TRUE iff the unit is transported.
2223 *****************************************************************************/
2224 bool unit_transported(const struct unit
*pcargo
)
2226 fc_assert_ret_val(pcargo
!= NULL
, FALSE
);
2228 /* The unit is transported if a transporter unit is set or, (for the client)
2229 * if the transported_by field is set. */
2230 if (pcargo
->transporter
!= NULL
2231 || (!is_server() && pcargo
->client
.transported_by
!= -1)) {
2238 /*****************************************************************************
2239 Returns the transporter of the unit or NULL if it is not transported.
2240 *****************************************************************************/
2241 struct unit
*unit_transport_get(const struct unit
*pcargo
)
2243 fc_assert_ret_val(pcargo
!= NULL
, NULL
);
2245 return pcargo
->transporter
;
2248 /*****************************************************************************
2249 Returns the list of cargo units.
2250 *****************************************************************************/
2251 struct unit_list
*unit_transport_cargo(const struct unit
*ptrans
)
2253 fc_assert_ret_val(ptrans
!= NULL
, NULL
);
2254 fc_assert_ret_val(ptrans
->transporting
!= NULL
, NULL
);
2256 return ptrans
->transporting
;
2259 /****************************************************************************
2260 Helper for unit_transport_check().
2261 ****************************************************************************/
2263 unit_transport_check_one(const struct unit_type
*cargo_utype
,
2264 const struct unit_type
*trans_utype
)
2266 return (trans_utype
!= cargo_utype
2267 && !can_unit_type_transport(cargo_utype
,
2268 utype_class(trans_utype
)));
2271 /****************************************************************************
2272 Returns whether 'pcargo' in 'ptrans' is a valid transport. Note that
2273 'pcargo' can already be (but doesn't need) loaded into 'ptrans'.
2275 It may fail if one of the cargo unit has the same type of one of the
2276 transporter unit or if one of the cargo unit can transport one of
2278 ****************************************************************************/
2279 bool unit_transport_check(const struct unit
*pcargo
,
2280 const struct unit
*ptrans
)
2282 const struct unit_type
*cargo_utype
= unit_type_get(pcargo
);
2284 /* Check 'pcargo' against 'ptrans'. */
2285 if (!unit_transport_check_one(cargo_utype
, unit_type_get(ptrans
))) {
2289 /* Check 'pcargo' against 'ptrans' parents. */
2290 unit_transports_iterate(ptrans
, pparent
) {
2291 if (!unit_transport_check_one(cargo_utype
, unit_type_get(pparent
))) {
2294 } unit_transports_iterate_end
;
2296 /* Check cargo children... */
2297 unit_cargo_iterate(pcargo
, pchild
) {
2298 cargo_utype
= unit_type_get(pchild
);
2300 /* ...against 'ptrans'. */
2301 if (!unit_transport_check_one(cargo_utype
, unit_type_get(ptrans
))) {
2305 /* ...and against 'ptrans' parents. */
2306 unit_transports_iterate(ptrans
, pparent
) {
2307 if (!unit_transport_check_one(cargo_utype
, unit_type_get(pparent
))) {
2310 } unit_transports_iterate_end
;
2311 } unit_cargo_iterate_end
;
2316 /****************************************************************************
2317 Returns whether 'pcargo' is transported by 'ptrans', either directly
2319 ****************************************************************************/
2320 bool unit_contained_in(const struct unit
*pcargo
, const struct unit
*ptrans
)
2322 unit_transports_iterate(pcargo
, plevel
) {
2323 if (ptrans
== plevel
) {
2326 } unit_transports_iterate_end
;
2330 /****************************************************************************
2331 Returns the number of unit cargo layers within transport 'ptrans'.
2332 ****************************************************************************/
2333 int unit_cargo_depth(const struct unit
*ptrans
)
2335 struct cargo_iter iter
;
2336 struct iterator
*it
;
2339 for (it
= cargo_iter_init(&iter
, ptrans
); iterator_valid(it
);
2340 iterator_next(it
)) {
2341 if (iter
.depth
> depth
) {
2348 /****************************************************************************
2349 Returns the number of unit transport layers which carry unit 'pcargo'.
2350 ****************************************************************************/
2351 int unit_transport_depth(const struct unit
*pcargo
)
2355 unit_transports_iterate(pcargo
, plevel
) {
2357 } unit_transports_iterate_end
;
2361 /****************************************************************************
2362 Returns the size of the unit cargo iterator.
2363 ****************************************************************************/
2364 size_t cargo_iter_sizeof(void)
2366 return sizeof(struct cargo_iter
);
2369 /****************************************************************************
2370 Get the unit of the cargo iterator.
2371 ****************************************************************************/
2372 static void *cargo_iter_get(const struct iterator
*it
)
2374 const struct cargo_iter
*iter
= CARGO_ITER(it
);
2376 return unit_list_link_data(iter
->links
[iter
->depth
- 1]);
2379 /****************************************************************************
2380 Try to find next unit for the cargo iterator.
2381 ****************************************************************************/
2382 static void cargo_iter_next(struct iterator
*it
)
2384 struct cargo_iter
*iter
= CARGO_ITER(it
);
2385 const struct unit_list_link
*piter
= iter
->links
[iter
->depth
- 1];
2386 const struct unit_list_link
*pnext
;
2388 /* Variant 1: unit has cargo. */
2389 pnext
= unit_list_head(unit_transport_cargo(unit_list_link_data(piter
)));
2390 if (NULL
!= pnext
) {
2391 fc_assert(iter
->depth
< ARRAY_SIZE(iter
->links
));
2392 iter
->links
[iter
->depth
++] = pnext
;
2397 /* Variant 2: there are other cargo units at same level. */
2398 pnext
= unit_list_link_next(piter
);
2399 if (NULL
!= pnext
) {
2400 iter
->links
[iter
->depth
- 1] = pnext
;
2404 /* Variant 3: return to previous level, and do same tests. */
2405 piter
= iter
->links
[iter
->depth
-- - 2];
2406 } while (0 < iter
->depth
);
2409 /****************************************************************************
2410 Return whether the iterator is still valid.
2411 ****************************************************************************/
2412 static bool cargo_iter_valid(const struct iterator
*it
)
2414 return (0 < CARGO_ITER(it
)->depth
);
2417 /****************************************************************************
2418 Initialize the cargo iterator.
2419 ****************************************************************************/
2420 struct iterator
*cargo_iter_init(struct cargo_iter
*iter
,
2421 const struct unit
*ptrans
)
2423 struct iterator
*it
= ITERATOR(iter
);
2425 it
->get
= cargo_iter_get
;
2426 it
->next
= cargo_iter_next
;
2427 it
->valid
= cargo_iter_valid
;
2428 iter
->links
[0] = unit_list_head(unit_transport_cargo(ptrans
));
2429 iter
->depth
= (NULL
!= iter
->links
[0] ? 1 : 0);
2434 /****************************************************************************
2435 Is a cityfounder unit?
2436 ****************************************************************************/
2437 bool unit_is_cityfounder(const struct unit
*punit
)
2439 return utype_is_cityfounder(unit_type_get(punit
));