From b85a1f777946af3ba763942ee78a7a4bce2afdb0 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 17 Sep 2016 09:58:15 +0200 Subject: Move player_hp[] into Game --- src/birth.cc | 80 +++++++++++++++++++++++++++++++++----------------------- src/birth.hpp | 2 ++ src/game.hpp | 11 +++++++- src/loadsave.cc | 2 ++ src/variable.cc | 8 ------ src/variable.hpp | 1 - src/wizard2.cc | 31 +++++----------------- src/xtra1.cc | 8 +++--- 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 #include /* @@ -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; + /** + * Player's un-adjusted HP at every level. + * Stored to avoid shenanigans with draininging levels + * and restoring them back, &c. + */ + std::array 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 @@ -437,14 +437,6 @@ player_class *cp_ptr; 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 */ 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( + (static_cast(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; -- cgit v1.2.3