OSDN Git Service

Merge pull request #2658 from sikabane-works/release/3.0.0Alpha66
[hengbandforosx/hengbandosx.git] / src / mspell / mspell-attack / mspell-curse.cpp
1 #include "mspell/mspell-attack/mspell-curse.h"
2 #include "core/disturbance.h"
3 #include "effect/attribute-types.h"
4 #include "effect/effect-processor.h"
5 #include "monster/monster-info.h"
6 #include "monster/monster-list.h"
7 #include "mspell/mspell-checker.h"
8 #include "mspell/mspell-damage-calculator.h"
9 #include "mspell/mspell-data.h"
10 #include "mspell/mspell-result.h"
11 #include "mspell/mspell-util.h"
12 #include "system/floor-type-definition.h"
13 #include "timed-effect/player-blindness.h"
14 #include "timed-effect/timed-effects.h"
15 #include "view/display-messages.h"
16
17 static bool message_curse(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, std::string_view msg1, std::string_view msg2, std::string_view msg3, int target_type)
18 {
19     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
20     monster_name(player_ptr, m_idx, m_name);
21     monster_name(player_ptr, t_idx, t_name);
22
23     if (target_type == MONSTER_TO_PLAYER) {
24         disturb(player_ptr, true, true);
25         if (player_ptr->effects()->blindness()->is_blind()) {
26             msg_format(msg1.data(), m_name);
27         } else {
28             msg_format(msg2.data(), m_name);
29         }
30     } else if (target_type == MONSTER_TO_MONSTER) {
31         if (see_monster(player_ptr, m_idx)) {
32             msg_format(msg3.data(), m_name, t_name);
33         } else {
34             player_ptr->current_floor_ptr->monster_noise = true;
35         }
36     }
37     return false;
38 }
39
40 CurseData::CurseData(const std::string_view &msg1, const std::string_view &msg2, const std::string_view &msg3, const AttributeType &typ)
41     : MSpellData([=](auto *player_ptr, auto m_idx, auto t_idx, int target_type) {
42         return message_curse(player_ptr, m_idx, t_idx, msg1, msg2, msg3, target_type);
43     },
44           typ)
45 {
46 }
47
48 const std::unordered_map<MonsterAbilityType, CurseData> curse_list = {
49     { MonsterAbilityType::CAUSE_1, { _("%^sが何かをつぶやいた。", "%^s mumbles."),
50                                        _("%^sがあなたを指さして呪った。", "%^s points at you and curses."), _("%^sは%sを指さして呪いをかけた。", "%^s points at %s and curses."),
51                                        AttributeType::CAUSE_1 } },
52     { MonsterAbilityType::CAUSE_2, { _("%^sが何かをつぶやいた。", "%^s mumbles."),
53                                        _("%^sがあなたを指さして恐ろしげに呪った。", "%^s points at you and curses horribly."),
54                                        _("%^sは%sを指さして恐ろしげに呪いをかけた。", "%^s points at %s and curses horribly."),
55                                        AttributeType::CAUSE_2 } },
56     { MonsterAbilityType::CAUSE_3, { _("%^sが何かを大声で叫んだ。", "%^s mumbles loudly."),
57                                        _("%^sがあなたを指さして恐ろしげに呪文を唱えた!", "%^s points at you, incanting terribly!"),
58                                        _("%^sは%sを指さし、恐ろしげに呪文を唱えた!", "%^s points at %s, incanting terribly!"),
59                                        AttributeType::CAUSE_3 } },
60     { MonsterAbilityType::CAUSE_4, { _("%^sが「お前は既に死んでいる」と叫んだ。", "%^s screams the word 'DIE!'"),
61                                        _("%^sがあなたの秘孔を突いて「お前は既に死んでいる」と叫んだ。", "%^s points at you, screaming the word DIE!"),
62                                        _("%^sが%sの秘孔を突いて、「お前は既に死んでいる」と叫んだ。", "%^s points at %s, screaming the word, 'DIE!'"),
63                                        AttributeType::CAUSE_4 } },
64 };
65
66 /*!
67  * @brief RF5_CAUSE_* の処理関数
68  * @param player_ptr プレイヤーへの参照ポインタ
69  * @param ms_type 呪文の番号
70  * @param dam 攻撃に使用するダメージ量
71  * @param y 対象の地点のy座標
72  * @param x 対象の地点のx座標
73  * @param m_idx 呪文を唱えるモンスターID
74  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
75  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
76  */
77 MonsterSpellResult spell_RF5_CAUSE(PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
78 {
79     if (curse_list.find(ms_type) == curse_list.end()) {
80         return MonsterSpellResult::make_invalid();
81     }
82
83     curse_list.at(ms_type).msg.output(player_ptr, m_idx, t_idx, target_type);
84
85     const auto dam = monspell_damage(player_ptr, ms_type, m_idx, DAM_ROLL);
86
87     pointed(player_ptr, y, x, m_idx, curse_list.at(ms_type).type, dam, target_type);
88
89     auto res = MonsterSpellResult::make_valid(dam);
90     res.learnable = target_type == MONSTER_TO_PLAYER;
91
92     return res;
93 }