Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / unit.c
blobd9097d5cf0d1c4177ac1d9c4a80b7bbd8ece33b4
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "astring.h"
20 #include "bitvector.h"
21 #include "fcintl.h"
22 #include "mem.h"
23 #include "shared.h"
24 #include "support.h"
26 /* common */
27 #include "ai.h"
28 #include "actions.h"
29 #include "base.h"
30 #include "city.h"
31 #include "game.h"
32 #include "log.h"
33 #include "map.h"
34 #include "movement.h"
35 #include "packets.h"
36 #include "player.h"
37 #include "road.h"
38 #include "tech.h"
39 #include "traderoutes.h"
40 #include "unitlist.h"
42 #include "unit.h"
44 static bool is_real_activity(enum unit_activity activity);
46 Activity_type_id real_activities[ACTIVITY_LAST];
48 struct cargo_iter {
49 struct iterator vtable;
50 const struct unit_list_link *links[GAME_TRANSPORT_MAX_RECURSIVE];
51 int depth;
53 #define CARGO_ITER(iter) ((struct cargo_iter *) (iter))
55 /****************************************************************************
56 Determines if punit can be airlifted to dest_city now! So punit needs
57 to be in a city now.
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),
76 ACTION_AIRLIFT, 0)) {
77 /* No moves left. */
78 return AR_NO_MOVES;
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. */
87 return AR_OCCUPIED;
90 if (NULL == psrc_city) {
91 /* No city there. */
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;
100 if (pdest_city
101 && (NULL == restriction
102 || (tile_get_known(city_tile(pdest_city), restriction)
103 == TILE_KNOWN_SEEN))
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;
121 if (pdest_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
133 * or no airport).
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 */
140 } else {
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;
146 if (pdest_city) {
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 */
155 } else {
156 ok_result = AR_OK_DST_UNKNOWN;
160 return ok_result;
163 /****************************************************************************
164 Determines if punit can be airlifted to dest_city now! So punit needs
165 to be in a city now.
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
168 player knowledge.
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);
175 if (is_server()) {
176 return is_action_enabled_unit_on_city(ACTION_AIRLIFT,
177 punit, pdest_city);
178 } else {
179 return action_prob_possible(action_prob_vs_city(punit, ACTION_AIRLIFT,
180 pdest_city));
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));
200 if (!pcity) {
201 /* No city to help at this tile. */
202 return FALSE;
205 if (!utype_can_do_action(unit_type_get(punit), ACTION_HELP_WONDER)) {
206 /* This unit can never do help wonder. */
207 return FALSE;
210 /* Evaluate all action enablers for extra accuracy. */
211 /* TODO: Is it worth it? */
212 return action_prob_possible(action_prob_vs_city(punit,
213 ACTION_HELP_WONDER,
214 pcity));
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,
271 const int action_id)
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) {
284 if ((omniscient
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)))) {
292 return TRUE;
294 } unit_list_iterate_end;
295 } square_iterate_end;
297 return FALSE;
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
313 this flag.
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));
344 } else {
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)
356 if (pcity == NULL) {
357 /* Can't change home city to a non existing city. */
358 return FALSE;
361 return action_prob_possible(action_prob_vs_city(punit, ACTION_HOME_CITY,
362 pcity));
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);
414 } else {
415 return 0;
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 */
437 } else {
438 return FC_INFINITY;
442 /**************************************************************************
443 Return TRUE if activity requires some sort of target to be specified.
444 **************************************************************************/
445 bool activity_requires_target(enum unit_activity activity)
447 switch (activity) {
448 case ACTIVITY_PILLAGE:
449 case ACTIVITY_BASE:
450 case ACTIVITY_GEN_ROAD:
451 case ACTIVITY_IRRIGATE:
452 case ACTIVITY_MINE:
453 case ACTIVITY_POLLUTION:
454 case ACTIVITY_FALLOUT:
455 return TRUE;
456 case ACTIVITY_IDLE:
457 case ACTIVITY_FORTIFIED:
458 case ACTIVITY_SENTRY:
459 case ACTIVITY_GOTO:
460 case ACTIVITY_EXPLORE:
461 case ACTIVITY_TRANSFORM:
462 case ACTIVITY_FORTIFYING:
463 case ACTIVITY_CONVERT:
464 return FALSE;
465 /* These shouldn't be kicking around internally. */
466 case ACTIVITY_FORTRESS:
467 case ACTIVITY_AIRBASE:
468 case ACTIVITY_PATROL_UNUSED:
469 default:
470 fc_assert_ret_val(FALSE, FALSE);
473 return 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
483 handled separately.
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;
496 int i = 0;
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. */
532 switch (activity) {
533 case ACTIVITY_IDLE:
534 return _("Idle");
535 case ACTIVITY_POLLUTION:
536 return _("Pollution");
537 case ACTIVITY_MINE:
538 /* TRANS: Activity name, verb in English */
539 return _("Plant");
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:
547 return _("Sentry");
548 case ACTIVITY_PILLAGE:
549 return _("Pillage");
550 case ACTIVITY_GOTO:
551 return _("Goto");
552 case ACTIVITY_EXPLORE:
553 return _("Explore");
554 case ACTIVITY_TRANSFORM:
555 return _("Transform");
556 case ACTIVITY_FALLOUT:
557 return _("Fallout");
558 case ACTIVITY_BASE:
559 return _("Base");
560 case ACTIVITY_GEN_ROAD:
561 return _("Road");
562 case ACTIVITY_CONVERT:
563 return _("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:
570 case ACTIVITY_LAST:
571 break;
574 fc_assert(FALSE);
575 return _("Unknown");
578 /****************************************************************************
579 Return TRUE iff the given unit could be loaded into the transporter
580 if we moved there.
581 ****************************************************************************/
582 bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
584 if (!pcargo || !ptrans || pcargo == ptrans) {
585 return FALSE;
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))) {
591 return FALSE;
594 /* Make sure this transporter can carry this type of unit. */
595 if (!can_unit_transport(ptrans, pcargo)) {
596 return FALSE;
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))) {
603 return FALSE;
606 /* Make sure there's room in the transporter. */
607 if (get_transporter_occupancy(ptrans)
608 >= get_transporter_capacity(ptrans)) {
609 return FALSE;
612 /* Check iff this is a valid transport. */
613 if (!unit_transport_check(pcargo, ptrans)) {
614 return FALSE;
617 /* Check transport depth. */
618 if (GAME_TRANSPORT_MAX_RECURSIVE
619 < 1 + unit_transport_depth(ptrans) + unit_cargo_depth(pcargo)) {
620 return FALSE;
623 return TRUE;
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))) {
636 return FALSE;
639 /* Cannot load if cargo is already loaded onto something else. */
640 if (unit_transported(pcargo)) {
641 return FALSE;
644 return could_unit_load(pcargo, ptrans);
647 /****************************************************************************
648 Return TRUE iff the given unit can be unloaded from its current
649 transporter.
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) {
659 return FALSE;
662 /* Make sure the unit's transporter exists and is known. */
663 if (unit_transport_get(pcargo) != ptrans) {
664 return FALSE;
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))) {
671 return FALSE;
674 return TRUE;
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;
696 bool result;
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;
706 return result;
709 /**************************************************************************
710 Return TRUE iff the unit can do the given untargeted activity at its
711 current location.
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,
732 EC_IRRIGATION,
733 unit_owner(punit),
734 punit);
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,
741 EC_MINE,
742 unit_owner(punit),
743 punit);
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
755 location.
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,
762 unit_tile(punit));
765 /**************************************************************************
766 Return TRUE if the unit can do the targeted activity at the given
767 location.
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
778 * gets executed. */
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)) {
785 return FALSE;
787 } unit_list_iterate_end;
790 switch(activity) {
791 case ACTIVITY_IDLE:
792 case ACTIVITY_GOTO:
793 return TRUE;
795 case ACTIVITY_POLLUTION:
797 struct extra_type *pextra;
799 if (pterrain->clean_pollution_time == 0) {
800 return FALSE;
803 if (target != NULL) {
804 pextra = target;
805 } else {
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,
809 ERM_CLEANPOLLUTION,
810 unit_owner(punit),
811 punit);
812 if (pextra == NULL) {
813 /* No available pollution extras */
814 return FALSE;
818 if (!is_extra_removed_by(pextra, ERM_CLEANPOLLUTION)) {
819 return FALSE;
822 if (!unit_has_type_flag(punit, UTYF_SETTLERS)
823 || !can_remove_extra(pextra, punit, ptile)) {
824 return FALSE;
827 if (tile_has_extra(ptile, pextra)) {
828 return TRUE;
831 return FALSE;
834 case ACTIVITY_FALLOUT:
836 struct extra_type *pextra;
838 if (pterrain->clean_fallout_time == 0) {
839 return FALSE;
842 if (target != NULL) {
843 pextra = target;
844 } else {
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,
848 ERM_CLEANFALLOUT,
849 unit_owner(punit),
850 punit);
851 if (pextra == NULL) {
852 /* No available pollution extras */
853 return FALSE;
857 if (!is_extra_removed_by(pextra, ERM_CLEANFALLOUT)) {
858 return FALSE;
861 if (!unit_has_type_flag(punit, UTYF_SETTLERS)
862 || !can_remove_extra(pextra, punit, ptile)) {
863 return FALSE;
866 if (tile_has_extra(ptile, pextra)) {
867 return TRUE;
870 return FALSE;
873 case ACTIVITY_MINE:
874 if (pterrain->mining_result == pterrain) {
875 if (target == NULL) {
876 return FALSE;
879 if (pterrain->mining_time == 0) {
880 return FALSE;
883 if (!is_extra_caused_by(target, EC_MINE)) {
884 return FALSE;
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
895 && target == NULL
896 && terrain_surroundings_allow_change(ptile,
897 pterrain->mining_result)
898 && (!terrain_has_flag(pterrain->mining_result, TER_NO_CITIES)
899 || !tile_city(ptile))))) {
900 return TRUE;
901 } else {
902 return FALSE;
905 case ACTIVITY_IRRIGATE:
906 if (pterrain->irrigation_result == pterrain) {
907 if (target == NULL) {
908 return FALSE;
911 if (pterrain->irrigation_time == 0) {
912 return FALSE;
915 if (!is_extra_caused_by(target, EC_IRRIGATION)) {
916 return FALSE;
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
927 && target == NULL
928 && terrain_surroundings_allow_change(ptile,
929 pterrain->irrigation_result)
930 && (!terrain_has_flag(pterrain->irrigation_result, TER_NO_CITIES)
931 || !tile_city(ptile))))) {
932 return TRUE;
933 } else {
934 return FALSE;
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:
944 return FALSE;
946 case ACTIVITY_BASE:
947 if (target == NULL) {
948 return FALSE;
950 return can_build_base(punit, extra_base_get(target), ptile);
952 case ACTIVITY_GEN_ROAD:
953 if (target == NULL) {
954 return FALSE;
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. */
962 return FALSE;
964 return TRUE;
966 case ACTIVITY_PILLAGE:
968 if (pterrain->pillage_time == 0) {
969 return FALSE;
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) {
991 required = TRUE;
992 break;
994 } extra_deps_iterate_end;
996 if (required) {
997 break;
999 } extra_type_iterate_end;
1001 if (!required) {
1002 BV_SET(pspossible, idx);
1005 } extra_type_iterate_end;
1007 if (!BV_ISSET_ANY(pspossible)) {
1008 /* Nothing available to pillage */
1009 return FALSE;
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 */
1015 return TRUE;
1016 } else {
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 */
1026 return FALSE;
1030 return BV_ISSET(pspossible, extra_index(target));
1032 } else {
1033 /* Unit is not a type that can pillage at all */
1034 return FALSE;
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:
1058 case ACTIVITY_LAST:
1059 case ACTIVITY_UNKNOWN:
1060 break;
1062 log_error("can_unit_do_activity_targeted_at() unknown activity %d",
1063 activity);
1064 return FALSE;
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,
1124 Base_type_id base)
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,
1138 Road_type_id road)
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) {
1156 return TRUE;
1158 } unit_list_iterate_end;
1159 return FALSE;
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)
1168 bv_extras tgt_ret;
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;
1177 return tgt_ret;
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;
1189 astr_clear(&str);
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) {
1201 return;
1204 switch (punit->activity) {
1205 case ACTIVITY_IDLE:
1206 if (utype_fuel(unit_type_get(punit))) {
1207 int rate, f;
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));
1218 } else {
1219 astr_add_line(astr, "%s: %s", _("Moves"),
1220 move_points_text(punit->moves_left, FALSE));
1222 return;
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:
1233 case ACTIVITY_GOTO:
1234 case ACTIVITY_EXPLORE:
1235 case ACTIVITY_CONVERT:
1236 astr_add_line(astr, "%s", get_activity_text(punit->activity));
1237 return;
1238 case ACTIVITY_MINE:
1239 case ACTIVITY_IRRIGATE:
1240 if (punit->activity_target == NULL) {
1241 astr_add_line(astr, "%s", get_activity_text(punit->activity));
1242 } else {
1243 astr_add_line(astr, "Building %s",
1244 extra_name_translation(punit->activity_target));
1246 return;
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));
1251 } else {
1252 astr_add_line(astr, "%s", get_activity_text(punit->activity));
1254 return;
1255 case ACTIVITY_BASE:
1256 astr_add_line(astr, "%s: %s", get_activity_text(punit->activity),
1257 extra_name_translation(punit->activity_target));
1258 return;
1259 case ACTIVITY_GEN_ROAD:
1260 astr_add_line(astr, "%s: %s", get_activity_text(punit->activity),
1261 extra_name_translation(punit->activity_target));
1262 return;
1263 case ACTIVITY_UNKNOWN:
1264 case ACTIVITY_PATROL_UNUSED:
1265 case ACTIVITY_LAST:
1266 break;
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) {
1282 return;
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)))
1320 punit = cunit;
1321 else
1322 return NULL;
1324 unit_list_iterate_end;
1326 return punit;
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))
1340 return punit;
1341 } unit_list_iterate_end;
1343 return NULL;
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))
1354 return punit;
1356 unit_list_iterate_end;
1358 return NULL;
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) {
1369 return punit;
1371 } unit_list_iterate_end;
1373 return NULL;
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))
1384 return punit;
1386 unit_list_iterate_end;
1388 return NULL;
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)) {
1404 continue;
1407 if (uclass_has_flag(unit_class_get(punit), UCF_DOESNT_OCCUPY_TILE)) {
1408 continue;
1411 if (pplayers_at_war(unit_owner(punit), pplayer)) {
1412 return punit;
1414 } unit_list_iterate_end;
1416 return NULL;
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)) {
1437 continue;
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)) {
1445 return FALSE;
1447 } unit_list_iterate_end;
1449 if (!is_server()) {
1450 struct city *pcity = is_non_allied_city_tile(ptile, pplayer);
1452 if (pcity
1453 && (pcity->client.occupied
1454 || TILE_KNOWN_UNSEEN == tile_get_known(ptile, pplayer))) {
1455 /* If the city is fogged, we assume it's occupied */
1456 return FALSE;
1459 } square_iterate_end;
1461 return TRUE;
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
1478 - inside a city
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)) {
1484 return FALSE;
1486 if (tile_city(unit_tile(punit))) {
1487 return FALSE;
1489 if (BORDERS_DISABLED != game.info.borders) {
1490 switch (game.info.happyborders) {
1491 case HB_DISABLED:
1492 break;
1493 case HB_NATIONAL:
1494 if (tile_owner(unit_tile(punit)) == unit_owner(punit)) {
1495 return FALSE;
1497 break;
1498 case HB_ALLIANCE:
1499 if (pplayers_allied(tile_owner(unit_tile(punit)), unit_owner(punit))) {
1500 return FALSE;
1502 break;
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);
1511 return TRUE;
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);
1525 switch (activity) {
1526 case ACTIVITY_MINE:
1527 if (pterr != NULL && pterr->mining_result != pterr) {
1528 return FALSE;
1530 return TRUE;
1531 case ACTIVITY_IRRIGATE:
1532 if (pterr != NULL && pterr->irrigation_result != pterr) {
1533 return FALSE;
1535 return TRUE;
1536 case ACTIVITY_BASE:
1537 case ACTIVITY_GEN_ROAD:
1538 return TRUE;
1539 default:
1540 return FALSE;
1544 /**************************************************************************
1545 Returns true if given activity is some kind of cleaning.
1546 **************************************************************************/
1547 bool is_clean_activity(enum unit_activity activity)
1549 switch (activity) {
1550 case ACTIVITY_PILLAGE:
1551 case ACTIVITY_POLLUTION:
1552 case ACTIVITY_FALLOUT:
1553 return TRUE;
1554 default:
1555 return FALSE;
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,
1575 int veteran_level)
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));
1580 int max_vet_lvl;
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();
1594 if (pcity) {
1595 unit_tile_set(punit, pcity->tile);
1596 punit->homecity = pcity->id;
1597 } else {
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;
1628 if (is_server()) {
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
1645 * number. */
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);
1652 } else {
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;
1659 return punit;
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);
1691 } else {
1692 if (punit->client.act_prob_cache) {
1693 FC_FREE(punit->client.act_prob_cache);
1697 FC_FREE(punit);
1700 /**************************************************************************
1701 Free and reset the unit's goto route (punit->pgr). Only used by the
1702 server.
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;
1734 struct {
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)) {
1741 continue;
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) {
1770 continue;
1774 /* Else, transports which are idle are preferable (giving players
1775 * some control over loading) -- this does not check transports
1776 * of 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) {
1782 continue;
1786 /* Else, transports from which the cargo could unload at any time
1787 * are preferable to those where the cargo can only disembark in
1788 * cities/bases. */
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) {
1795 continue;
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) {
1805 continue;
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) {
1816 continue;
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,
1825 * etc. */
1826 if (best_trans != ptrans) {
1827 if (cur.total_moves > best.total_moves) {
1828 best_trans = ptrans;
1829 } else {
1830 continue;
1834 fc_assert(best_trans == ptrans);
1835 best = cur;
1836 } unit_list_iterate_end;
1838 return best_trans;
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
1844 for 'pcargo'.
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
1854 for 'pcargo'.
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
1864 cargo.
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) {
1870 return FALSE;
1873 unit_list_iterate(punit->transporting, pcargo) {
1874 if (!can_unit_type_transport(utype, unit_class_get(pcargo))) {
1875 return FALSE;
1877 } unit_list_iterate_end;
1879 return TRUE;
1882 /****************************************************************************
1883 Tests if the unit could be updated. Returns UU_OK if is this is
1884 possible.
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,
1892 bool is_free)
1894 struct player *pplayer = unit_owner(punit);
1895 struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
1896 unit_type_get(punit));
1897 struct city *pcity;
1898 int cost;
1900 if (!to_unittype) {
1901 return UU_NO_UNITTYPE;
1904 if (!is_free) {
1905 cost = unit_upgrade_price(pplayer, unit_type_get(punit), to_unittype);
1906 if (pplayer->economic.gold < cost) {
1907 return UU_NO_MONEY;
1910 pcity = tile_city(unit_tile(punit));
1911 if (!pcity) {
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;
1936 return UU_OK;
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;
1946 if (tgt == NULL) {
1947 return FALSE;
1950 if (!can_type_transport_units_cargo(tgt, punit)) {
1951 return FALSE;
1954 if (!can_exist_at_tile(tgt, unit_tile(punit))) {
1955 return FALSE;
1958 return TRUE;
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);
1970 int upgrade_cost;
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);
1981 switch (result) {
1982 case UU_OK:
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",
1988 upgrade_cost),
1989 utype_name_translation(from_unittype),
1990 utype_name_translation(to_unittype),
1991 upgrade_cost, tbuf);
1992 break;
1993 case UU_NO_UNITTYPE:
1994 fc_snprintf(buf, bufsz,
1995 _("Sorry, cannot upgrade %s (yet)."),
1996 utype_name_translation(from_unittype));
1997 break;
1998 case UU_NO_MONEY:
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",
2003 upgrade_cost),
2004 utype_name_translation(from_unittype),
2005 utype_name_translation(to_unittype),
2006 upgrade_cost, tbuf);
2007 break;
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."));
2012 break;
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));
2017 break;
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));
2024 break;
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));
2032 break;
2035 return result;
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)
2046 < (punittype->hp *
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)
2057 < (punittype->hp *
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)) {
2069 return TRUE;
2072 return FALSE;
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)
2084 if (!punit) {
2085 return FALSE;
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,
2103 void *data)
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
2112 increased.
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)));
2131 } else {
2132 dist = GAME_UNIT_BRIBE_DIST_MAX;
2134 cost /= dist + 2;
2136 /* Consider the build cost. */
2137 cost *= unit_build_shield_cost(punit) / 10;
2139 /* Rule set specific cost modification */
2140 cost += (cost
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,
2145 NULL,
2146 EFT_UNIT_BRIBE_COST_PCT))
2147 / 100;
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;
2158 } else {
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);
2183 return TRUE;
2186 return FALSE;
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. */
2200 return FALSE;
2203 /* Get the transporter; must not be defined on the client! */
2204 ptrans = unit_transport_get(pcargo);
2205 if (ptrans) {
2206 bool success;
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);
2212 fc_assert(success);
2215 /* For the server (also safe for the client). */
2216 pcargo->transporter = NULL;
2218 return TRUE;
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)) {
2232 return TRUE;
2235 return FALSE;
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 ****************************************************************************/
2262 static inline bool
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
2277 the transporters.
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))) {
2286 return FALSE;
2289 /* Check 'pcargo' against 'ptrans' parents. */
2290 unit_transports_iterate(ptrans, pparent) {
2291 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2292 return FALSE;
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))) {
2302 return FALSE;
2305 /* ...and against 'ptrans' parents. */
2306 unit_transports_iterate(ptrans, pparent) {
2307 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2308 return FALSE;
2310 } unit_transports_iterate_end;
2311 } unit_cargo_iterate_end;
2313 return TRUE;
2316 /****************************************************************************
2317 Returns whether 'pcargo' is transported by 'ptrans', either directly
2318 or indirectly.
2319 ****************************************************************************/
2320 bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
2322 unit_transports_iterate(pcargo, plevel) {
2323 if (ptrans == plevel) {
2324 return TRUE;
2326 } unit_transports_iterate_end;
2327 return FALSE;
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;
2337 int depth = 0;
2339 for (it = cargo_iter_init(&iter, ptrans); iterator_valid(it);
2340 iterator_next(it)) {
2341 if (iter.depth > depth) {
2342 depth = iter.depth;
2345 return depth;
2348 /****************************************************************************
2349 Returns the number of unit transport layers which carry unit 'pcargo'.
2350 ****************************************************************************/
2351 int unit_transport_depth(const struct unit *pcargo)
2353 int level = 0;
2355 unit_transports_iterate(pcargo, plevel) {
2356 level++;
2357 } unit_transports_iterate_end;
2358 return level;
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;
2393 return;
2396 do {
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;
2401 return;
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);
2431 return it;
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));