1 #include "core/hp-mp-processor.h"
2 #include "cmd-action/cmd-pet.h"
3 #include "core/hp-mp-regenerator.h"
4 #include "floor/floor.h"
5 #include "floor/pattern-walk.h"
6 #include "grid/feature.h"
8 #include "monster-race/monster-race.h"
9 #include "monster-race/race-flags2.h"
10 #include "monster-race/race-flags3.h"
11 #include "object-enchant/object-ego.h"
12 #include "object-enchant/trc-types.h"
13 #include "object/object-flavor.h"
14 #include "player/player-damage.h"
15 #include "player/player-effects.h"
16 #include "player/player-race-types.h"
17 #include "player/player-race.h"
18 #include "util/bit-flags-calculator.h"
19 #include "view/display-messages.h"
20 #include "world/world.h"
23 * @brief 10ゲームターンが進行するごとにプレイヤーのHPとMPの増減処理を行う。
24 * / Handle timed damage and regeneration every 10 game turns
27 void process_player_hp_mp(player_type *creature_ptr)
29 feature_type *f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].feat];
30 bool cave_no_regen = FALSE;
31 int upkeep_factor = 0;
32 int regen_amount = PY_REGEN_NORMAL;
33 if (creature_ptr->poisoned && !is_invuln(creature_ptr)) {
34 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, _("毒", "poison"), -1);
37 if (creature_ptr->cut && !is_invuln(creature_ptr)) {
39 if (creature_ptr->cut > 1000) {
41 } else if (creature_ptr->cut > 200) {
43 } else if (creature_ptr->cut > 100) {
45 } else if (creature_ptr->cut > 50) {
47 } else if (creature_ptr->cut > 25) {
49 } else if (creature_ptr->cut > 10) {
55 take_hit(creature_ptr, DAMAGE_NOESCAPE, dam, _("致命傷", "a fatal wound"), -1);
58 if (is_specific_player_race(creature_ptr, RACE_VAMPIRE) || (creature_ptr->mimic_form == MIMIC_VAMPIRE)) {
59 if (!creature_ptr->current_floor_ptr->dun_level && !creature_ptr->resist_lite && !is_invuln(creature_ptr) && is_daytime()) {
60 if ((creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) {
61 msg_print(_("日光があなたのアンデッドの肉体を焼き焦がした!", "The sun's rays scorch your undead flesh!"));
62 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, _("日光", "sunlight"), -1);
67 if (creature_ptr->inventory_list[INVEN_LITE].tval && (creature_ptr->inventory_list[INVEN_LITE].name2 != EGO_LITE_DARKNESS)
68 && !creature_ptr->resist_lite) {
69 object_type *o_ptr = &creature_ptr->inventory_list[INVEN_LITE];
70 GAME_TEXT o_name[MAX_NLEN];
71 char ouch[MAX_NLEN + 40];
72 object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
73 msg_format(_("%sがあなたのアンデッドの肉体を焼き焦がした!", "The %s scorches your undead flesh!"), o_name);
76 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
77 sprintf(ouch, _("%sを装備したダメージ", "wielding %s"), o_name);
79 if (!is_invuln(creature_ptr))
80 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1, ouch, -1);
84 if (have_flag(f_ptr->flags, FF_LAVA) && !is_invuln(creature_ptr) && !creature_ptr->immune_fire) {
87 if (have_flag(f_ptr->flags, FF_DEEP)) {
88 damage = 6000 + randint0(4000);
89 } else if (!creature_ptr->levitation) {
90 damage = 3000 + randint0(2000);
94 if (is_specific_player_race(creature_ptr, RACE_ENT))
96 if (creature_ptr->resist_fire)
98 if (is_oppose_fire(creature_ptr))
100 if (creature_ptr->levitation)
103 damage = damage / 100 + (randint0(100) < (damage % 100));
105 if (creature_ptr->levitation) {
106 msg_print(_("熱で火傷した!", "The heat burns you!"));
107 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage,
108 format(_("%sの上に浮遊したダメージ", "flying over %s"),
109 f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name),
112 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
113 msg_format(_("%sで火傷した!", "The %s burns you!"), name);
114 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
117 cave_no_regen = TRUE;
121 if (have_flag(f_ptr->flags, FF_COLD_PUDDLE) && !is_invuln(creature_ptr) && !creature_ptr->immune_cold) {
124 if (have_flag(f_ptr->flags, FF_DEEP)) {
125 damage = 6000 + randint0(4000);
126 } else if (!creature_ptr->levitation) {
127 damage = 3000 + randint0(2000);
131 if (creature_ptr->resist_cold)
133 if (is_oppose_cold(creature_ptr))
135 if (creature_ptr->levitation)
138 damage = damage / 100 + (randint0(100) < (damage % 100));
140 if (creature_ptr->levitation) {
141 msg_print(_("冷気に覆われた!", "The cold engulfs you!"));
142 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage,
143 format(_("%sの上に浮遊したダメージ", "flying over %s"),
144 f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name),
147 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
148 msg_format(_("%sに凍えた!", "The %s frostbites you!"), name);
149 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
152 cave_no_regen = TRUE;
156 if (have_flag(f_ptr->flags, FF_ELEC_PUDDLE) && !is_invuln(creature_ptr) && !creature_ptr->immune_elec) {
159 if (have_flag(f_ptr->flags, FF_DEEP)) {
160 damage = 6000 + randint0(4000);
161 } else if (!creature_ptr->levitation) {
162 damage = 3000 + randint0(2000);
166 if (creature_ptr->resist_elec)
168 if (is_oppose_elec(creature_ptr))
170 if (creature_ptr->levitation)
173 damage = damage / 100 + (randint0(100) < (damage % 100));
175 if (creature_ptr->levitation) {
176 msg_print(_("電撃を受けた!", "The electricity shocks you!"));
177 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage,
178 format(_("%sの上に浮遊したダメージ", "flying over %s"),
179 f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name),
182 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
183 msg_format(_("%sに感電した!", "The %s shocks you!"), name);
184 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
187 cave_no_regen = TRUE;
191 if (have_flag(f_ptr->flags, FF_ACID_PUDDLE) && !is_invuln(creature_ptr) && !creature_ptr->immune_acid) {
194 if (have_flag(f_ptr->flags, FF_DEEP)) {
195 damage = 6000 + randint0(4000);
196 } else if (!creature_ptr->levitation) {
197 damage = 3000 + randint0(2000);
201 if (creature_ptr->resist_acid)
203 if (is_oppose_acid(creature_ptr))
205 if (creature_ptr->levitation)
208 damage = damage / 100 + (randint0(100) < (damage % 100));
210 if (creature_ptr->levitation) {
211 msg_print(_("酸が飛び散った!", "The acid melts you!"));
212 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage,
213 format(_("%sの上に浮遊したダメージ", "flying over %s"),
214 f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name),
217 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
218 msg_format(_("%sに溶かされた!", "The %s melts you!"), name);
219 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
222 cave_no_regen = TRUE;
226 if (have_flag(f_ptr->flags, FF_POISON_PUDDLE) && !is_invuln(creature_ptr)) {
229 if (have_flag(f_ptr->flags, FF_DEEP)) {
230 damage = 6000 + randint0(4000);
231 } else if (!creature_ptr->levitation) {
232 damage = 3000 + randint0(2000);
236 if (creature_ptr->resist_pois)
238 if (is_oppose_pois(creature_ptr))
240 if (creature_ptr->levitation)
243 damage = damage / 100 + (randint0(100) < (damage % 100));
245 if (creature_ptr->levitation) {
246 msg_print(_("毒気を吸い込んだ!", "The gas poisons you!"));
247 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage,
248 format(_("%sの上に浮遊したダメージ", "flying over %s"),
249 f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name),
251 if (creature_ptr->resist_pois)
252 (void)set_poisoned(creature_ptr, creature_ptr->poisoned + 1);
254 concptr name = f_name + f_info[get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x])].name;
255 msg_format(_("%sに毒された!", "The %s poisons you!"), name);
256 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, name, -1);
257 if (creature_ptr->resist_pois)
258 (void)set_poisoned(creature_ptr, creature_ptr->poisoned + 3);
261 cave_no_regen = TRUE;
265 if (have_flag(f_ptr->flags, FF_WATER) && have_flag(f_ptr->flags, FF_DEEP) && !creature_ptr->levitation && !creature_ptr->can_swim
266 && !creature_ptr->resist_water) {
267 if (creature_ptr->total_weight > weight_limit(creature_ptr)) {
268 msg_print(_("溺れている!", "You are drowning!"));
269 take_hit(creature_ptr, DAMAGE_NOESCAPE, randint1(creature_ptr->lev), _("溺れ", "drowning"), -1);
270 cave_no_regen = TRUE;
274 if (creature_ptr->riding) {
276 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags2 & RF2_AURA_FIRE) && !creature_ptr->immune_fire) {
277 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
278 if (is_specific_player_race(creature_ptr, RACE_ENT))
279 damage += damage / 3;
280 if (creature_ptr->resist_fire)
282 if (is_oppose_fire(creature_ptr))
284 msg_print(_("熱い!", "It's hot!"));
285 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("炎のオーラ", "Fire aura"), -1);
287 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags2 & RF2_AURA_ELEC) && !creature_ptr->immune_elec) {
288 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
289 if (is_specific_player_race(creature_ptr, RACE_ANDROID))
290 damage += damage / 3;
291 if (creature_ptr->resist_elec)
293 if (is_oppose_elec(creature_ptr))
295 msg_print(_("痛い!", "It hurts!"));
296 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("電気のオーラ", "Elec aura"), -1);
298 if ((r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].flags3 & RF3_AURA_COLD) && !creature_ptr->immune_cold) {
299 damage = r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx].level / 2;
300 if (creature_ptr->resist_cold)
302 if (is_oppose_cold(creature_ptr))
304 msg_print(_("冷たい!", "It's cold!"));
305 take_hit(creature_ptr, DAMAGE_NOESCAPE, damage, _("冷気のオーラ", "Cold aura"), -1);
309 /* Spectres -- take damage when moving through walls */
311 * Added: ANYBODY takes damage if inside through walls
312 * without wraith form -- NOTE: Spectres will never be
313 * reduced below 0 hp by being inside a stone wall; others
316 if (!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) {
317 if (!is_invuln(creature_ptr) && !creature_ptr->wraith_form && !creature_ptr->kabenuke
318 && ((creature_ptr->chp > (creature_ptr->lev / 5)) || !creature_ptr->pass_wall)) {
320 cave_no_regen = TRUE;
322 if (creature_ptr->pass_wall) {
323 msg_print(_("体の分子が分解した気がする!", "Your molecules feel disrupted!"));
324 dam_desc = _("密度", "density");
326 msg_print(_("崩れた岩に押し潰された!", "You are being crushed!"));
327 dam_desc = _("硬い岩", "solid rock");
330 take_hit(creature_ptr, DAMAGE_NOESCAPE, 1 + (creature_ptr->lev / 5), dam_desc, -1);
334 if (creature_ptr->food < PY_FOOD_WEAK) {
335 if (creature_ptr->food < PY_FOOD_STARVE) {
337 } else if (creature_ptr->food < PY_FOOD_FAINT) {
338 regen_amount = PY_REGEN_FAINT;
340 regen_amount = PY_REGEN_WEAK;
344 if (pattern_effect(creature_ptr)) {
345 cave_no_regen = TRUE;
347 if (creature_ptr->regenerate) {
348 regen_amount = regen_amount * 2;
350 if (creature_ptr->special_defense & (KAMAE_MASK | KATA_MASK)) {
353 if (creature_ptr->cursed & TRC_SLOW_REGEN) {
358 if ((creature_ptr->action == ACTION_SEARCH) || (creature_ptr->action == ACTION_REST)) {
359 regen_amount = regen_amount * 2;
362 upkeep_factor = calculate_upkeep(creature_ptr);
363 if ((creature_ptr->action == ACTION_LEARN) || (creature_ptr->action == ACTION_HAYAGAKE) || (creature_ptr->special_defense & KATA_KOUKIJIN)) {
364 upkeep_factor += 100;
367 regenmana(creature_ptr, upkeep_factor, regen_amount);
368 if (creature_ptr->pclass == CLASS_MAGIC_EATER) {
369 regenmagic(creature_ptr, regen_amount);
372 if ((creature_ptr->csp == 0) && (creature_ptr->csp_frac == 0)) {
373 while (upkeep_factor > 100) {
374 msg_print(_("こんなに多くのペットを制御できない!", "Too many pets to control at once!"));
376 do_cmd_pet_dismiss(creature_ptr);
378 upkeep_factor = calculate_upkeep(creature_ptr);
380 msg_format(_("維持MPは %d%%", "Upkeep: %d%% mana."), upkeep_factor);
385 if (creature_ptr->poisoned)
387 if (creature_ptr->cut)
392 regen_amount = (regen_amount * creature_ptr->mutant_regenerate_mod) / 100;
393 if ((creature_ptr->chp < creature_ptr->mhp) && !cave_no_regen) {
394 regenhp(creature_ptr, regen_amount);