Move tools_fc_interface.[c|h] to tools/shared.
[freeciv.git] / common / combat.c
blob4d05474d4fc380ff48555b206d829fbba0202cbd
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(&(wld.map),
364 unit_type_get(defender), unit_tile(attacker))) {
365 *att_fp = 1;
366 *def_fp = 1;
370 /**************************************************************************
371 Returns a double in the range [0;1] indicating the attackers chance of
372 winning. The calculation takes all factors into account.
373 **************************************************************************/
374 double unit_win_chance(const struct unit *attacker,
375 const struct unit *defender)
377 int def_power = get_total_defense_power(attacker, defender);
378 int att_power = get_total_attack_power(attacker, defender);
380 double chance;
382 int def_fp, att_fp;
383 get_modified_firepower(attacker, defender, &att_fp, &def_fp);
385 chance = win_chance(att_power, attacker->hp, att_fp,
386 def_power, defender->hp, def_fp);
388 return chance;
391 /**************************************************************************
392 Try defending against nuclear attack; if successful, return a city which
393 had enough luck and EFT_NUKE_PROOF.
394 If the attack was successful return NULL.
395 **************************************************************************/
396 struct city *sdi_try_defend(const struct player *owner,
397 const struct tile *ptile)
399 square_iterate(&(wld.map), ptile, 2, ptile1) {
400 struct city *pcity = tile_city(ptile1);
402 if (pcity
403 && fc_rand(100) < get_target_bonus_effects(NULL,
404 city_owner(pcity), owner,
405 pcity, NULL, ptile,
406 NULL, NULL,
407 NULL, NULL, NULL,
408 EFT_NUKE_PROOF)) {
409 return pcity;
411 } square_iterate_end;
413 return NULL;
416 /**************************************************************************
417 Convenience wrapper for base_get_attack_power.
418 **************************************************************************/
419 int get_attack_power(const struct unit *punit)
421 return base_get_attack_power(unit_type_get(punit), punit->veteran,
422 punit->moves_left);
425 /**************************************************************************
426 Returns the attack power, modified by moves left, and veteran
427 status.
428 **************************************************************************/
429 int base_get_attack_power(const struct unit_type *punittype,
430 int veteran, int moves_left)
432 int power;
433 const struct veteran_level *vlevel;
435 fc_assert_ret_val(punittype != NULL, 0);
437 vlevel = utype_veteran_level(punittype, veteran);
438 fc_assert_ret_val(vlevel != NULL, 0);
440 power = punittype->attack_strength * POWER_FACTOR
441 * vlevel->power_fact / 100;
443 if (game.info.tired_attack && moves_left < SINGLE_MOVE) {
444 power = (power * moves_left) / SINGLE_MOVE;
447 return power;
450 /**************************************************************************
451 Returns the defense power, modified by veteran status.
452 **************************************************************************/
453 int base_get_defense_power(const struct unit *punit)
455 const struct veteran_level *vlevel;
457 fc_assert_ret_val(punit != NULL, 0);
459 vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
460 fc_assert_ret_val(vlevel != NULL, 0);
462 return unit_type_get(punit)->defense_strength * POWER_FACTOR
463 * vlevel->power_fact / 100;
466 /**************************************************************************
467 Returns the defense power, modified by terrain and veteran status.
468 Note that rivers as special road types are not handled here as
469 terrain property.
470 **************************************************************************/
471 static int get_defense_power(const struct unit *punit)
473 int db, power = base_get_defense_power(punit);
474 struct tile *ptile = unit_tile(punit);
475 struct unit_class *pclass = unit_class_get(punit);
477 if (uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)) {
478 db = 100 + tile_terrain(ptile)->defense_bonus;
479 power = (power * db) / 100;
482 if (!is_native_tile_to_class(pclass, ptile)) {
483 power = power * pclass->non_native_def_pct / 100;
486 return power;
489 /***************************************************************************
490 Return the modified attack power of a unit.
491 ***************************************************************************/
492 int get_total_attack_power(const struct unit *attacker,
493 const struct unit *defender)
495 int mod;
496 int attackpower = get_attack_power(attacker);
498 mod = 100 + get_unittype_bonus(unit_owner(attacker), unit_tile(defender),
499 unit_type_get(attacker), EFT_ATTACK_BONUS);
501 return attackpower * mod / 100;
504 /**************************************************************************
505 Return an increased defensepower. Effects which increase the
506 defensepower are:
507 - unit type effects (horse vs pikemen for example)
508 - defender in a fortress
509 - fortified defender
511 May be called with a non-existing att_type to avoid any unit type
512 effects.
513 **************************************************************************/
514 static int defense_multiplication(const struct unit_type *att_type,
515 const struct unit_type *def_type,
516 const struct player *def_player,
517 const struct tile *ptile,
518 int defensepower, bool fortified)
520 struct city *pcity = tile_city(ptile);
521 int mod;
523 fc_assert_ret_val(NULL != def_type, 0);
525 if (NULL != att_type) {
526 int defense_divider;
527 int defense_multiplier = 1 + def_type->cache.defense_mp_bonuses[utype_index(att_type)];
529 defensepower *= defense_multiplier;
531 /* This applies even if pcity is NULL. */
532 mod = 100 + get_unittype_bonus(def_player, ptile,
533 att_type, EFT_DEFEND_BONUS);
534 defensepower = MAX(0, defensepower * mod / 100);
536 defense_divider = 1 + combat_bonus_against(att_type->bonuses, def_type,
537 CBONUS_DEFENSE_DIVIDER);
538 defensepower /= defense_divider;
541 defensepower +=
542 defensepower * tile_extras_defense_bonus(ptile, def_type) / 100;
544 if ((pcity || fortified)
545 && uclass_has_flag(utype_class(def_type), UCF_CAN_FORTIFY)
546 && !utype_has_flag(def_type, UTYF_CANT_FORTIFY)) {
547 defensepower = (defensepower * 3) / 2;
550 return defensepower;
553 /**************************************************************************
554 May be called with a non-existing att_type to avoid any effects which
555 depend on the attacker.
556 **************************************************************************/
557 int get_virtual_defense_power(const struct unit_type *att_type,
558 const struct unit_type *def_type,
559 const struct player *def_player,
560 const struct tile *ptile,
561 bool fortified, int veteran)
563 int defensepower = def_type->defense_strength;
564 int db;
565 const struct veteran_level *vlevel;
566 struct unit_class *defclass;
568 fc_assert_ret_val(def_type != NULL, 0);
570 if (!can_exist_at_tile(&(wld.map), def_type, ptile)) {
571 /* Ground units on ship doesn't defend. */
572 return 0;
575 vlevel = utype_veteran_level(def_type, veteran);
576 fc_assert_ret_val(vlevel != NULL, 0);
578 defclass = utype_class(def_type);
580 db = POWER_FACTOR;
581 if (uclass_has_flag(defclass, UCF_TERRAIN_DEFENSE)) {
582 db += tile_terrain(ptile)->defense_bonus / (100 / POWER_FACTOR);
584 defensepower *= db;
585 defensepower *= vlevel->power_fact / 100;
586 if (!is_native_tile_to_class(defclass, ptile)) {
587 defensepower = defensepower * defclass->non_native_def_pct / 100;
590 return defense_multiplication(att_type, def_type, def_player,
591 ptile, defensepower,
592 fortified);
595 /***************************************************************************
596 return the modified defense power of a unit.
597 An veteran aegis cruiser in a mountain city with SAM and SDI defense
598 being attacked by a missile gets defense 288.
599 ***************************************************************************/
600 int get_total_defense_power(const struct unit *attacker,
601 const struct unit *defender)
603 return defense_multiplication(unit_type_get(attacker),
604 unit_type_get(defender),
605 unit_owner(defender), unit_tile(defender),
606 get_defense_power(defender),
607 defender->activity == ACTIVITY_FORTIFIED);
610 /***************************************************************************
611 Return total defense power of the unit if it fortifies, if possible,
612 where it is. attacker might be NULL to skip calculating attacker specific
613 bonuses.
614 ***************************************************************************/
615 int get_fortified_defense_power(const struct unit *attacker,
616 const struct unit *defender)
618 struct unit_type *att_type = NULL;
620 if (attacker != NULL) {
621 att_type = unit_type_get(attacker);
624 return defense_multiplication(att_type, unit_type_get(defender),
625 unit_owner(defender), unit_tile(defender),
626 get_defense_power(defender),
627 TRUE);
630 /**************************************************************************
631 A number indicating the defense strength.
632 Unlike the one got from win chance this doesn't potentially get insanely
633 small if the units are unevenly matched, unlike win_chance.
634 **************************************************************************/
635 static int get_defense_rating(const struct unit *attacker,
636 const struct unit *defender)
638 int afp, dfp;
640 int rating = get_total_defense_power(attacker, defender);
641 get_modified_firepower(attacker, defender, &afp, &dfp);
643 /* How many rounds the defender will last */
644 rating *= (defender->hp + afp-1)/afp;
646 rating *= dfp;
648 return rating;
651 /**************************************************************************
652 Finds the best defender on the tile, given an attacker. The diplomatic
653 relationship of attacker and defender is ignored; the caller should check
654 this.
655 **************************************************************************/
656 struct unit *get_defender(const struct unit *attacker,
657 const struct tile *ptile)
659 struct unit *bestdef = NULL;
660 int bestvalue = -99, best_cost = 0, rating_of_best = 0;
662 /* Simply call win_chance with all the possible defenders in turn, and
663 * take the best one. It currently uses build cost as a tiebreaker in
664 * case 2 units are identical, but this is crude as build cost does not
665 * neccesarily have anything to do with the value of a unit. This function
666 * could be improved to take the value of the unit into account. It would
667 * also be nice if the function was a bit more fuzzy about prioritizing,
668 * making it able to fx choose a 1a/9d unit over a 10a/10d unit. It should
669 * also be able to spare units without full hp's to some extent, as these
670 * could be more valuable later. */
671 unit_list_iterate(ptile->units, defender) {
672 /* We used to skip over allied units, but the logic for that is
673 * complicated and is now handled elsewhere. */
674 if (unit_can_defend_here(&(wld.map), defender)
675 && unit_attack_unit_at_tile_result(attacker, defender, ptile) == ATT_OK) {
676 bool change = FALSE;
677 int build_cost = unit_build_shield_cost(defender);
678 int defense_rating = get_defense_rating(attacker, defender);
679 /* This will make units roughly evenly good defenders look alike. */
680 int unit_def
681 = (int) (100000 * (1 - unit_win_chance(attacker, defender)));
683 fc_assert_action(0 <= unit_def, continue);
685 if (unit_has_type_flag(defender, UTYF_GAMELOSS)
686 && !is_stack_vulnerable(unit_tile(defender))) {
687 unit_def = -1; /* then always use leader as last defender. */
688 /* FIXME: multiple gameloss units with varying defense value
689 * not handled. */
692 if (unit_def > bestvalue) {
693 change = TRUE;
694 } else if (unit_def == bestvalue) {
695 if (build_cost < best_cost) {
696 change = TRUE;
697 } else if (build_cost == best_cost) {
698 if (rating_of_best < defense_rating) {
699 change = TRUE;
704 if (change) {
705 bestvalue = unit_def;
706 bestdef = defender;
707 best_cost = build_cost;
708 rating_of_best = defense_rating;
711 } unit_list_iterate_end;
713 return bestdef;
716 /**************************************************************************
717 get unit at (x, y) that wants to kill defender.
719 Works like get_defender; see comment there.
720 This function is mostly used by the AI.
721 **************************************************************************/
722 struct unit *get_attacker(const struct unit *defender,
723 const struct tile *ptile)
725 struct unit *bestatt = 0;
726 int bestvalue = -1, unit_a, best_cost = 0;
728 unit_list_iterate(ptile->units, attacker) {
729 int build_cost = unit_build_shield_cost(attacker);
731 if (pplayers_allied(unit_owner(defender), unit_owner(attacker))) {
732 return NULL;
734 unit_a = (int) (100000 * (unit_win_chance(attacker, defender)));
735 if (unit_a > bestvalue ||
736 (unit_a == bestvalue && build_cost < best_cost)) {
737 bestvalue = unit_a;
738 bestatt = attacker;
739 best_cost = build_cost;
741 } unit_list_iterate_end;
743 return bestatt;
746 /**************************************************************************
747 Is it a city/fortress/air base or will the whole stack die in an attack
748 **************************************************************************/
749 bool is_stack_vulnerable(const struct tile *ptile)
751 return (game.info.killstack
752 && !tile_has_extra_flag(ptile, EF_NO_STACK_DEATH)
753 && NULL == tile_city(ptile));
756 /**************************************************************************
757 Get bonus value against given unit type from bonus list.
759 Consider using cached values instead of calling this recalculation
760 directly.
761 **************************************************************************/
762 int combat_bonus_against(const struct combat_bonus_list *list,
763 const struct unit_type *enemy,
764 enum combat_bonus_type type)
766 int value = 0;
768 combat_bonus_list_iterate(list, pbonus) {
769 if (pbonus->type == type && utype_has_flag(enemy, pbonus->flag)) {
770 value += pbonus->value;
772 } combat_bonus_list_iterate_end;
774 return value;