summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/birth.cc80
-rw-r--r--src/birth.hpp2
-rw-r--r--src/game.hpp11
-rw-r--r--src/loadsave.cc2
-rw-r--r--src/variable.cc8
-rw-r--r--src/variable.hpp1
-rw-r--r--src/wizard2.cc31
-rw-r--r--src/xtra1.cc8
8 files changed, 71 insertions, 72 deletions
diff --git a/src/birth.cc b/src/birth.cc
index 06c2115e..25b1beff 100644
--- a/src/birth.cc
+++ b/src/birth.cc
@@ -59,6 +59,7 @@
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include <numeric>
#include <string>
/*
@@ -442,13 +443,53 @@ static void get_stats(void)
/*
- * Roll for some info that the auto-roller ignores
+ * Roll for player HP
*/
-static void get_extra(void)
+void roll_player_hp()
{
- int i, j, min_value, max_value;
+ auto &player_hp = game->player_hp;
+
+ // Minimum hitpoints at highest level
+ int const min_value =
+ (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8 + PY_MAX_LEVEL;
+
+ // Maximum hitpoints at highest level
+ int const max_value =
+ (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8 + PY_MAX_LEVEL;
+
+ // Pre-calculate level 1 hitdice; first roll is always maximal
+ player_hp[0] = p_ptr->hitdie;
+
+ // Roll out the hitpoints
+ while (true)
+ {
+ // Roll the hitpoint values
+ std::generate(
+ player_hp.begin() + 1,
+ player_hp.end(),
+ []() { return randint(p_ptr->hitdie); });
+ // Sum along
+ std::partial_sum(
+ player_hp.begin(),
+ player_hp.end(),
+ player_hp.begin());
+ // Require "valid" hitpoints at highest level
+ if (player_hp.back() < min_value) continue;
+ if (player_hp.back() > max_value) continue;
+
+ // Acceptable
+ break;
+ }
+}
+
+
+/*
+ * Roll for some info that the auto-roller ignores
+ */
+static void get_extra(void)
+{
/* Level one */
p_ptr->max_plv = p_ptr->lev = 1;
@@ -464,37 +505,10 @@ static void get_extra(void)
/* Initial hitpoints */
p_ptr->mhp = p_ptr->hitdie;
- /* Minimum hitpoints at highest level */
- min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8;
- min_value += PY_MAX_LEVEL;
-
- /* Maximum hitpoints at highest level */
- max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8;
- max_value += PY_MAX_LEVEL;
-
- /* Pre-calculate level 1 hitdice */
- player_hp[0] = p_ptr->hitdie;
-
- /* Roll out the hitpoints */
- while (TRUE)
- {
- /* Roll the hitpoint values */
- for (i = 1; i < PY_MAX_LEVEL; i++)
- {
- j = randint(p_ptr->hitdie);
- player_hp[i] = player_hp[i - 1] + j;
- }
-
- /* XXX Could also require acceptable "mid-level" hitpoints */
-
- /* Require "valid" hitpoints at highest level */
- if (player_hp[PY_MAX_LEVEL - 1] < min_value) continue;
- if (player_hp[PY_MAX_LEVEL - 1] > max_value) continue;
-
- /* Acceptable */
- break;
- }
+ /* Roll for HP */
+ roll_player_hp();
+ /* Set tactics and movement */
p_ptr->tactic = 4;
p_ptr->movement = 4;
}
diff --git a/src/birth.hpp b/src/birth.hpp
index af361499..7c171610 100644
--- a/src/birth.hpp
+++ b/src/birth.hpp
@@ -7,3 +7,5 @@ extern void save_savefile_names(void);
extern bool_ begin_screen(void);
extern void player_birth(void);
extern bool_ no_begin_screen;
+
+void roll_player_hp();
diff --git a/src/game.hpp b/src/game.hpp
index 03db8a45..b4894fd6 100644
--- a/src/game.hpp
+++ b/src/game.hpp
@@ -2,6 +2,8 @@
#include "game_fwd.hpp"
#include "grid.hpp"
+#include "h-basic.h"
+#include "player_defs.hpp"
#include "wilderness_map.hpp"
/**
@@ -9,11 +11,18 @@
*/
struct Game {
- /*
+ /**
* Wilderness map
*/
grid<wilderness_map> wilderness;
+ /**
+ * Player's un-adjusted HP at every level.
+ * Stored to avoid shenanigans with draininging levels
+ * and restoring them back, &c.
+ */
+ std::array<s16b, PY_MAX_LEVEL> player_hp { };
+
};
/**
diff --git a/src/loadsave.cc b/src/loadsave.cc
index 22708203..bbcc8784 100644
--- a/src/loadsave.cc
+++ b/src/loadsave.cc
@@ -2409,6 +2409,8 @@ static bool do_floor_inscriptions(ls_flag_t flag)
static bool do_player_hd(ls_flag_t flag)
{
+ auto &player_hp = game->player_hp;
+
u16b max_level = PY_MAX_LEVEL;
do_u16b(&max_level, flag);
diff --git a/src/variable.cc b/src/variable.cc
index 553c1dd2..941bc9a0 100644
--- a/src/variable.cc
+++ b/src/variable.cc
@@ -438,14 +438,6 @@ player_spec *spp_ptr;
/*
- * Calculated base hp values for player at each level,
- * store them so that drain life + restore life does not
- * affect hit points. Also prevents shameless use of backup
- * savefiles for hitpoint acquirement.
- */
-s16b player_hp[PY_MAX_LEVEL];
-
-/*
* The vault generation arrays
*/
vault_type *v_info;
diff --git a/src/variable.hpp b/src/variable.hpp
index 1a789747..20dcbaea 100644
--- a/src/variable.hpp
+++ b/src/variable.hpp
@@ -169,7 +169,6 @@ extern player_race *rp_ptr;
extern player_race_mod *rmp_ptr;
extern player_class *cp_ptr;
extern player_spec *spp_ptr;
-extern s16b player_hp[PY_MAX_LEVEL];
extern char player_name[32];
extern char player_base[32];
extern ability_type *ab_info;
diff --git a/src/wizard2.cc b/src/wizard2.cc
index 359d5c5a..dd0d50e8 100644
--- a/src/wizard2.cc
+++ b/src/wizard2.cc
@@ -9,6 +9,7 @@
#include "wizard2.hpp"
#include "artifact_type.hpp"
+#include "birth.hpp"
#include "cave.hpp"
#include "cave_type.hpp"
#include "cmd4.hpp"
@@ -116,32 +117,14 @@ static void teleport_player_town(int town)
*/
void do_cmd_rerate(void)
{
- int min_value, max_value, i, percent;
+ auto &player_hp = game->player_hp;
- min_value = (PY_MAX_LEVEL * 3 * (p_ptr->hitdie - 1)) / 8;
- min_value += PY_MAX_LEVEL;
+ // Force HP re-roll
+ roll_player_hp();
- max_value = (PY_MAX_LEVEL * 5 * (p_ptr->hitdie - 1)) / 8;
- max_value += PY_MAX_LEVEL;
-
- player_hp[0] = p_ptr->hitdie;
-
- /* Rerate */
- while (1)
- {
- /* Collect values */
- for (i = 1; i < PY_MAX_LEVEL; i++)
- {
- player_hp[i] = randint(p_ptr->hitdie);
- player_hp[i] += player_hp[i - 1];
- }
-
- /* Legal values */
- if ((player_hp[PY_MAX_LEVEL - 1] >= min_value) &&
- (player_hp[PY_MAX_LEVEL - 1] <= max_value)) break;
- }
-
- percent = (int)(((long)player_hp[PY_MAX_LEVEL - 1] * 200L) /
+ // Calculate life rating
+ int percent = static_cast<int>(
+ (static_cast<long>(player_hp[PY_MAX_LEVEL - 1]) * 200L) /
(p_ptr->hitdie + ((PY_MAX_LEVEL - 1) * p_ptr->hitdie)));
/* Update and redraw hitpoints */
diff --git a/src/xtra1.cc b/src/xtra1.cc
index c8fdb2e0..b4f2adf6 100644
--- a/src/xtra1.cc
+++ b/src/xtra1.cc
@@ -1841,15 +1841,13 @@ static void calc_mana(void)
*/
void calc_hitpoints(void)
{
- int bonus, mhp;
+ auto const &player_hp = game->player_hp;
/* Un-inflate "half-hitpoint bonus per level" value */
- bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128);
+ int const bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128);
/* Calculate hitpoints */
- assert(p_ptr->lev - 1 >= 0);
- assert(p_ptr->lev - 1 < PY_MAX_LEVEL);
- mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2);
+ int mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2);
/* Always have at least one hitpoint per level */
if (mhp < p_ptr->lev + 1) mhp = p_ptr->lev + 1;