OSDN Git Service

[Refactor] #3359 'const auto flags_swrf = {' を'static constexpr auto flags_swrf ...
[hengbandforosx/hengbandosx.git] / src / mind / mind-samurai.cpp
1 /*!
2  * @brief 剣術家のレイシャルパワー処理
3  * @date 2020/05/16
4  * @author Hourier
5  */
6
7 #include "mind/mind-samurai.h"
8 #include "action/action-limited.h"
9 #include "avatar/avatar.h"
10 #include "cmd-action/cmd-attack.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "io/input-key-acceptor.h"
13 #include "mind/stances-table.h"
14 #include "monster-attack/monster-attack-player.h"
15 #include "monster-race/monster-race-hook.h"
16 #include "monster-race/monster-race.h"
17 #include "monster-race/race-flags-resistance.h"
18 #include "monster-race/race-flags3.h"
19 #include "monster-race/race-resistance-mask.h"
20 #include "monster/monster-describer.h"
21 #include "monster/monster-info.h"
22 #include "monster/monster-status-setter.h"
23 #include "monster/monster-status.h"
24 #include "object-enchant/tr-types.h"
25 #include "pet/pet-util.h"
26 #include "player-attack/player-attack-util.h"
27 #include "player-base/player-class.h"
28 #include "player-info/samurai-data-type.h"
29 #include "player/attack-defense-types.h"
30 #include "status/action-setter.h"
31 #include "system/grid-type-definition.h"
32 #include "system/item-entity.h"
33 #include "system/monster-entity.h"
34 #include "system/monster-race-info.h"
35 #include "system/player-type-definition.h"
36 #include "system/redrawing-flags-updater.h"
37 #include "term/screen-processor.h"
38 #include "term/z-form.h"
39 #include "timed-effect/player-cut.h"
40 #include "timed-effect/player-fear.h"
41 #include "timed-effect/player-stun.h"
42 #include "timed-effect/timed-effects.h"
43 #include "util/bit-flags-calculator.h"
44 #include "util/int-char-converter.h"
45 #include "view/display-messages.h"
46
47 struct samurai_slaying_type {
48     MULTIPLY mult;
49     TrFlags flags;
50     MonsterEntity *m_ptr;
51     combat_options mode;
52     MonsterRaceInfo *r_ptr;
53 };
54
55 static samurai_slaying_type *initialize_samurai_slaying_type(
56     samurai_slaying_type *samurai_slaying_ptr, MULTIPLY mult, const TrFlags &flags, MonsterEntity *m_ptr, combat_options mode, MonsterRaceInfo *r_ptr)
57 {
58     samurai_slaying_ptr->mult = mult;
59     samurai_slaying_ptr->flags = flags;
60     samurai_slaying_ptr->m_ptr = m_ptr;
61     samurai_slaying_ptr->mode = mode;
62     samurai_slaying_ptr->r_ptr = r_ptr;
63     return samurai_slaying_ptr;
64 }
65
66 /*!
67  * @nrief 焔霊 (焼棄スレイ)
68  * @param player_ptr プレイヤーへの参照ポインタ
69  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
70  */
71 static void hissatsu_burning_strike(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
72 {
73     if (samurai_slaying_ptr->mode != HISSATSU_FIRE) {
74         return;
75     }
76
77     /* Notice immunity */
78     if (samurai_slaying_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_FIRE_MASK)) {
79         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
80             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(samurai_slaying_ptr->r_ptr->resistance_flags & RFR_EFF_IM_FIRE_MASK);
81         }
82
83         return;
84     }
85
86     /* Otherwise, take the damage */
87     if (samurai_slaying_ptr->flags.has(TR_BRAND_FIRE)) {
88         if (samurai_slaying_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_FIRE)) {
89             if (samurai_slaying_ptr->mult < 70) {
90                 samurai_slaying_ptr->mult = 70;
91             }
92
93             if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
94                 samurai_slaying_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_FIRE);
95             }
96
97         } else if (samurai_slaying_ptr->mult < 35) {
98             samurai_slaying_ptr->mult = 35;
99         }
100
101         return;
102     }
103
104     if (samurai_slaying_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_FIRE)) {
105         if (samurai_slaying_ptr->mult < 50) {
106             samurai_slaying_ptr->mult = 50;
107         }
108
109         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
110             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_FIRE);
111         }
112     } else if (samurai_slaying_ptr->mult < 25) {
113         samurai_slaying_ptr->mult = 25;
114     }
115 }
116
117 /*!
118  * @brief サーペンツタン (毒殺スレイ)
119  * @param player_ptr プレイヤーへの参照ポインタ
120  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
121  */
122 static void hissatsu_serpent_tongue(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
123 {
124     if (samurai_slaying_ptr->mode != HISSATSU_POISON) {
125         return;
126     }
127
128     /* Notice immunity */
129     if (samurai_slaying_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_POISON_MASK)) {
130         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
131             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(samurai_slaying_ptr->r_ptr->resistance_flags & RFR_EFF_IM_POISON_MASK);
132         }
133
134         return;
135     }
136
137     /* Otherwise, take the damage */
138     if (samurai_slaying_ptr->flags.has(TR_BRAND_POIS)) {
139         if (samurai_slaying_ptr->mult < 35) {
140             samurai_slaying_ptr->mult = 35;
141         }
142     } else if (samurai_slaying_ptr->mult < 25) {
143         samurai_slaying_ptr->mult = 25;
144     }
145 }
146
147 /*!
148  * @brief 二重の極み^h^h^h^h^h 斬魔剣弐の太刀 (邪悪無生命スレイ)
149  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
150  */
151 static void hissatsu_zanma_ken(samurai_slaying_type *samurai_slaying_ptr)
152 {
153     if (samurai_slaying_ptr->mode != HISSATSU_ZANMA) {
154         return;
155     }
156
157     if (!samurai_slaying_ptr->m_ptr->has_living_flag() && samurai_slaying_ptr->r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
158         if (samurai_slaying_ptr->mult < 15) {
159             samurai_slaying_ptr->mult = 25;
160         } else if (samurai_slaying_ptr->mult < 50) {
161             samurai_slaying_ptr->mult = std::min<short>(50, samurai_slaying_ptr->mult + 20);
162         }
163     }
164 }
165
166 /*!
167  * @brief 破岩斬 (岩石スレイ)
168  * @param player_ptr プレイヤーへの参照ポインタ
169  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
170  */
171 static void hissatsu_rock_smash(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
172 {
173     if (samurai_slaying_ptr->mode != HISSATSU_HAGAN) {
174         return;
175     }
176
177     if (samurai_slaying_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_ROCK)) {
178         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
179             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_ROCK);
180         }
181
182         if (samurai_slaying_ptr->mult == 10) {
183             samurai_slaying_ptr->mult = 40;
184         } else if (samurai_slaying_ptr->mult < 60) {
185             samurai_slaying_ptr->mult = 60;
186         }
187     }
188 }
189
190 /*!
191  * @brief 乱れ雪月花 (冷気スレイ)
192  * @param player_ptr プレイヤーへの参照ポインタ
193  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
194  */
195 static void hissatsu_midare_setsugetsuka(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
196 {
197     if (samurai_slaying_ptr->mode != HISSATSU_COLD) {
198         return;
199     }
200
201     /* Notice immunity */
202     if (samurai_slaying_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_COLD_MASK)) {
203         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
204             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(samurai_slaying_ptr->r_ptr->resistance_flags & RFR_EFF_IM_COLD_MASK);
205         }
206
207         return;
208     }
209
210     /* Otherwise, take the damage */
211     if (samurai_slaying_ptr->flags.has(TR_BRAND_COLD)) {
212         if (samurai_slaying_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_COLD)) {
213             if (samurai_slaying_ptr->mult < 70) {
214                 samurai_slaying_ptr->mult = 70;
215             }
216
217             if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
218                 samurai_slaying_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_COLD);
219             }
220         } else if (samurai_slaying_ptr->mult < 35) {
221             samurai_slaying_ptr->mult = 35;
222         }
223
224         return;
225     }
226
227     if (samurai_slaying_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_COLD)) {
228         if (samurai_slaying_ptr->mult < 50) {
229             samurai_slaying_ptr->mult = 50;
230         }
231
232         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
233             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_COLD);
234         }
235     } else if (samurai_slaying_ptr->mult < 25) {
236         samurai_slaying_ptr->mult = 25;
237     }
238 }
239
240 /*!
241  * @brief 雷撃鷲爪斬
242  * @param player_ptr プレイヤーへの参照ポインタ
243  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
244  */
245 static void hissatsu_lightning_eagle(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
246 {
247     if (samurai_slaying_ptr->mode != HISSATSU_ELEC) {
248         return;
249     }
250
251     /* Notice immunity */
252     if (samurai_slaying_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_ELEC_MASK)) {
253         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
254             samurai_slaying_ptr->r_ptr->r_resistance_flags.set(samurai_slaying_ptr->r_ptr->resistance_flags & RFR_EFF_IM_ELEC_MASK);
255         }
256
257         return;
258     }
259
260     /* Otherwise, take the damage */
261     if (samurai_slaying_ptr->flags.has(TR_BRAND_ELEC)) {
262         if (samurai_slaying_ptr->mult < 70) {
263             samurai_slaying_ptr->mult = 70;
264         }
265     } else if (samurai_slaying_ptr->mult < 50) {
266         samurai_slaying_ptr->mult = 50;
267     }
268 }
269
270 /*!
271  * @brief 赤流渦 (ペインバッカー)
272  * @param player_ptr プレイヤーへの参照ポインタ
273  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
274  */
275 static void hissatsu_bloody_maelstroem(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
276 {
277     auto player_cut = player_ptr->effects()->cut();
278     if ((samurai_slaying_ptr->mode == HISSATSU_SEKIRYUKA) && player_cut->is_cut() && samurai_slaying_ptr->m_ptr->has_living_flag()) {
279         auto tmp = std::min<short>(100, std::max<short>(10, player_cut->current() / 10));
280         if (samurai_slaying_ptr->mult < tmp) {
281             samurai_slaying_ptr->mult = tmp;
282         }
283     }
284 }
285
286 /*!
287  * @brief 慶雲鬼忍剣 (アンデッドスレイ)
288  * @param player_ptr プレイヤーへの参照ポインタ
289  * @param samurai_slaying_ptr スレイ計算に必要なパラメータ群への参照ポインタ
290  */
291 static void hissatsu_keiun_kininken(PlayerType *player_ptr, samurai_slaying_type *samurai_slaying_ptr)
292 {
293     if (samurai_slaying_ptr->mode != HISSATSU_UNDEAD) {
294         return;
295     }
296
297     if (samurai_slaying_ptr->r_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
298         if (is_original_ap_and_seen(player_ptr, samurai_slaying_ptr->m_ptr)) {
299             samurai_slaying_ptr->r_ptr->r_kind_flags.set(MonsterKindType::UNDEAD);
300
301             if (samurai_slaying_ptr->mult == 10) {
302                 samurai_slaying_ptr->mult = 70;
303             } else if (samurai_slaying_ptr->mult < 140) {
304                 samurai_slaying_ptr->mult = std::min<short>(140, samurai_slaying_ptr->mult + 60);
305             }
306         }
307     }
308
309     if (samurai_slaying_ptr->mult == 10) {
310         samurai_slaying_ptr->mult = 40;
311     } else if (samurai_slaying_ptr->mult < 60) {
312         samurai_slaying_ptr->mult = std::min<short>(60, samurai_slaying_ptr->mult + 30);
313     }
314 }
315
316 /*!
317  * @brief 剣術のスレイ倍率計算を行う /
318  * Calcurate magnification of hissatsu technics
319  * @param mult 剣術のスレイ効果以前に算出している多要素の倍率(/10倍)
320  * @param flags 剣術に使用する武器のスレイフラグ配列
321  * @param m_ptr 目標となるモンスターの構造体参照ポインタ
322  * @param mode 剣術のスレイ型ID
323  * @return スレイの倍率(/10倍)
324  */
325 MULTIPLY mult_hissatsu(PlayerType *player_ptr, MULTIPLY mult, const TrFlags &flags, MonsterEntity *m_ptr, combat_options mode)
326 {
327     auto *r_ptr = &monraces_info[m_ptr->r_idx];
328     samurai_slaying_type tmp_slaying;
329     samurai_slaying_type *samurai_slaying_ptr = initialize_samurai_slaying_type(&tmp_slaying, mult, flags, m_ptr, mode, r_ptr);
330     hissatsu_burning_strike(player_ptr, samurai_slaying_ptr);
331     hissatsu_serpent_tongue(player_ptr, samurai_slaying_ptr);
332     hissatsu_zanma_ken(samurai_slaying_ptr);
333     hissatsu_rock_smash(player_ptr, samurai_slaying_ptr);
334     hissatsu_midare_setsugetsuka(player_ptr, samurai_slaying_ptr);
335     hissatsu_lightning_eagle(player_ptr, samurai_slaying_ptr);
336     hissatsu_bloody_maelstroem(player_ptr, samurai_slaying_ptr);
337     hissatsu_keiun_kininken(player_ptr, samurai_slaying_ptr);
338
339     if (samurai_slaying_ptr->mult > 150) {
340         samurai_slaying_ptr->mult = 150;
341     }
342
343     return samurai_slaying_ptr->mult;
344 }
345
346 void concentration(PlayerType *player_ptr)
347 {
348     int max_csp = std::max(player_ptr->msp * 4, player_ptr->lev * 5 + 5);
349
350     if (total_friends) {
351         msg_print(_("今はペットを操ることに集中していないと。", "Your pets demand all of your attention."));
352         return;
353     }
354
355     if (!PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::NONE)) {
356         msg_print(_("今は構えに集中している。", "You're already concentrating on your stance."));
357         return;
358     }
359
360     msg_print(_("精神を集中して気合いを溜めた。", "You concentrate to charge your power."));
361
362     player_ptr->csp += player_ptr->msp / 2;
363     if (player_ptr->csp >= max_csp) {
364         player_ptr->csp = max_csp;
365         player_ptr->csp_frac = 0;
366     }
367
368     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::MP);
369 }
370
371 /*!
372  * @brief 剣術家の型設定処理
373  * @return 型を変化させたらTRUE、型の構え不能かキャンセルしたらFALSEを返す。
374  */
375 bool choose_samurai_stance(PlayerType *player_ptr)
376 {
377     char choice;
378     char buf[80];
379
380     if (cmd_limit_confused(player_ptr)) {
381         return false;
382     }
383
384     auto effects = player_ptr->effects();
385     if (effects->stun()->is_stunned()) {
386         msg_print(_("意識がはっきりとしない。", "You are not clear-headed"));
387         return false;
388     }
389
390     if (effects->fear()->is_fearful()) {
391         msg_print(_("体が震えて構えられない!", "You are trembling with fear!"));
392         return false;
393     }
394
395     screen_save();
396     prt(_(" a) 型を崩す", " a) No Form"), 2, 20);
397     for (auto i = 0U; i < samurai_stances.size(); i++) {
398         if (player_ptr->lev >= samurai_stances[i].min_level) {
399             strnfmt(buf, sizeof(buf), _(" %c) %sの型    %s", " %c) Stance of %-12s  %s"), I2A(i + 1), samurai_stances[i].desc, samurai_stances[i].info);
400             prt(buf, 3 + i, 20);
401         }
402     }
403
404     prt("", 1, 0);
405     prt(_("        どの型で構えますか?", "        Choose Stance: "), 1, 14);
406
407     SamuraiStanceType new_stance = SamuraiStanceType::NONE;
408     while (true) {
409         choice = inkey();
410
411         if (choice == ESCAPE) {
412             screen_load();
413             return false;
414         } else if ((choice == 'a') || (choice == 'A')) {
415             if (player_ptr->action == ACTION_SAMURAI_STANCE) {
416                 set_action(player_ptr, ACTION_NONE);
417             } else {
418                 msg_print(_("もともと構えていない。", "You are not in a special stance."));
419             }
420             screen_load();
421             return true;
422         } else if ((choice == 'b') || (choice == 'B')) {
423             new_stance = SamuraiStanceType::IAI;
424             break;
425         } else if (((choice == 'c') || (choice == 'C')) && (player_ptr->lev > 29)) {
426             new_stance = SamuraiStanceType::FUUJIN;
427             break;
428         } else if (((choice == 'd') || (choice == 'D')) && (player_ptr->lev > 34)) {
429             new_stance = SamuraiStanceType::KOUKIJIN;
430             break;
431         } else if (((choice == 'e') || (choice == 'E')) && (player_ptr->lev > 39)) {
432             new_stance = SamuraiStanceType::MUSOU;
433             break;
434         }
435     }
436
437     set_action(player_ptr, ACTION_SAMURAI_STANCE);
438     auto &rfu = RedrawingFlagsUpdater::get_instance();
439     if (PlayerClass(player_ptr).samurai_stance_is(new_stance)) {
440         msg_print(_("構え直した。", "You reassume a stance."));
441     } else {
442         static constexpr auto flags_srf = {
443             StatusRedrawingFlag::BONUS,
444             StatusRedrawingFlag::MONSTER_STATUSES,
445         };
446         rfu.set_flags(flags_srf);
447         msg_format(_("%sの型で構えた。", "You assume the %s stance."), samurai_stances[enum2i(new_stance) - 1].desc);
448         PlayerClass(player_ptr).set_samurai_stance(new_stance);
449     }
450
451     static constexpr auto flags = {
452         MainWindowRedrawingFlag::ACTION,
453         MainWindowRedrawingFlag::TIMED_EFFECT,
454     };
455     rfu.set_flags(flags);
456     screen_load();
457     return true;
458 }
459
460 /*!
461  * @brief 剣術家限定で、型等に応じて命中率を高める
462  * @param player_ptr プレイヤーへの参照ポインタ
463  * @param pa_ptr 直接攻撃構造体への参照ポインタ
464  * @return 上昇後の命中率
465  */
466 int calc_attack_quality(PlayerType *player_ptr, player_attack_type *pa_ptr)
467 {
468     auto *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
469     int bonus = player_ptr->to_h[pa_ptr->hand] + o_ptr->to_h;
470     int chance = (player_ptr->skill_thn + (bonus * BTH_PLUS_ADJ));
471     if (pa_ptr->mode == HISSATSU_IAI) {
472         chance += 60;
473     }
474
475     if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::KOUKIJIN)) {
476         chance += 150;
477     }
478
479     if (player_ptr->sutemi) {
480         chance = std::max(chance * 3 / 2, chance + 60);
481     }
482
483     int vir = virtue_number(player_ptr, Virtue::VALOUR);
484     if (vir != 0) {
485         chance += (player_ptr->virtues[vir - 1] / 10);
486     }
487
488     return chance;
489 }
490
491 /*!
492  * @brief 峰打ちの効果処理
493  * @param player_ptr プレイヤーへの参照ポインタ
494  * @param pa_ptr 直接攻撃構造体への参照ポインタ
495  */
496 void mineuchi(PlayerType *player_ptr, player_attack_type *pa_ptr)
497 {
498     if (pa_ptr->mode != HISSATSU_MINEUCHI) {
499         return;
500     }
501
502     pa_ptr->attack_damage = 0;
503     anger_monster(player_ptr, pa_ptr->m_ptr);
504
505     auto *r_ptr = &monraces_info[pa_ptr->m_ptr->r_idx];
506     if ((r_ptr->flags3 & (RF3_NO_STUN))) {
507         msg_format(_("%s には効果がなかった。", "%s is not effected."), pa_ptr->m_name);
508         return;
509     }
510
511     int tmp = (10 + randint1(15) + player_ptr->lev / 5);
512     if (pa_ptr->m_ptr->get_remaining_stun()) {
513         msg_format(_("%sはひどくもうろうとした。", "%s is more dazed."), pa_ptr->m_name);
514         tmp /= 2;
515     } else {
516         msg_format(_("%s はもうろうとした。", "%s is dazed."), pa_ptr->m_name);
517     }
518
519     (void)set_monster_stunned(player_ptr, pa_ptr->g_ptr->m_idx, pa_ptr->m_ptr->get_remaining_stun() + tmp);
520 }
521
522 /*!
523  * @brief 無想による反撃処理
524  * @param player_ptr プレイヤーへの参照ポインタ
525  * @param pa_ptr 直接攻撃構造体への参照ポインタ
526  */
527 void musou_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
528 {
529     const auto is_musou = PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU);
530     if ((!player_ptr->counter && !is_musou) || !monap_ptr->alive || player_ptr->is_dead || !monap_ptr->m_ptr->ml || (player_ptr->csp <= 7)) {
531         return;
532     }
533
534     const auto m_target_name = monster_desc(player_ptr, monap_ptr->m_ptr, 0);
535     player_ptr->csp -= 7;
536     msg_format(_("%s^に反撃した!", "You counterattacked %s!"), m_target_name.data());
537     do_cmd_attack(player_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, HISSATSU_COUNTER);
538     monap_ptr->fear = false;
539     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::MP);
540 }