1 #include "system/angband.h"
2 #include "core/hp-mp-processor.h"
3 #include "realm/realm-song.h"
4 #include "player/player-damage.h"
5 #include "object/object-flavor.h"
6 #include "object/object-ego.h"
7 #include "world/world.h"
8 #include "player/player-effects.h"
9 #include "floor/pattern-walk.h"
10 #include "core/hp-mp-regenerator.h"
11 #include "cmd/cmd-pet.h"
12 #include "player/player-races-table.h"
15 * @brief 10ゲームターンが進行するごとにプレイヤーのHPとMPの増減処理を行う。
16 * / Handle timed damage and regeneration every 10 game turns
19 void process_player_hp_mp(player_type* creature_ptr)
21 feature_type* f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].feat];
22 bool cave_no_regen = FALSE;
23 int upkeep_factor = 0;
24 int regen_amount = PY_REGEN_NORMAL;
25 if (creature_ptr->poisoned && !IS_INVULN(creature_ptr)) {
26 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, _("毒", "poison"), -1);
29 if (creature_ptr->cut && !IS_INVULN(creature_ptr)) {
31 if (creature_ptr->cut > 1000) {
33 } else if (creature_ptr->cut > 200) {
35 } else if (creature_ptr->cut > 100) {
37 } else if (creature_ptr->cut > 50) {
39 } else if (creature_ptr->cut > 25) {
41 } else if (creature_ptr->cut > 10) {
47 take_hit(creature_ptr, DAMAGE_NOESCAPE, dam, _("致命傷", "a fatal wound"), -1);
50 if (PRACE_IS_(creature_ptr, RACE_VAMPIRE) || (creature_ptr->mimic_form == MIMIC_VAMPIRE)) {
51 if (!creature_ptr->current_floor_ptr->dun_level && !creature_ptr->resist_lite && !IS_INVULN(creature_ptr) && is_daytime()) {
52 if ((creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) {
53 msg_print(_("日光があなたのアンデッドの肉体を焼き焦がした!", "The sun's rays scorch your undead flesh!"));
54 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, _("日光", "sunlight"), -1);
59 if (creature_ptr->inventory_list[INVEN_LITE].tval && (creature_ptr->inventory_list[INVEN_LITE].name2 != EGO_LITE_DARKNESS) && !creature_ptr->resist_lite) {
60 object_type* o_ptr = &creature_ptr->inventory_list[INVEN_LITE];
61 GAME_TEXT o_name[MAX_NLEN];
62 char ouch[MAX_NLEN + 40];
63 object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
64 msg_format(_("%sがあなたのアンデッドの肉体を焼き焦がした!", "The %s scorches your undead flesh!"), o_name);
67 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
68 sprintf(ouch, _("%sを装備したダメージ", "wielding %s"), o_name);
70 if (!IS_INVULN(creature_ptr))
71 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, ouch, -1);
75 if (have_flag(f_ptr->flags, FF_LAVA) && !IS_INVULN(creature_ptr) && !creature_ptr->immune_fire) {
78 if (have_flag(f_ptr->flags, FF_DEEP)) {
79 damage = 6000 + randint0(4000);
80 } else if (!creature_ptr->levitation) {
81 damage = 3000 + randint0(2000);
85 if (PRACE_IS_(creature_ptr, RACE_ENT))
87 if (creature_ptr->resist_fire)
89 if (is_oppose_fire(creature_ptr))
91 if (creature_ptr->levitation)
94 damage = damage / 100 + (randint0(100) < (damage % 100));
96 if (creature_ptr->levitation) {
97 msg_print(_("熱で火傷した!", "The heat burns you!"));
98 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name), -1);
100 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
101 msg_format(_("%sで火傷した!", "The %s burns you!"), name);
102 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
105 cave_no_regen = TRUE;
109 if (have_flag(f_ptr->flags, FF_COLD_PUDDLE) && !IS_INVULN(creature_ptr) && !creature_ptr->immune_cold) {
112 if (have_flag(f_ptr->flags, FF_DEEP)) {
113 damage = 6000 + randint0(4000);
114 } else if (!creature_ptr->levitation) {
115 damage = 3000 + randint0(2000);
119 if (creature_ptr->resist_cold)
121 if (is_oppose_cold(creature_ptr))
123 if (creature_ptr->levitation)
126 damage = damage / 100 + (randint0(100) < (damage % 100));
128 if (creature_ptr->levitation) {
129 msg_print(_("冷気に覆われた!", "The cold engulfs you!"));
130 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name), -1);
132 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
133 msg_format(_("%sに凍えた!", "The %s frostbites you!"), name);
134 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
137 cave_no_regen = TRUE;
141 if (have_flag(f_ptr->flags, FF_ELEC_PUDDLE) && !IS_INVULN(creature_ptr) && !creature_ptr->immune_elec) {
144 if (have_flag(f_ptr->flags, FF_DEEP)) {
145 damage = 6000 + randint0(4000);
146 } else if (!creature_ptr->levitation) {
147 damage = 3000 + randint0(2000);
151 if (creature_ptr->resist_elec)
153 if (is_oppose_elec(creature_ptr))
155 if (creature_ptr->levitation)
158 damage = damage / 100 + (randint0(100) < (damage % 100));
160 if (creature_ptr->levitation) {
161 msg_print(_("電撃を受けた!", "The electricity shocks you!"));
162 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name), -1);
164 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
165 msg_format(_("%sに感電した!", "The %s shocks you!"), name);
166 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
169 cave_no_regen = TRUE;
173 if (have_flag(f_ptr->flags, FF_ACID_PUDDLE) && !IS_INVULN(creature_ptr) && !creature_ptr->immune_acid) {
176 if (have_flag(f_ptr->flags, FF_DEEP)) {
177 damage = 6000 + randint0(4000);
178 } else if (!creature_ptr->levitation) {
179 damage = 3000 + randint0(2000);
183 if (creature_ptr->resist_acid)
185 if (is_oppose_acid(creature_ptr))
187 if (creature_ptr->levitation)
190 damage = damage / 100 + (randint0(100) < (damage % 100));
192 if (creature_ptr->levitation) {
193 msg_print(_("酸が飛び散った!", "The acid melts you!"));
194 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name), -1);
196 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
197 msg_format(_("%sに溶かされた!", "The %s melts you!"), name);
198 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
201 cave_no_regen = TRUE;
205 if (have_flag(f_ptr->flags, FF_POISON_PUDDLE) && !IS_INVULN(creature_ptr)) {
208 if (have_flag(f_ptr->flags, FF_DEEP)) {
209 damage = 6000 + randint0(4000);
210 } else if (!creature_ptr->levitation) {
211 damage = 3000 + randint0(2000);
215 if (creature_ptr->resist_pois)
217 if (is_oppose_pois(creature_ptr))
219 if (creature_ptr->levitation)
222 damage = damage / 100 + (randint0(100) < (damage % 100));
224 if (creature_ptr->levitation) {
225 msg_print(_("毒気を吸い込んだ!", "The gas poisons you!"));
226 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name), -1);
227 if (creature_ptr->resist_pois)
228 (void)set_poisoned(creature_ptr, creature_ptr->poisoned + 1);
230 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
231 msg_format(_("%sに毒された!", "The %s poisons you!"), name);
232 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
233 if (creature_ptr->resist_pois)
234 (void)set_poisoned(creature_ptr, creature_ptr->poisoned + 3);
237 cave_no_regen = TRUE;
241 if (have_flag(f_ptr->flags, FF_WATER) && have_flag(f_ptr->flags, FF_DEEP) && !creature_ptr->levitation && !creature_ptr->can_swim && !creature_ptr->resist_water) {
242 if (creature_ptr->total_weight > weight_limit(creature_ptr)) {
243 msg_print(_("溺れている!", "You are drowning!"));
244 take_hit(creature_ptr, DAMAGE_NOESCAPE, randint1(creature_ptr->lev), _("溺れ", "drowning"), -1);
245 cave_no_regen = TRUE;
249 if (creature_ptr->riding) {
251 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags2 & RF2_AURA_FIRE) && !creature_ptr->immune_fire) {
252 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
253 if (PRACE_IS_(creature_ptr, RACE_ENT))
254 damage += damage / 3;
255 if (creature_ptr->resist_fire)
257 if (is_oppose_fire(creature_ptr))
259 msg_print(_("熱い!", "It's hot!"));
260 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("炎のオーラ", "Fire aura"), -1);
262 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags2 & RF2_AURA_ELEC) && !creature_ptr->immune_elec) {
263 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
264 if (PRACE_IS_(creature_ptr, RACE_ANDROID))
265 damage += damage / 3;
266 if (creature_ptr->resist_elec)
268 if (is_oppose_elec(creature_ptr))
270 msg_print(_("痛い!", "It hurts!"));
271 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("電気のオーラ", "Elec aura"), -1);
273 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags3 & RF3_AURA_COLD) && !creature_ptr->immune_cold) {
274 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
275 if (creature_ptr->resist_cold)
277 if (is_oppose_cold(creature_ptr))
279 msg_print(_("冷たい!", "It's cold!"));
280 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("冷気のオーラ", "Cold aura"), -1);
284 /* Spectres -- take damage when moving through walls */
286 * Added: ANYBODY takes damage if inside through walls
287 * without wraith form -- NOTE: Spectres will never be
288 * reduced below 0 hp by being inside a stone wall; others
291 if (!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) {
292 if (!IS_INVULN(creature_ptr) && !creature_ptr->wraith_form && !creature_ptr->kabenuke && ((creature_ptr->chp > (creature_ptr->lev / 5)) || !creature_ptr->pass_wall)) {
294 cave_no_regen = TRUE;
296 if (creature_ptr->pass_wall) {
297 msg_print(_("体の分子が分解した気がする!", "Your molecules feel disrupted!"));
298 dam_desc = _("密度", "density");
300 msg_print(_("崩れた岩に押し潰された!", "You are being crushed!"));
301 dam_desc = _("硬い岩", "solid rock");
304 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1 + (creature_ptr->lev / 5), dam_desc, -1);
308 if (creature_ptr->food < PY_FOOD_WEAK) {
309 if (creature_ptr->food < PY_FOOD_STARVE) {
311 } else if (creature_ptr->food < PY_FOOD_FAINT) {
312 regen_amount = PY_REGEN_FAINT;
314 regen_amount = PY_REGEN_WEAK;
318 if (pattern_effect(creature_ptr)) {
319 cave_no_regen = TRUE;
321 if (creature_ptr->regenerate) {
322 regen_amount = regen_amount * 2;
324 if (creature_ptr->special_defense & (KAMAE_MASK | KATA_MASK)) {
327 if (creature_ptr->cursed & TRC_SLOW_REGEN) {
332 if ((creature_ptr->action == ACTION_SEARCH) || (creature_ptr->action == ACTION_REST)) {
333 regen_amount = regen_amount * 2;
336 upkeep_factor = calculate_upkeep(creature_ptr);
337 if ((creature_ptr->action == ACTION_LEARN) || (creature_ptr->action == ACTION_HAYAGAKE) || (creature_ptr->special_defense & KATA_KOUKIJIN)) {
338 upkeep_factor += 100;
341 regenmana(creature_ptr, upkeep_factor, regen_amount);
342 if (creature_ptr->pclass == CLASS_MAGIC_EATER) {
343 regenmagic(creature_ptr, regen_amount);
346 if ((creature_ptr->csp == 0) && (creature_ptr->csp_frac == 0)) {
347 while (upkeep_factor > 100) {
348 msg_print(_("こんなに多くのペットを制御できない!", "Too many pets to control at once!"));
350 do_cmd_pet_dismiss(creature_ptr);
352 upkeep_factor = calculate_upkeep(creature_ptr);
354 msg_format(_("維持MPは %d%%", "Upkeep: %d%% mana."), upkeep_factor);
359 if (creature_ptr->poisoned)
361 if (creature_ptr->cut)
366 regen_amount = (regen_amount * creature_ptr->mutant_regenerate_mod) / 100;
367 if ((creature_ptr->chp < creature_ptr->mhp) && !cave_no_regen) {
368 regenhp(creature_ptr, regen_amount);