1 #include "status/buff-setter.h"
2 #include "avatar/avatar.h"
3 #include "core/disturbance.h"
4 #include "core/player-redraw-types.h"
5 #include "core/player-update-types.h"
6 #include "core/speed-table.h"
7 #include "core/stuff-handler.h"
8 #include "core/window-redrawer.h"
9 #include "game-option/disturbance-options.h"
10 #include "monster/monster-status-setter.h"
11 #include "player-info/class-info.h"
12 #include "player-info/race-info.h"
13 #include "player/attack-defense-types.h"
14 #include "player/player-status.h"
15 #include "realm/realm-song-numbers.h"
16 #include "spell-realm/spells-song.h"
17 #include "status/base-status.h"
18 #include "status/buff-setter.h"
19 #include "status/element-resistance.h"
20 #include "system/player-type-definition.h"
21 #include "timed-effect/player-cut.h"
22 #include "timed-effect/player-stun.h"
23 #include "timed-effect/timed-effects.h"
24 #include "view/display-messages.h"
27 * @brief プレイヤーの全ての時限効果をリセットする。 / reset timed flags
29 void reset_tim_flags(player_type *player_ptr)
31 auto effects = player_ptr->effects();
32 player_ptr->fast = 0; /* Timed -- Fast */
33 player_ptr->lightspeed = 0;
34 player_ptr->slow = 0; /* Timed -- Slow */
35 player_ptr->blind = 0; /* Timed -- Blindness */
36 player_ptr->paralyzed = 0; /* Timed -- Paralysis */
37 player_ptr->confused = 0; /* Timed -- Confusion */
38 player_ptr->afraid = 0; /* Timed -- Fear */
39 player_ptr->hallucinated = 0; /* Timed -- Hallucination */
40 player_ptr->poisoned = 0; /* Timed -- Poisoned */
41 effects->cut()->reset();
42 effects->stun()->reset();
44 player_ptr->protevil = 0; /* Timed -- Protection */
45 player_ptr->invuln = 0; /* Timed -- Invulnerable */
46 player_ptr->ult_res = 0;
47 player_ptr->hero = 0; /* Timed -- Heroism */
48 player_ptr->shero = 0; /* Timed -- Super Heroism */
49 player_ptr->shield = 0; /* Timed -- Shield Spell */
50 player_ptr->blessed = 0; /* Timed -- Blessed */
51 player_ptr->tim_invis = 0; /* Timed -- Invisibility */
52 player_ptr->tim_infra = 0; /* Timed -- Infra Vision */
53 player_ptr->tim_regen = 0; /* Timed -- Regeneration */
54 player_ptr->tim_stealth = 0; /* Timed -- Stealth */
55 player_ptr->tim_esp = 0;
56 player_ptr->wraith_form = 0; /* Timed -- Wraith Form */
57 player_ptr->tim_levitation = 0;
58 player_ptr->tim_sh_touki = 0;
59 player_ptr->tim_sh_fire = 0;
60 player_ptr->tim_sh_holy = 0;
61 player_ptr->tim_eyeeye = 0;
62 player_ptr->magicdef = 0;
63 player_ptr->resist_magic = 0;
64 player_ptr->tsuyoshi = 0;
65 player_ptr->tim_pass_wall = 0;
66 player_ptr->tim_res_nether = 0;
67 player_ptr->tim_res_time = 0;
68 player_ptr->tim_mimic = 0;
69 player_ptr->mimic_form = 0;
70 player_ptr->tim_reflect = 0;
71 player_ptr->multishadow = 0;
72 player_ptr->dustrobe = 0;
73 player_ptr->action = ACTION_NONE;
75 player_ptr->oppose_acid = 0; /* Timed -- oppose acid */
76 player_ptr->oppose_elec = 0; /* Timed -- oppose lightning */
77 player_ptr->oppose_fire = 0; /* Timed -- oppose heat */
78 player_ptr->oppose_cold = 0; /* Timed -- oppose cold */
79 player_ptr->oppose_pois = 0; /* Timed -- oppose poison */
81 player_ptr->word_recall = 0;
82 player_ptr->alter_reality = 0;
83 player_ptr->sutemi = false;
84 player_ptr->counter = false;
85 player_ptr->ele_attack = 0;
86 player_ptr->ele_immune = 0;
87 player_ptr->special_attack = 0L;
88 player_ptr->special_defense = 0L;
90 while (player_ptr->energy_need < 0)
91 player_ptr->energy_need += ENERGY_NEED();
93 player_ptr->timewalk = false;
95 if (player_ptr->riding) {
96 (void)set_monster_fast(player_ptr, player_ptr->riding, 0);
97 (void)set_monster_slow(player_ptr, player_ptr->riding, 0);
98 (void)set_monster_invulner(player_ptr, player_ptr->riding, 0, false);
101 if (player_ptr->pclass == CLASS_BARD) {
102 set_singing_song_effect(player_ptr, MUSIC_NONE);
103 set_singing_song_id(player_ptr, 0);
108 * @brief 加速の継続時間をセットする / Set "fast", notice observable changes
110 * @param do_dec 現在の継続時間より長い値のみ上書きする
111 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
113 bool set_fast(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
116 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
118 if (player_ptr->is_dead)
122 if (player_ptr->fast && !do_dec) {
123 if (player_ptr->fast > v)
125 } else if (!is_fast(player_ptr) && !player_ptr->lightspeed) {
126 msg_print(_("素早く動けるようになった!", "You feel yourself moving much faster!"));
128 chg_virtue(player_ptr, V_PATIENCE, -1);
129 chg_virtue(player_ptr, V_DILIGENCE, 1);
132 if (player_ptr->fast && !player_ptr->lightspeed && !music_singing(player_ptr, MUSIC_SPEED) && !music_singing(player_ptr, MUSIC_SHERO)) {
133 msg_print(_("動きの素早さがなくなったようだ。", "You feel yourself slow down."));
138 player_ptr->fast = v;
143 disturb(player_ptr, false, false);
144 player_ptr->update |= (PU_BONUS);
145 handle_stuff(player_ptr);
150 * @brief 肌石化の継続時間をセットする / Set "shield", notice observable changes
152 * @param do_dec 現在の継続時間より長い値のみ上書きする
153 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
155 bool set_shield(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
158 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
160 if (player_ptr->is_dead)
164 if (player_ptr->shield && !do_dec) {
165 if (player_ptr->shield > v)
167 } else if (!player_ptr->shield) {
168 msg_print(_("肌が石になった。", "Your skin turns to stone."));
172 if (player_ptr->shield) {
173 msg_print(_("肌が元に戻った。", "Your skin returns to normal."));
178 player_ptr->shield = v;
179 player_ptr->redraw |= (PR_STATUS);
185 disturb(player_ptr, false, false);
186 player_ptr->update |= (PU_BONUS);
187 handle_stuff(player_ptr);
192 * @brief 魔法の鎧の継続時間をセットする / Set "magicdef", notice observable changes
194 * @param do_dec 現在の継続時間より長い値のみ上書きする
195 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
197 bool set_magicdef(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
200 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
202 if (player_ptr->is_dead)
206 if (player_ptr->magicdef && !do_dec) {
207 if (player_ptr->magicdef > v)
209 } else if (!player_ptr->magicdef) {
210 msg_print(_("魔法の防御力が増したような気がする。", "You feel more resistant to magic."));
214 if (player_ptr->magicdef) {
215 msg_print(_("魔法の防御力が元に戻った。", "You feel less resistant to magic."));
220 player_ptr->magicdef = v;
221 player_ptr->redraw |= (PR_STATUS);
227 disturb(player_ptr, false, false);
228 player_ptr->update |= (PU_BONUS);
229 handle_stuff(player_ptr);
234 * @brief 祝福の継続時間をセットする / Set "blessed", notice observable changes
236 * @param do_dec 現在の継続時間より長い値のみ上書きする
237 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
239 bool set_blessed(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
242 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
244 if (player_ptr->is_dead)
248 if (player_ptr->blessed && !do_dec) {
249 if (player_ptr->blessed > v)
251 } else if (!is_blessed(player_ptr)) {
252 msg_print(_("高潔な気分になった!", "You feel righteous!"));
256 if (player_ptr->blessed && !music_singing(player_ptr, MUSIC_BLESS)) {
257 msg_print(_("高潔な気分が消え失せた。", "The prayer has expired."));
262 player_ptr->blessed = v;
263 player_ptr->redraw |= (PR_STATUS);
269 disturb(player_ptr, false, false);
270 player_ptr->update |= (PU_BONUS);
271 handle_stuff(player_ptr);
276 * @brief 士気高揚の継続時間をセットする / Set "hero", notice observable changes
278 * @param do_dec 現在の継続時間より長い値のみ上書きする
279 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
281 bool set_hero(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
284 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
286 if (player_ptr->is_dead)
290 if (player_ptr->hero && !do_dec) {
291 if (player_ptr->hero > v)
293 } else if (!is_hero(player_ptr)) {
294 msg_print(_("ヒーローになった気がする!", "You feel like a hero!"));
298 if (player_ptr->hero && !music_singing(player_ptr, MUSIC_HERO) && !music_singing(player_ptr, MUSIC_SHERO)) {
299 msg_print(_("ヒーローの気分が消え失せた。", "The heroism wears off."));
304 player_ptr->hero = v;
305 player_ptr->redraw |= (PR_STATUS);
311 disturb(player_ptr, false, false);
312 player_ptr->update |= (PU_BONUS);
313 player_ptr->update |= (PU_HP);
314 handle_stuff(player_ptr);
319 * @brief 変身効果の継続時間と変身先をセットする / Set "tim_mimic", and "mimic_form", notice observable changes
321 * @param mimic_race_idx 変身内容
322 * @param do_dec 現在の継続時間より長い値のみ上書きする
323 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
325 bool set_mimic(player_type *player_ptr, TIME_EFFECT v, int16_t mimic_race_idx, bool do_dec)
328 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
330 if (player_ptr->is_dead)
334 if (player_ptr->tim_mimic && (player_ptr->mimic_form == mimic_race_idx) && !do_dec) {
335 if (player_ptr->tim_mimic > v)
337 } else if ((!player_ptr->tim_mimic) || (player_ptr->mimic_form != mimic_race_idx)) {
338 msg_print(_("自分の体が変わってゆくのを感じた。", "You feel that your body changes."));
339 player_ptr->mimic_form = mimic_race_idx;
345 if (player_ptr->tim_mimic) {
346 msg_print(_("変身が解けた。", "You are no longer transformed."));
347 if (player_ptr->mimic_form == MIMIC_DEMON)
348 set_oppose_fire(player_ptr, 0, true);
349 player_ptr->mimic_form = 0;
355 player_ptr->tim_mimic = v;
360 disturb(player_ptr, false, true);
362 player_ptr->redraw |= (PR_BASIC | PR_STATUS);
363 player_ptr->update |= (PU_BONUS | PU_HP);
365 handle_stuff(player_ptr);
370 * @brief 狂戦士化の継続時間をセットする / Set "shero", notice observable changes
371 * @param v 継続時間/ 0ならば無条件にリセット
372 * @param do_dec FALSEの場合現在の継続時間より長い値のみ上書きする
373 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
375 bool set_shero(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
378 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
380 if (player_ptr->is_dead)
383 if (player_ptr->pclass == CLASS_BERSERKER) {
389 if (player_ptr->shero && !do_dec) {
390 if (player_ptr->shero > v)
392 } else if (!player_ptr->shero) {
393 msg_print(_("殺戮マシーンになった気がする!", "You feel like a killing machine!"));
397 if (player_ptr->shero) {
398 msg_print(_("野蛮な気持ちが消え失せた。", "You feel less berserk."));
403 player_ptr->shero = v;
404 player_ptr->redraw |= (PR_STATUS);
410 disturb(player_ptr, false, false);
411 player_ptr->update |= (PU_BONUS);
412 player_ptr->update |= (PU_HP);
413 handle_stuff(player_ptr);
418 * @brief 幽体化の継続時間をセットする / Set "wraith_form", notice observable changes
420 * @param do_dec 現在の継続時間より長い値のみ上書きする
421 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
423 bool set_wraith_form(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
426 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
428 if (player_ptr->is_dead)
432 if (player_ptr->wraith_form && !do_dec) {
433 if (player_ptr->wraith_form > v)
435 } else if (!player_ptr->wraith_form) {
436 msg_print(_("物質界を離れて幽鬼のような存在になった!", "You leave the physical world and turn into a wraith-being!"));
438 chg_virtue(player_ptr, V_UNLIFE, 3);
439 chg_virtue(player_ptr, V_HONOUR, -2);
440 chg_virtue(player_ptr, V_SACRIFICE, -2);
441 chg_virtue(player_ptr, V_VALOUR, -5);
443 player_ptr->redraw |= (PR_MAP);
444 player_ptr->update |= (PU_MONSTERS);
446 player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
449 if (player_ptr->wraith_form) {
450 msg_print(_("不透明になった感じがする。", "You feel opaque."));
453 player_ptr->redraw |= (PR_MAP);
454 player_ptr->update |= (PU_MONSTERS);
456 player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
460 player_ptr->wraith_form = v;
461 player_ptr->redraw |= (PR_STATUS);
467 disturb(player_ptr, false, false);
468 player_ptr->update |= (PU_BONUS);
469 handle_stuff(player_ptr);
474 * @brief オクレ兄さんの継続時間をセットする / Set "tsuyoshi", notice observable changes
476 * @param do_dec 現在の継続時間より長い値のみ上書きする
477 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
479 bool set_tsuyoshi(player_type *player_ptr, TIME_EFFECT v, bool do_dec)
482 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
484 if (player_ptr->is_dead)
488 if (player_ptr->tsuyoshi && !do_dec) {
489 if (player_ptr->tsuyoshi > v)
491 } else if (!player_ptr->tsuyoshi) {
492 msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
494 chg_virtue(player_ptr, V_VITALITY, 2);
497 if (player_ptr->tsuyoshi) {
498 msg_print(_("肉体が急速にしぼんでいった。", "Your body has quickly shriveled."));
500 (void)dec_stat(player_ptr, A_CON, 20, true);
501 (void)dec_stat(player_ptr, A_STR, 20, true);
504 chg_virtue(player_ptr, V_VITALITY, -3);
508 player_ptr->tsuyoshi = v;
509 player_ptr->redraw |= (PR_STATUS);
515 disturb(player_ptr, false, false);
516 player_ptr->update |= (PU_BONUS);
517 player_ptr->update |= (PU_HP);
518 handle_stuff(player_ptr);