1 #include "core/hp-mp-regenerator.h"
2 #include "cmd-item/cmd-magiceat.h"
3 #include "core/player-redraw-types.h"
4 #include "core/player-update-types.h"
5 #include "core/window-redrawer.h"
6 #include "inventory/inventory-slot-types.h"
7 #include "monster-race/monster-race.h"
8 #include "monster-race/race-flags2.h"
9 #include "monster/monster-status.h"
10 #include "player/attack-defense-types.h"
11 #include "player/special-defense-types.h"
12 #include "player/player-status-table.h"
13 #include "system/floor-type-definition.h"
14 #include "system/object-type-definition.h"
16 /*!<広域マップ移動時の自然回復処理カウンタ(広域マップ1マス毎に20回処理を基本とする)*/
20 * @brief プレイヤーのHP自然回復処理 / Regenerate hit points -RAK-
24 void regenhp(player_type *creature_ptr, int percent)
26 if (creature_ptr->special_defense & KATA_KOUKIJIN)
28 if (creature_ptr->action == ACTION_HAYAGAKE)
31 HIT_POINT old_chp = creature_ptr->chp;
34 * Extract the new hitpoints
36 * 'percent' is the Regen factor in unit (1/2^16)
38 HIT_POINT new_chp = 0;
39 u32b new_chp_frac = (creature_ptr->mhp * percent + PY_REGEN_HPBASE);
40 s64b_LSHIFT(new_chp, new_chp_frac, 16);
41 s64b_add(&(creature_ptr->chp), &(creature_ptr->chp_frac), new_chp, new_chp_frac);
42 if (0 < s64b_cmp(creature_ptr->chp, creature_ptr->chp_frac, creature_ptr->mhp, 0)) {
43 creature_ptr->chp = creature_ptr->mhp;
44 creature_ptr->chp_frac = 0;
47 if (old_chp != creature_ptr->chp) {
48 creature_ptr->redraw |= (PR_HP);
49 creature_ptr->window |= (PW_PLAYER);
55 * @brief プレイヤーのMP自然回復処理(regen_magic()のサブセット) / Regenerate mana points
56 * @param upkeep_factor ペット維持によるMPコスト量
57 * @param regen_amount 回復量
60 void regenmana(player_type *creature_ptr, MANA_POINT upkeep_factor, MANA_POINT regen_amount)
62 MANA_POINT old_csp = creature_ptr->csp;
63 s32b regen_rate = regen_amount * 100 - upkeep_factor * PY_REGEN_NORMAL;
66 * Excess mana will decay 32 times faster than normal
69 if (creature_ptr->csp > creature_ptr->msp) {
71 u32b decay_frac = (creature_ptr->msp * 32 * PY_REGEN_NORMAL + PY_REGEN_MNBASE);
72 s64b_LSHIFT(decay, decay_frac, 16);
73 s64b_sub(&(creature_ptr->csp), &(creature_ptr->csp_frac), decay, decay_frac);
74 if (creature_ptr->csp < creature_ptr->msp) {
75 creature_ptr->csp = creature_ptr->msp;
76 creature_ptr->csp_frac = 0;
80 /* Regenerating mana (unless the player has excess mana) */
81 else if (regen_rate > 0) {
82 MANA_POINT new_mana = 0;
83 u32b new_mana_frac = (creature_ptr->msp * regen_rate / 100 + PY_REGEN_MNBASE);
84 s64b_LSHIFT(new_mana, new_mana_frac, 16);
85 s64b_add(&(creature_ptr->csp), &(creature_ptr->csp_frac), new_mana, new_mana_frac);
86 if (creature_ptr->csp >= creature_ptr->msp) {
87 creature_ptr->csp = creature_ptr->msp;
88 creature_ptr->csp_frac = 0;
92 /* Reduce mana (even when the player has excess mana) */
95 u32b reduce_mana_frac = (creature_ptr->msp * (-1) * regen_rate / 100 + PY_REGEN_MNBASE);
96 s64b_LSHIFT(reduce_mana, reduce_mana_frac, 16);
97 s64b_sub(&(creature_ptr->csp), &(creature_ptr->csp_frac), reduce_mana, reduce_mana_frac);
98 if (creature_ptr->csp < 0) {
99 creature_ptr->csp = 0;
100 creature_ptr->csp_frac = 0;
104 if (old_csp != creature_ptr->csp) {
105 creature_ptr->redraw |= (PR_MANA);
106 creature_ptr->window |= (PW_PLAYER);
107 creature_ptr->window |= (PW_SPELL);
113 * @brief プレイヤーのMP自然回復処理 / Regenerate magic regen_amount: PY_REGEN_NORMAL * 2 (if resting) * 2 (if having regenarate)
114 * @param regen_amount 回復量
117 void regenmagic(player_type *creature_ptr, int regen_amount)
121 int mult = (dev + adj_mag_mana[creature_ptr->stat_ind[A_INT]]); /* x1 to x2 speed bonus for recharging */
123 for (int i = 0; i < EATER_EXT * 2; i++) {
124 if (!creature_ptr->magic_num2[i])
126 if (creature_ptr->magic_num1[i] == ((long)creature_ptr->magic_num2[i] << 16))
129 /* Increase remaining charge number like float value */
130 new_mana = (regen_amount * mult * ((long)creature_ptr->magic_num2[i] + 13)) / (dev * 8);
131 creature_ptr->magic_num1[i] += new_mana;
133 /* Check maximum charge */
134 if (creature_ptr->magic_num1[i] > (creature_ptr->magic_num2[i] << 16)) {
135 creature_ptr->magic_num1[i] = ((long)creature_ptr->magic_num2[i] << 16);
141 for (int i = EATER_EXT * 2; i < EATER_EXT * 3; i++) {
142 if (!creature_ptr->magic_num1[i])
144 if (!creature_ptr->magic_num2[i])
147 /* Decrease remaining period for charging */
148 new_mana = (regen_amount * mult * ((long)creature_ptr->magic_num2[i] + 10) * EATER_ROD_CHARGE) / (dev * 16 * PY_REGEN_NORMAL);
149 creature_ptr->magic_num1[i] -= new_mana;
151 /* Check minimum remaining period for charging */
152 if (creature_ptr->magic_num1[i] < 0)
153 creature_ptr->magic_num1[i] = 0;
159 * @brief 100ゲームターン毎のモンスターのHP自然回復処理 / Regenerate the monsters (once per 100 game turns)
160 * @param player_ptr プレーヤーへの参照ポインタ
162 * @note Should probably be done during monster turns.
164 void regenerate_monsters(player_type *player_ptr)
166 for (int i = 1; i < player_ptr->current_floor_ptr->m_max; i++) {
167 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[i];
168 monster_race *r_ptr = &r_info[m_ptr->r_idx];
170 if (!monster_is_valid(m_ptr))
173 if (m_ptr->hp < m_ptr->maxhp) {
174 int frac = m_ptr->maxhp / 100;
179 if (r_ptr->flags2 & RF2_REGENERATE)
183 if (m_ptr->hp > m_ptr->maxhp)
184 m_ptr->hp = m_ptr->maxhp;
186 if (player_ptr->health_who == i)
187 player_ptr->redraw |= (PR_HEALTH);
188 if (player_ptr->riding == i)
189 player_ptr->redraw |= (PR_UHEALTH);
195 * @brief 30ゲームターン毎のボール中モンスターのHP自然回復処理 / Regenerate the captured monsters (once per 30 game turns)
196 * @param creature_ptr プレーヤーへの参照ポインタ
198 * @note Should probably be done during monster turns.
200 void regenerate_captured_monsters(player_type *creature_ptr)
203 for (int i = 0; i < INVEN_TOTAL; i++) {
205 object_type *o_ptr = &creature_ptr->inventory_list[i];
208 if (o_ptr->tval != TV_CAPTURE)
214 r_ptr = &r_info[o_ptr->pval];
215 if (o_ptr->xtra4 < o_ptr->xtra5) {
216 int frac = o_ptr->xtra5 / 100;
221 if (r_ptr->flags2 & RF2_REGENERATE)
224 o_ptr->xtra4 += (XTRA16)frac;
225 if (o_ptr->xtra4 > o_ptr->xtra5)
226 o_ptr->xtra4 = o_ptr->xtra5;
231 creature_ptr->update |= (PU_COMBINE);
232 creature_ptr->window |= (PW_INVEN);
233 creature_ptr->window |= (PW_EQUIP);