Freeciv21
Develop your civilization from humble roots to a global empire
unit_utils.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 1996-2021 Freeciv contributors
2 // SPDX-FileCopyrightText: 1996-2021 Freeciv21 contributors
3 // SPDX-FileCopyrightText: 2022 Louis Moureaux
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
6 #include "unit_utils.h"
7 
8 #include "game.h"
9 #include "tile.h"
10 #include "unit.h"
11 
20 static int hp_gain_coord(struct unit *punit)
21 {
22  int bonus, hp;
23  const int base = unit_type_get(punit)->hp;
24 
25  // Includes barracks (100%), fortress (25%), etc.
26  bonus = get_unit_bonus(punit, EFT_HP_REGEN);
27  bonus = MAX(bonus, get_unit_bonus(punit, EFT_HP_REGEN_MIN));
28  if (bonus <= 0)
29  return 0;
30  hp = (base - 1) * bonus / 100 + 1; // rounds up
31 
32  return MAX(hp, 0);
33 }
34 
45 void unit_restore_hitpoints(struct unit *punit)
46 {
47  bool was_lower;
48  int save_hp;
49  struct unit_class *pclass = unit_class_get(punit);
50  struct city *pcity = tile_city(unit_tile(punit));
51 
52  was_lower = (punit->hp < unit_type_get(punit)->hp);
53  save_hp = punit->hp;
54 
55  if (!punit->moved) {
56  punit->hp += hp_gain_coord(punit);
57  }
58 
59  // Bonus recovery HP (traditionally from the United Nations)
60  punit->hp += get_unit_bonus(punit, EFT_UNIT_RECOVER);
61 
62  if (!punit->homecity && 0 < game.info.killunhomed
63  && !unit_has_type_flag(punit, UTYF_GAMELOSS)) {
64  // Hit point loss of units without homecity; at least 1 hp!
65  // Gameloss units are immune to this effect.
66  int hp_loss =
67  MAX(unit_type_get(punit)->hp * game.info.killunhomed / 100, 1);
68  punit->hp = MIN(punit->hp - hp_loss, save_hp - 1);
69  }
70 
71  if (!pcity && !tile_has_native_base(unit_tile(punit), unit_type_get(punit))
72  && !unit_transported(punit)) {
73  punit->hp -= unit_type_get(punit)->hp * pclass->hp_loss_pct / 100;
74  }
75 
76  if (punit->hp >= unit_type_get(punit)->hp) {
77  punit->hp = unit_type_get(punit)->hp;
78  if (was_lower && punit->activity == ACTIVITY_SENTRY) {
79  set_unit_activity(punit, ACTIVITY_IDLE);
80  }
81  }
82 
83  if (punit->hp < 0) {
84  punit->hp = 0;
85  }
86 
87  punit->moved = false;
88  punit->paradropped = false;
89 }
static int hp_gain_coord(struct unit *punit)
returns how many hp's a unit will gain on this square depends on whether or not it's inside city or f...
Definition: unit_utils.cpp:20
void unit_restore_hitpoints(struct unit *punit)
add hitpoints to the unit, hp_gain_coord returns the amount to add united nations will speed up the p...
Definition: unit_utils.cpp:45
static void base(QVariant data1, QVariant data2)
Action "Build Base" for choice dialog.
Definition: dialogs.cpp:2393
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Returns the effect bonus at a unit.
Definition: effects.cpp:869
struct civ_game game
Definition: game.cpp:47
#define MIN(x, y)
Definition: shared.h:49
#define MAX(x, y)
Definition: shared.h:48
Definition: city.h:291
struct packet_game_info info
Definition: game.h:80
int hp_loss_pct
Definition: unittype.h:126
int hp
Definition: unittype.h:489
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
bool moved
Definition: unit.h:170
int hp
Definition: unit.h:148
int homecity
Definition: unit.h:142
bool paradropped
Definition: unit.h:171
bool tile_has_native_base(const struct tile *ptile, const struct unit_type *punittype)
Check if tile contains base native for unit.
Definition: tile.cpp:327
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Assign a new untargeted task to a unit.
Definition: unit.cpp:1011
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
#define unit_tile(_pu)
Definition: unit.h:371
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
struct unit_class * unit_class_get(const struct unit *punit)
Returns unit class pointer for a unit.
Definition: unittype.cpp:2151
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176