player_ptr->skill_exp[i] = class_skills_info[pclass].s_start[i];
}
- player_ptr->hitdie = cp_ptr->c_mhp + ap_ptr->a_mhp;
- player_ptr->hitdie += is_sorcerer ? rp_ptr->r_mhp / 2 : rp_ptr->r_mhp;
+ const auto r_mhp = is_sorcerer ? rp_ptr->r_mhp / 2 : rp_ptr->r_mhp;
+ player_ptr->hit_dice = Dice(1, r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
if (roll_hitdie) {
roll_hitdice(player_ptr, SPOP_NO_UPDATE);
}
{
PlayerClass pc(player_ptr);
if (h_older_than(0, 2, 2) && pc.equals(PlayerClassType::BEASTMASTER) && !player_ptr->is_dead) {
- player_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
+ player_ptr->hit_dice = Dice(1, rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
roll_hitdice(player_ptr, SPOP_NONE);
}
if (h_older_than(0, 3, 2) && pc.equals(PlayerClassType::ARCHER) && !player_ptr->is_dead) {
- player_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
+ player_ptr->hit_dice = Dice(1, rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
roll_hitdice(player_ptr, SPOP_NONE);
}
if (h_older_than(0, 2, 6) && pc.equals(PlayerClassType::SORCERER) && !player_ptr->is_dead) {
- player_ptr->hitdie = rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
+ player_ptr->hit_dice = Dice(1, rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp);
roll_hitdice(player_ptr, SPOP_NONE);
}
if (h_older_than(0, 4, 7) && pc.equals(PlayerClassType::BLUE_MAGE) && !player_ptr->is_dead) {
- player_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
+ player_ptr->hit_dice = Dice(1, rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
roll_hitdice(player_ptr, SPOP_NONE);
}
}
set_zangband_realm(player_ptr);
}
- player_ptr->hitdie = rd_byte();
+ player_ptr->hit_dice = Dice(1, rd_byte());
player_ptr->expfact = rd_u16b();
player_ptr->age = rd_s16b();
int bonus = ((int)(adj_con_mhp[player_ptr->stat_index[A_CON]]) - 128) * player_ptr->lev / 4;
int mhp = player_ptr->player_hp[player_ptr->lev - 1];
- byte tmp_hitdie;
PlayerClass pc(player_ptr);
auto is_sorcerer = pc.equals(PlayerClassType::SORCERER);
if (player_ptr->mimic_form != MimicKindType::NONE) {
auto r_mhp = mimic_info.at(player_ptr->mimic_form).r_mhp;
- if (is_sorcerer) {
- tmp_hitdie = r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
- } else {
- tmp_hitdie = r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
- }
-
- mhp = mhp * tmp_hitdie / player_ptr->hitdie;
+ const auto mimic_hit_dice = Dice(1, (is_sorcerer ? r_mhp / 2 : r_mhp) + cp_ptr->c_mhp + ap_ptr->a_mhp);
+ mhp = mhp * mimic_hit_dice.maxroll() / player_ptr->hit_dice.maxroll();
}
if (is_sorcerer) {
wr_relams(player_ptr);
wr_byte(0);
- wr_byte((byte)player_ptr->hitdie);
+ wr_byte((byte)player_ptr->hit_dice.sides);
wr_u16b(player_ptr->expfact);
wr_s16b(player_ptr->age);
*/
void roll_hitdice(PlayerType *player_ptr, spell_operation options)
{
- int min_value = player_ptr->hitdie + ((PY_MAX_LEVEL + 2) * (player_ptr->hitdie + 1)) * 3 / 8;
- int max_value = player_ptr->hitdie + ((PY_MAX_LEVEL + 2) * (player_ptr->hitdie + 1)) * 5 / 8;
+ constexpr auto roll_num = 3 + PY_MAX_LEVEL - 1;
+ const auto expected_hp = player_ptr->hit_dice.maxroll() + player_ptr->hit_dice.floored_expected_value_multiplied_by(roll_num);
+ const auto min_value = expected_hp * 3 / 4;
+ const auto max_value = expected_hp * 5 / 4;
/* Rerate */
while (true) {
/* Pre-calculate level 1 hitdice */
- player_ptr->player_hp[0] = (int)player_ptr->hitdie;
+ player_ptr->player_hp[0] = player_ptr->hit_dice.maxroll();
for (int i = 1; i < 4; i++) {
- player_ptr->player_hp[0] += randint1(player_ptr->hitdie);
+ player_ptr->player_hp[0] += player_ptr->hit_dice.roll();
}
/* Roll the hitpoint values */
for (int i = 1; i < PY_MAX_LEVEL; i++) {
- player_ptr->player_hp[i] = player_ptr->player_hp[i - 1] + randint1(player_ptr->hitdie);
+ player_ptr->player_hp[i] = player_ptr->player_hp[i - 1] + player_ptr->hit_dice.roll();
}
/* Require "valid" hitpoints at highest level */
get_height_weight(player_ptr);
- if (pc.equals(PlayerClassType::SORCERER)) {
- player_ptr->hitdie = rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
- } else {
- player_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
- }
+ const auto r_mhp = pc.equals(PlayerClassType::SORCERER) ? rp_ptr->r_mhp / 2 : rp_ptr->r_mhp;
+ player_ptr->hit_dice = Dice(1, r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
roll_hitdice(player_ptr, SPOP_NONE);
check_experience(player_ptr);
// ダイスによる上昇回数は52回(初期3回+LV50までの49回)なので
// 期待値計算のため2で割っても端数は出ない
constexpr auto roll_num = 3 + PY_MAX_LEVEL - 1;
- const auto expected_hp = this->hitdie + roll_num * (this->hitdie + 1) / 2;
+ const auto expected_hp = this->hit_dice.maxroll() + this->hit_dice.floored_expected_value_multiplied_by(roll_num);
return actual_hp * 100 / expected_hp;
}
int16_t realm2{}; /* Second magic realm */
int16_t element{}; //!< 元素使い領域番号 / Elementalist system index
- DICE_SID hitdie{}; /* Hit dice (sides) */
+ Dice hit_dice{}; /* Hit dice */
uint16_t expfact{}; /* Experience factor
* Note: was byte, causing overflow for Amberite
* characters (such as Amberite Paladins)