1 #include "system/angband.h"
2 #include "core/hp-mp-regenerator.h"
3 #include "cmd-item/cmd-magiceat.h"
4 #include "floor/floor.h"
5 #include "monster-race/race-flags2.h"
6 #include "monster/monster-status.h"
8 /*!<広域マップ移動時の自然回復処理カウンタ(広域マップ1マス毎に20回処理を基本とする)*/
12 * @brief プレイヤーのHP自然回復処理 / Regenerate hit points -RAK-
16 void regenhp(player_type* creature_ptr, int percent)
18 if (creature_ptr->special_defense & KATA_KOUKIJIN)
20 if (creature_ptr->action == ACTION_HAYAGAKE)
23 HIT_POINT old_chp = creature_ptr->chp;
26 * Extract the new hitpoints
28 * 'percent' is the Regen factor in unit (1/2^16)
30 HIT_POINT new_chp = 0;
31 u32b new_chp_frac = (creature_ptr->mhp * percent + PY_REGEN_HPBASE);
32 s64b_LSHIFT(new_chp, new_chp_frac, 16);
33 s64b_add(&(creature_ptr->chp), &(creature_ptr->chp_frac), new_chp, new_chp_frac);
34 if (0 < s64b_cmp(creature_ptr->chp, creature_ptr->chp_frac, creature_ptr->mhp, 0)) {
35 creature_ptr->chp = creature_ptr->mhp;
36 creature_ptr->chp_frac = 0;
39 if (old_chp != creature_ptr->chp) {
40 creature_ptr->redraw |= (PR_HP);
41 creature_ptr->window |= (PW_PLAYER);
47 * @brief プレイヤーのMP自然回復処理(regen_magic()のサブセット) / Regenerate mana points
48 * @param upkeep_factor ペット維持によるMPコスト量
49 * @param regen_amount 回復量
52 void regenmana(player_type* creature_ptr, MANA_POINT upkeep_factor, MANA_POINT regen_amount)
54 MANA_POINT old_csp = creature_ptr->csp;
55 s32b regen_rate = regen_amount * 100 - upkeep_factor * PY_REGEN_NORMAL;
58 * Excess mana will decay 32 times faster than normal
61 if (creature_ptr->csp > creature_ptr->msp) {
63 u32b decay_frac = (creature_ptr->msp * 32 * PY_REGEN_NORMAL + PY_REGEN_MNBASE);
64 s64b_LSHIFT(decay, decay_frac, 16);
65 s64b_sub(&(creature_ptr->csp), &(creature_ptr->csp_frac), decay, decay_frac);
66 if (creature_ptr->csp < creature_ptr->msp) {
67 creature_ptr->csp = creature_ptr->msp;
68 creature_ptr->csp_frac = 0;
72 /* Regenerating mana (unless the player has excess mana) */
73 else if (regen_rate > 0) {
74 MANA_POINT new_mana = 0;
75 u32b new_mana_frac = (creature_ptr->msp * regen_rate / 100 + PY_REGEN_MNBASE);
76 s64b_LSHIFT(new_mana, new_mana_frac, 16);
77 s64b_add(&(creature_ptr->csp), &(creature_ptr->csp_frac), new_mana, new_mana_frac);
78 if (creature_ptr->csp >= creature_ptr->msp) {
79 creature_ptr->csp = creature_ptr->msp;
80 creature_ptr->csp_frac = 0;
84 /* Reduce mana (even when the player has excess mana) */
87 u32b reduce_mana_frac = (creature_ptr->msp * (-1) * regen_rate / 100 + PY_REGEN_MNBASE);
88 s64b_LSHIFT(reduce_mana, reduce_mana_frac, 16);
89 s64b_sub(&(creature_ptr->csp), &(creature_ptr->csp_frac), reduce_mana, reduce_mana_frac);
90 if (creature_ptr->csp < 0) {
91 creature_ptr->csp = 0;
92 creature_ptr->csp_frac = 0;
96 if (old_csp != creature_ptr->csp) {
97 creature_ptr->redraw |= (PR_MANA);
98 creature_ptr->window |= (PW_PLAYER);
99 creature_ptr->window |= (PW_SPELL);
105 * @brief プレイヤーのMP自然回復処理 / Regenerate magic regen_amount: PY_REGEN_NORMAL * 2 (if resting) * 2 (if having regenarate)
106 * @param regen_amount 回復量
109 void regenmagic(player_type* creature_ptr, int regen_amount)
113 int mult = (dev + adj_mag_mana[creature_ptr->stat_ind[A_INT]]); /* x1 to x2 speed bonus for recharging */
115 for (int i = 0; i < EATER_EXT * 2; i++) {
116 if (!creature_ptr->magic_num2[i])
118 if (creature_ptr->magic_num1[i] == ((long)creature_ptr->magic_num2[i] << 16))
121 /* Increase remaining charge number like float value */
122 new_mana = (regen_amount * mult * ((long)creature_ptr->magic_num2[i] + 13)) / (dev * 8);
123 creature_ptr->magic_num1[i] += new_mana;
125 /* Check maximum charge */
126 if (creature_ptr->magic_num1[i] > (creature_ptr->magic_num2[i] << 16)) {
127 creature_ptr->magic_num1[i] = ((long)creature_ptr->magic_num2[i] << 16);
133 for (int i = EATER_EXT * 2; i < EATER_EXT * 3; i++) {
134 if (!creature_ptr->magic_num1[i])
136 if (!creature_ptr->magic_num2[i])
139 /* Decrease remaining period for charging */
140 new_mana = (regen_amount * mult * ((long)creature_ptr->magic_num2[i] + 10) * EATER_ROD_CHARGE)
141 / (dev * 16 * PY_REGEN_NORMAL);
142 creature_ptr->magic_num1[i] -= new_mana;
144 /* Check minimum remaining period for charging */
145 if (creature_ptr->magic_num1[i] < 0)
146 creature_ptr->magic_num1[i] = 0;
152 * @brief 100ゲームターン毎のモンスターのHP自然回復処理 / Regenerate the monsters (once per 100 game turns)
153 * @param player_ptr プレーヤーへの参照ポインタ
155 * @note Should probably be done during monster turns.
157 void regenerate_monsters(player_type* player_ptr)
159 for (int i = 1; i < player_ptr->current_floor_ptr->m_max; i++) {
160 monster_type* m_ptr = &player_ptr->current_floor_ptr->m_list[i];
161 monster_race* r_ptr = &r_info[m_ptr->r_idx];
163 if (!monster_is_valid(m_ptr))
166 if (m_ptr->hp < m_ptr->maxhp) {
167 int frac = m_ptr->maxhp / 100;
172 if (r_ptr->flags2 & RF2_REGENERATE)
176 if (m_ptr->hp > m_ptr->maxhp)
177 m_ptr->hp = m_ptr->maxhp;
179 if (player_ptr->health_who == i)
180 player_ptr->redraw |= (PR_HEALTH);
181 if (player_ptr->riding == i)
182 player_ptr->redraw |= (PR_UHEALTH);
188 * @brief 30ゲームターン毎のボール中モンスターのHP自然回復処理 / Regenerate the captured monsters (once per 30 game turns)
189 * @param creature_ptr プレーヤーへの参照ポインタ
191 * @note Should probably be done during monster turns.
193 void regenerate_captured_monsters(player_type* creature_ptr)
196 for (int i = 0; i < INVEN_TOTAL; i++) {
198 object_type* o_ptr = &creature_ptr->inventory_list[i];
201 if (o_ptr->tval != TV_CAPTURE)
207 r_ptr = &r_info[o_ptr->pval];
208 if (o_ptr->xtra4 < o_ptr->xtra5) {
209 int frac = o_ptr->xtra5 / 100;
214 if (r_ptr->flags2 & RF2_REGENERATE)
217 o_ptr->xtra4 += (XTRA16)frac;
218 if (o_ptr->xtra4 > o_ptr->xtra5)
219 o_ptr->xtra4 = o_ptr->xtra5;
224 creature_ptr->update |= (PU_COMBINE);
225 creature_ptr->window |= (PW_INVEN);
226 creature_ptr->window |= (PW_EQUIP);