Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / combat.c
bloba9dbe5ad4df9131a387cb01611b8ee5b22618897
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 #include <math.h>
20 /* utility */
21 #include "bitvector.h"
22 #include "rand.h"
23 #include "log.h"
25 /* common */
26 #include "base.h"
27 #include "game.h"
28 #include "map.h"
29 #include "movement.h"
30 #include "packets.h"
31 #include "unit.h"
32 #include "unitlist.h"
33 #include "unittype.h"
35 #include "combat.h"
37 /***********************************************************************
38 Checks if player is restricted diplomatically from attacking the tile.
39 Returns FLASE if
40 1) the tile is empty or
41 2) the tile contains a non-enemy city or
42 3) the tile contains a non-enemy unit
43 ***********************************************************************/
44 bool can_player_attack_tile(const struct player *pplayer,
45 const struct tile *ptile)
47 struct city *pcity = tile_city(ptile);
49 /* 1. Is there anyone there at all? */
50 if (!pcity && unit_list_size((ptile->units)) == 0) {
51 return FALSE;
54 /* 2. If there is a city there, can we attack it? */
55 if (pcity && !pplayers_at_war(city_owner(pcity), pplayer)) {
56 return FALSE;
59 /* 3. Are we allowed to attack _all_ units there? */
60 unit_list_iterate(ptile->units, aunit) {
61 if (!pplayers_at_war(unit_owner(aunit), pplayer)) {
62 /* Enemy hiding behind a human/diplomatic shield */
63 return FALSE;
65 } unit_list_iterate_end;
67 return TRUE;
70 /***********************************************************************
71 Can unit attack other
72 ***********************************************************************/
73 static bool is_unit_reachable_by_unit(const struct unit *defender,
74 const struct unit *attacker)
76 struct unit_class *dclass = unit_class_get(defender);
77 struct unit_type *atype = unit_type_get(attacker);
79 return BV_ISSET(atype->targets, uclass_index(dclass));
82 /***********************************************************************
83 Can unit attack other at given location
84 ***********************************************************************/
85 bool is_unit_reachable_at(const struct unit *defender,
86 const struct unit *attacker,
87 const struct tile *location)
89 if (NULL != tile_city(location)) {
90 return TRUE;
93 if (is_unit_reachable_by_unit(defender, attacker)) {
94 return TRUE;
97 if (tile_has_native_base(location, unit_type_get(defender))) {
98 return TRUE;
101 return FALSE;
104 /***********************************************************************
105 Checks if a unit can physically attack pdefender at the tile
106 (assuming it is adjacent and at war).
108 Unit can NOT attack if:
109 1) it does not have any attack power.
110 2) it is not a fighter and defender is a flying unit (except city/airbase).
111 3) it is a ground unit without marine ability and it attacks from ocean.
112 4) it is a ground unit and it attacks a target on an ocean square.
113 5) it is a sailing unit without shore bombardment capability and it
114 attempts to attack land.
116 Does NOT check:
117 1) Moves left
118 2) Adjacency
119 3) Diplomatic status
120 ***********************************************************************/
121 enum unit_attack_result unit_attack_unit_at_tile_result(const struct unit *punit,
122 const struct unit *pdefender,
123 const struct tile *dest_tile)
125 /* 1. Can we attack _anything_ ? */
126 if (!is_military_unit(punit) || !is_attack_unit(punit)) {
127 return ATT_NON_ATTACK;
130 /* 2. Only fighters can attack planes, except in city or airbase attacks */
131 if (!is_unit_reachable_at(pdefender, punit, dest_tile)) {
132 return ATT_UNREACHABLE;
135 /* 3. Can't attack with ground unit from ocean, except for marines */
136 if (!is_native_tile(unit_type_get(punit), unit_tile(punit))
137 && !utype_can_do_act_when_ustate(unit_type_get(punit), ACTION_ATTACK,
138 USP_NATIVE_TILE, FALSE)) {
139 return ATT_NONNATIVE_SRC;
142 /* 4. Most units can not attack non-native terrain.
143 * Most ships can attack land tiles (shore bombardment) */
144 if (!is_native_tile(unit_type_get(punit), dest_tile)
145 && !can_attack_non_native(unit_type_get(punit))) {
146 return ATT_NONNATIVE_DST;
149 return ATT_OK;
152 /***********************************************************************
153 When unreachable_protects setting is TRUE:
154 To attack a stack, unit must be able to attack every unit there (not
155 including transported units).
156 ************************************************************************/
157 static enum unit_attack_result unit_attack_all_at_tile_result(const struct unit *punit,
158 const struct tile *ptile)
160 unit_list_iterate(ptile->units, aunit) {
161 /* HACK: we don't count transported units here. This prevents some
162 * bugs like a submarine carrying a cruise missile being invulnerable
163 * to other sea units. However from a gameplay perspective it's a hack,
164 * since players can load and unload their units manually to protect
165 * their transporters. */
166 if (!unit_transported(aunit)) {
167 enum unit_attack_result result;
169 result = unit_attack_unit_at_tile_result(punit, aunit, ptile);
170 if (result != ATT_OK) {
171 return result;
174 } unit_list_iterate_end;
176 return ATT_OK;
179 /***********************************************************************
180 When unreachable_protects setting is FALSE:
181 To attack a stack, unit must be able to attack some unit there (not
182 including transported units).
183 ************************************************************************/
184 static enum unit_attack_result unit_attack_any_at_tile_result(const struct unit *punit,
185 const struct tile *ptile)
187 enum unit_attack_result result = ATT_OK;
189 unit_list_iterate(ptile->units, aunit) {
190 /* HACK: we don't count transported units here. This prevents some
191 * bugs like a cargoplane carrying a land unit being vulnerable. */
192 if (!unit_transported(aunit)) {
193 result = unit_attack_unit_at_tile_result(punit, aunit, ptile);
194 if (result == ATT_OK) {
195 return result;
198 } unit_list_iterate_end;
200 /* That's result from check against last unit on tile, not first.
201 * Shouldn't matter. */
202 return result;
205 /***********************************************************************
206 Check if unit can attack unit stack at tile.
207 ***********************************************************************/
208 enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit,
209 const struct tile *ptile)
211 if (game.info.unreachable_protects) {
212 return unit_attack_all_at_tile_result(punit, ptile);
213 } else {
214 return unit_attack_any_at_tile_result(punit, ptile);
218 /***********************************************************************
219 Is unit (1) diplomatically allowed to attack and (2) physically able
220 to do so?
221 ***********************************************************************/
222 bool can_unit_attack_tile(const struct unit *punit,
223 const struct tile *dest_tile)
225 return (can_player_attack_tile(unit_owner(punit), dest_tile)
226 && unit_attack_units_at_tile_result(punit, dest_tile) == ATT_OK);
229 /***********************************************************************
230 Returns the chance of the attacker winning, a number between 0 and 1.
231 If you want the chance that the defender wins just use 1-chance(...)
233 NOTE: this number can be _very_ small, fx in a battle between an
234 ironclad and a battleship the ironclad has less than 1/100000 chance of
235 winning.
237 The algoritm calculates the probability of each possible number of HP's
238 the attacker has left. Maybe that info should be preserved for use in
239 the AI.
240 ***********************************************************************/
241 double win_chance(int as, int ahp, int afp, int ds, int dhp, int dfp)
243 /* number of rounds a unit can fight without dying */
244 int att_N_lose = (ahp + dfp - 1) / dfp;
245 int def_N_lose = (dhp + afp - 1) / afp;
246 /* Probability of losing one round */
247 double att_P_lose1 = (as + ds == 0) ? 0.5 : (double) ds / (as + ds);
248 double def_P_lose1 = 1 - att_P_lose1;
251 This calculates
253 binomial_coeff(def_N_lose-1 + lr, lr)
254 * def_P_lose1^(def_N_lose-1)
255 * att_P_lose1^(lr)
256 * def_P_lose1
258 for each possible number of rounds lost (rl) by the winning unit.
259 rl is of course less than the number of rounds the winning unit
260 should lose to lose all it's hit points.
261 The probabilities are then summed.
263 To see this is correct consider the set of series for all valid fights.
264 These series are the type (win, lose, lose...). The possible lenghts are
265 def_N_lose to def_N_lose+att_N_lose-1. A series is not valid unless it
266 contains def_N_lose wins, and one of the wins must be the last one, or
267 the series would be equivalent the a shorter series (the attacker would
268 have won one or more fights previously).
269 So since the last fight is a win we disregard it while calculating. Now
270 a series contains def_N_lose-1 wins. So for each possible lenght of a
271 series we find the probability of every valid series and then sum.
272 For a specific lenght (a "lr") every series have the probability
273 def_P_lose1^(def_N_lose-1) * att_P_lose1^(lr)
274 and then getting from that to the real series requires a win, ie factor
275 def_N_lose. The number of series with lenght (def_N_lose-1 + lr) and
276 "lr" lost fights is
277 binomial_coeff(def_N_lose-1 + lr, lr)
278 And by multiplying we get the formula on the top of this code block.
279 Adding the cumulative probability for each valid lenght then gives the
280 total probability.
282 We clearly have all valid series this way. To see that we have counted
283 none twice note that would require a series with a smaller series inbedded.
284 But since the smaller series already included def_N_lose wins, and the
285 larger series ends with a win, it would have too many wins and therefore
286 cannot exist.
288 In practice each binomial coefficient for a series lenght can be calculated
289 from the previous. In the coefficient (n, k) n is increased and k is
290 unchanged.
291 The "* def_P_lose1" is multiplied on the sum afterwards.
293 (lots of talk for so little code)
296 double binom_save = pow(def_P_lose1, (double)(def_N_lose - 1));
297 double accum_prob = binom_save; /* lr = 0 */
299 int lr; /* the number of Lost Rounds by the attacker */
300 for (lr = 1; lr < att_N_lose; lr++) {
301 /* update the coefficient */
302 int n = lr + def_N_lose - 1;
303 binom_save *= n;
304 binom_save /= lr;
305 binom_save *= att_P_lose1;
306 /* use it for this lr */
307 accum_prob += binom_save;
309 /* Every element of the sum needs a factor for the very last fight round */
310 accum_prob *= def_P_lose1;
312 return accum_prob;
315 /**************************************************************************
316 A unit's effective firepower depend on the situation.
317 **************************************************************************/
318 void get_modified_firepower(const struct unit *attacker,
319 const struct unit *defender,
320 int *att_fp, int *def_fp)
322 struct city *pcity = tile_city(unit_tile(defender));
324 *att_fp = unit_type_get(attacker)->firepower;
325 *def_fp = unit_type_get(defender)->firepower;
327 /* Check CityBuster flag */
328 if (unit_has_type_flag(attacker, UTYF_CITYBUSTER) && pcity) {
329 *att_fp *= 2;
333 * UTYF_BADWALLATTACKER sets the firepower of the attacking unit to 1 if
334 * an EFT_DEFEND_BONUS applies (such as a land unit attacking a city with
335 * city walls).
337 if (unit_has_type_flag(attacker, UTYF_BADWALLATTACKER)
338 && get_unittype_bonus(unit_owner(defender), unit_tile(defender),
339 unit_type_get(attacker), EFT_DEFEND_BONUS) > 0) {
340 *att_fp = 1;
343 /* pearl harbour - defender's firepower is reduced to one,
344 * attacker's is multiplied by two */
345 if (unit_has_type_flag(defender, UTYF_BADCITYDEFENDER)
346 && tile_city(unit_tile(defender))) {
347 *att_fp *= 2;
348 *def_fp = 1;
352 * When attacked by fighters, helicopters have their firepower
353 * reduced to 1.
355 if (combat_bonus_against(unit_type_get(attacker)->bonuses,
356 unit_type_get(defender),
357 CBONUS_FIREPOWER1)) {
358 *def_fp = 1;
361 /* In land bombardment both units have their firepower reduced to 1 */
362 if (!is_native_tile(unit_type_get(attacker), unit_tile(defender))
363 && !can_exist_at_tile(unit_type_get(defender), unit_tile(attacker))) {
364 *att_fp = 1;
365 *def_fp = 1;
369 /**************************************************************************
370 Returns a double in the range [0;1] indicating the attackers chance of
371 winning. The calculation takes all factors into account.
372 **************************************************************************/
373 double unit_win_chance(const struct unit *attacker,
374 const struct unit *defender)
376 int def_power = get_total_defense_power(attacker, defender);
377 int att_power = get_total_attack_power(attacker, defender);
379 double chance;
381 int def_fp, att_fp;
382 get_modified_firepower(attacker, defender, &att_fp, &def_fp);
384 chance = win_chance(att_power, attacker->hp, att_fp,
385 def_power, defender->hp, def_fp);
387 return chance;
390 /**************************************************************************
391 Try defending against nuclear attack; if successful, return a city which
392 had enough luck and EFT_NUKE_PROOF.
393 If the attack was successful return NULL.
394 **************************************************************************/
395 struct city *sdi_try_defend(const struct player *owner,
396 const struct tile *ptile)
398 square_iterate(ptile, 2, ptile1) {
399 struct city *pcity = tile_city(ptile1);
401 if (pcity
402 && fc_rand(100) < get_target_bonus_effects(NULL,
403 city_owner(pcity), owner,
404 pcity, NULL, ptile,
405 NULL, NULL,
406 NULL, NULL, NULL,
407 EFT_NUKE_PROOF)) {
408 return pcity;
410 } square_iterate_end;
412 return NULL;
415 /**************************************************************************
416 Convenience wrapper for base_get_attack_power.
417 **************************************************************************/
418 int get_attack_power(const struct unit *punit)
420 return base_get_attack_power(unit_type_get(punit), punit->veteran,
421 punit->moves_left);
424 /**************************************************************************
425 Returns the attack power, modified by moves left, and veteran
426 status.
427 **************************************************************************/
428 int base_get_attack_power(const struct unit_type *punittype,
429 int veteran, int moves_left)
431 int power;
432 const struct veteran_level *vlevel;
434 fc_assert_ret_val(punittype != NULL, 0);
436 vlevel = utype_veteran_level(punittype, veteran);
437 fc_assert_ret_val(vlevel != NULL, 0);
439 power = punittype->attack_strength * POWER_FACTOR
440 * vlevel->power_fact / 100;
442 if (game.info.tired_attack && moves_left < SINGLE_MOVE) {
443 power = (power * moves_left) / SINGLE_MOVE;
446 return power;
449 /**************************************************************************
450 Returns the defense power, modified by veteran status.
451 **************************************************************************/
452 int base_get_defense_power(const struct unit *punit)
454 const struct veteran_level *vlevel;
456 fc_assert_ret_val(punit != NULL, 0);
458 vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
459 fc_assert_ret_val(vlevel != NULL, 0);
461 return unit_type_get(punit)->defense_strength * POWER_FACTOR
462 * vlevel->power_fact / 100;
465 /**************************************************************************
466 Returns the defense power, modified by terrain and veteran status.
467 Note that rivers as special road types are not handled here as
468 terrain property.
469 **************************************************************************/
470 static int get_defense_power(const struct unit *punit)
472 int db, power = base_get_defense_power(punit);
473 struct tile *ptile = unit_tile(punit);
474 struct unit_class *pclass = unit_class_get(punit);
476 if (uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)) {
477 db = 100 + tile_terrain(ptile)->defense_bonus;
478 power = (power * db) / 100;
481 if (!is_native_tile_to_class(pclass, ptile)) {
482 power = power * pclass->non_native_def_pct / 100;
485 return power;
488 /***************************************************************************
489 Return the modified attack power of a unit.
490 ***************************************************************************/
491 int get_total_attack_power(const struct unit *attacker,
492 const struct unit *defender)
494 int mod;
495 int attackpower = get_attack_power(attacker);
497 mod = 100 + get_unittype_bonus(unit_owner(attacker), unit_tile(defender),
498 unit_type_get(attacker), EFT_ATTACK_BONUS);
500 return attackpower * mod / 100;
503 /**************************************************************************
504 Return an increased defensepower. Effects which increase the
505 defensepower are:
506 - unit type effects (horse vs pikemen for example)
507 - defender in a fortress
508 - fortified defender
510 May be called with a non-existing att_type to avoid any unit type
511 effects.
512 **************************************************************************/
513 static int defense_multiplication(const struct unit_type *att_type,
514 const struct unit_type *def_type,
515 const struct player *def_player,
516 const struct tile *ptile,
517 int defensepower, bool fortified)
519 struct city *pcity = tile_city(ptile);
520 int mod;
522 fc_assert_ret_val(NULL != def_type, 0);
524 if (NULL != att_type) {
525 int defense_divider;
526 int defense_multiplier = 1 + def_type->cache.defense_mp_bonuses[utype_index(att_type)];
528 defensepower *= defense_multiplier;
530 /* This applies even if pcity is NULL. */
531 mod = 100 + get_unittype_bonus(def_player, ptile,
532 att_type, EFT_DEFEND_BONUS);
533 defensepower = MAX(0, defensepower * mod / 100);
535 defense_divider = 1 + combat_bonus_against(att_type->bonuses, def_type,
536 CBONUS_DEFENSE_DIVIDER);
537 defensepower /= defense_divider;
540 defensepower +=
541 defensepower * tile_extras_defense_bonus(ptile, def_type) / 100;
543 if ((pcity || fortified)
544 && uclass_has_flag(utype_class(def_type), UCF_CAN_FORTIFY)
545 && !utype_has_flag(def_type, UTYF_CANT_FORTIFY)) {
546 defensepower = (defensepower * 3) / 2;
549 return defensepower;
552 /**************************************************************************
553 May be called with a non-existing att_type to avoid any effects which
554 depend on the attacker.
555 **************************************************************************/
556 int get_virtual_defense_power(const struct unit_type *att_type,
557 const struct unit_type *def_type,
558 const struct player *def_player,
559 const struct tile *ptile,
560 bool fortified, int veteran)
562 int defensepower = def_type->defense_strength;
563 int db;
564 const struct veteran_level *vlevel;
565 struct unit_class *defclass;
567 fc_assert_ret_val(def_type != NULL, 0);
569 if (!can_exist_at_tile(def_type, ptile)) {
570 /* Ground units on ship doesn't defend. */
571 return 0;
574 vlevel = utype_veteran_level(def_type, veteran);
575 fc_assert_ret_val(vlevel != NULL, 0);
577 defclass = utype_class(def_type);
579 db = POWER_FACTOR;
580 if (uclass_has_flag(defclass, UCF_TERRAIN_DEFENSE)) {
581 db += tile_terrain(ptile)->defense_bonus / (100 / POWER_FACTOR);
583 defensepower *= db;
584 defensepower *= vlevel->power_fact / 100;
585 if (!is_native_tile_to_class(defclass, ptile)) {
586 defensepower = defensepower * defclass->non_native_def_pct / 100;
589 return defense_multiplication(att_type, def_type, def_player,
590 ptile, defensepower,
591 fortified);
594 /***************************************************************************
595 return the modified defense power of a unit.
596 An veteran aegis cruiser in a mountain city with SAM and SDI defense
597 being attacked by a missile gets defense 288.
598 ***************************************************************************/
599 int get_total_defense_power(const struct unit *attacker,
600 const struct unit *defender)
602 return defense_multiplication(unit_type_get(attacker),
603 unit_type_get(defender),
604 unit_owner(defender), unit_tile(defender),
605 get_defense_power(defender),
606 defender->activity == ACTIVITY_FORTIFIED);
609 /***************************************************************************
610 Return total defense power of the unit if it fortifies, if possible,
611 where it is. attacker might be NULL to skip calculating attacker specific
612 bonuses.
613 ***************************************************************************/
614 int get_fortified_defense_power(const struct unit *attacker,
615 const struct unit *defender)
617 struct unit_type *att_type = NULL;
619 if (attacker != NULL) {
620 att_type = unit_type_get(attacker);
623 return defense_multiplication(att_type, unit_type_get(defender),
624 unit_owner(defender), unit_tile(defender),
625 get_defense_power(defender),
626 TRUE);
629 /**************************************************************************
630 A number indicating the defense strength.
631 Unlike the one got from win chance this doesn't potentially get insanely
632 small if the units are unevenly matched, unlike win_chance.
633 **************************************************************************/
634 static int get_defense_rating(const struct unit *attacker,
635 const struct unit *defender)
637 int afp, dfp;
639 int rating = get_total_defense_power(attacker, defender);
640 get_modified_firepower(attacker, defender, &afp, &dfp);
642 /* How many rounds the defender will last */
643 rating *= (defender->hp + afp-1)/afp;
645 rating *= dfp;
647 return rating;
650 /**************************************************************************
651 Finds the best defender on the tile, given an attacker. The diplomatic
652 relationship of attacker and defender is ignored; the caller should check
653 this.
654 **************************************************************************/
655 struct unit *get_defender(const struct unit *attacker,
656 const struct tile *ptile)
658 struct unit *bestdef = NULL;
659 int bestvalue = -99, best_cost = 0, rating_of_best = 0;
661 /* Simply call win_chance with all the possible defenders in turn, and
662 * take the best one. It currently uses build cost as a tiebreaker in
663 * case 2 units are identical, but this is crude as build cost does not
664 * neccesarily have anything to do with the value of a unit. This function
665 * could be improved to take the value of the unit into account. It would
666 * also be nice if the function was a bit more fuzzy about prioritizing,
667 * making it able to fx choose a 1a/9d unit over a 10a/10d unit. It should
668 * also be able to spare units without full hp's to some extent, as these
669 * could be more valuable later. */
670 unit_list_iterate(ptile->units, defender) {
671 /* We used to skip over allied units, but the logic for that is
672 * complicated and is now handled elsewhere. */
673 if (unit_can_defend_here(defender)
674 && unit_attack_unit_at_tile_result(attacker, defender, ptile) == ATT_OK) {
675 bool change = FALSE;
676 int build_cost = unit_build_shield_cost(defender);
677 int defense_rating = get_defense_rating(attacker, defender);
678 /* This will make units roughly evenly good defenders look alike. */
679 int unit_def
680 = (int) (100000 * (1 - unit_win_chance(attacker, defender)));
682 fc_assert_action(0 <= unit_def, continue);
684 if (unit_has_type_flag(defender, UTYF_GAMELOSS)
685 && !is_stack_vulnerable(unit_tile(defender))) {
686 unit_def = -1; /* then always use leader as last defender. */
687 /* FIXME: multiple gameloss units with varying defense value
688 * not handled. */
691 if (unit_def > bestvalue) {
692 change = TRUE;
693 } else if (unit_def == bestvalue) {
694 if (build_cost < best_cost) {
695 change = TRUE;
696 } else if (build_cost == best_cost) {
697 if (rating_of_best < defense_rating) {
698 change = TRUE;
703 if (change) {
704 bestvalue = unit_def;
705 bestdef = defender;
706 best_cost = build_cost;
707 rating_of_best = defense_rating;
710 } unit_list_iterate_end;
712 return bestdef;
715 /**************************************************************************
716 get unit at (x, y) that wants to kill defender.
718 Works like get_defender; see comment there.
719 This function is mostly used by the AI.
720 **************************************************************************/
721 struct unit *get_attacker(const struct unit *defender,
722 const struct tile *ptile)
724 struct unit *bestatt = 0;
725 int bestvalue = -1, unit_a, best_cost = 0;
727 unit_list_iterate(ptile->units, attacker) {
728 int build_cost = unit_build_shield_cost(attacker);
730 if (pplayers_allied(unit_owner(defender), unit_owner(attacker))) {
731 return NULL;
733 unit_a = (int) (100000 * (unit_win_chance(attacker, defender)));
734 if (unit_a > bestvalue ||
735 (unit_a == bestvalue && build_cost < best_cost)) {
736 bestvalue = unit_a;
737 bestatt = attacker;
738 best_cost = build_cost;
740 } unit_list_iterate_end;
742 return bestatt;
745 /**************************************************************************
746 Is it a city/fortress/air base or will the whole stack die in an attack
747 **************************************************************************/
748 bool is_stack_vulnerable(const struct tile *ptile)
750 return (game.info.killstack
751 && !tile_has_extra_flag(ptile, EF_NO_STACK_DEATH)
752 && NULL == tile_city(ptile));
755 /**************************************************************************
756 Get bonus value against given unit type from bonus list.
758 Consider using cached values instead of calling this recalculation
759 directly.
760 **************************************************************************/
761 int combat_bonus_against(const struct combat_bonus_list *list,
762 const struct unit_type *enemy,
763 enum combat_bonus_type type)
765 int value = 0;
767 combat_bonus_list_iterate(list, pbonus) {
768 if (pbonus->type == type && utype_has_flag(enemy, pbonus->flag)) {
769 value += pbonus->value;
771 } combat_bonus_list_iterate_end;
773 return value;