OSDN Git Service

3916568d9233ce005ef0bb838287164ba4466638
[hengbandforosx/hengbandosx.git] / src / mspell / specified-summon.cpp
1 #include "mspell/specified-summon.h"
2 #include "effect/effect-characteristics.h"
3 #include "effect/effect-processor.h"
4 #include "floor/cave.h"
5 #include "floor/floor-util.h"
6 #include "monster-floor/monster-summon.h"
7 #include "monster-floor/place-monster-types.h"
8 #include "monster-race/monster-race.h"
9 #include "monster-race/race-indice-types.h"
10 #include "monster/monster-info.h"
11 #include "mspell/mspell-checker.h"
12 #include "mspell/mspell-util.h"
13 #include "spell-kind/spells-launcher.h"
14 #include "spell/summon-types.h"
15 #include "system/monster-race-definition.h"
16 #include "system/player-type-definition.h"
17 #include "view/display-messages.h"
18
19 /*!
20  * @brief 鷹召喚の処理。 /
21  * @param player_ptr プレイヤーへの参照ポインタ
22  * @param y 対象の地点のy座標
23  * @param x 対象の地点のx座標
24  * @param rlev 呪文を唱えるモンスターのレベル
25  * @param m_idx 呪文を唱えるモンスターID
26  * @return 召喚したモンスターの数を返す。
27  */
28 MONSTER_NUMBER summon_EAGLE(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
29 {
30     int count = 0;
31     int num = 4 + randint1(3);
32     for (int k = 0; k < num; k++) {
33         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_EAGLES, PM_ALLOW_GROUP | PM_ALLOW_UNIQUE);
34     }
35
36     return count;
37 }
38
39 /*!
40  * @brief エッヂ召喚の処理。 /
41  * @param player_ptr プレイヤーへの参照ポインタ
42  * @param y 対象の地点のy座標
43  * @param x 対象の地点のx座標
44  * @param rlev 呪文を唱えるモンスターのレベル
45  * @param m_idx 呪文を唱えるモンスターID
46  * @return 召喚したモンスターの数を返す。
47  */
48 MONSTER_NUMBER summon_EDGE(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
49 {
50     int count = 0;
51     int num = 2 + randint1(1 + rlev / 20);
52     for (int k = 0; k < num; k++) {
53         count += summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::EDGE, PM_NONE);
54     }
55
56     return count;
57 }
58
59 /*!
60  * @brief ダンジョンの主召喚の処理。 /
61  * @param player_ptr プレイヤーへの参照ポインタ
62  * @param y 対象の地点のy座標
63  * @param x 対象の地点のx座標
64  * @param rlev 呪文を唱えるモンスターのレベル
65  * @param m_idx 呪文を唱えるモンスターID
66  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
67  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
68  * @return 召喚したモンスターの数を返す。
69  */
70 MONSTER_NUMBER summon_guardian(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
71 {
72     int num = 2 + randint1(3);
73     bool mon_to_mon = (target_type == MONSTER_TO_MONSTER);
74     bool mon_to_player = (target_type == MONSTER_TO_PLAYER);
75
76     if (r_info[MonsterRaceId::JORMUNGAND].cur_num < r_info[MonsterRaceId::JORMUNGAND].max_num && one_in_(6)) {
77         mspell_cast_msg_simple msg(_("地面から水が吹き出した!", "Water blew off from the ground!"),
78             _("地面から水が吹き出した!", "Water blew off from the ground!"));
79
80         simple_monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
81
82         if (mon_to_player) {
83             fire_ball_hide(player_ptr, AttributeType::WATER_FLOW, 0, 3, 8);
84         } else if (mon_to_mon) {
85             project(player_ptr, t_idx, 8, y, x, 3, AttributeType::WATER_FLOW, PROJECT_GRID | PROJECT_HIDE);
86         }
87     }
88
89     int count = 0;
90     for (int k = 0; k < num; k++) {
91         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_GUARDIANS, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
92     }
93
94     return count;
95 }
96
97 /*!
98  * @brief ロックのクローン召喚の処理。 /
99  * @param player_ptr プレイヤーへの参照ポインタ
100  * @param y 対象の地点のy座標
101  * @param x 対象の地点のx座標
102  * @param m_idx 呪文を唱えるモンスターID
103  * @return 召喚したモンスターの数を返す。
104  */
105 MONSTER_NUMBER summon_LOCKE_CLONE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
106 {
107     int count = 0;
108     int num = randint1(3);
109     for (int k = 0; k < num; k++) {
110         count += summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::LOCKE_CLONE, PM_NONE);
111     }
112
113     return count;
114 }
115
116 /*!
117  * @brief シラミ召喚の処理。 /
118  * @param player_ptr プレイヤーへの参照ポインタ
119  * @param y 対象の地点のy座標
120  * @param x 対象の地点のx座標
121  * @param rlev 呪文を唱えるモンスターのレベル
122  * @param m_idx 呪文を唱えるモンスターID
123  * @return 召喚したモンスターの数を返す。
124  */
125 MONSTER_NUMBER summon_LOUSE(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
126 {
127     int count = 0;
128     int num = 2 + randint1(3);
129     for (int k = 0; k < num; k++) {
130         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_LOUSE, PM_ALLOW_GROUP);
131     }
132
133     return count;
134 }
135
136 MONSTER_NUMBER summon_MOAI(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
137 {
138     int count = 0;
139     int num = 3 + randint1(3);
140     for (int k = 0; k < num; k++) {
141         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_SMALL_MOAI, PM_NONE);
142     }
143
144     return count;
145 }
146
147 MONSTER_NUMBER summon_DEMON_SLAYER(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
148 {
149     auto *r_ptr = &r_info[MonsterRaceId::DEMON_SLAYER_MEMBER];
150     if (r_ptr->max_num == 0) {
151         msg_print(_("しかし、隊士は全滅していた…。", "However, all demon slayer members were murdered..."));
152         return 0;
153     }
154
155     auto count = 0;
156     for (auto k = 0; k < MAX_NAZGUL_NUM; k++) {
157         count += summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::DEMON_SLAYER_MEMBER, PM_NONE);
158     }
159
160     if (count == 0) {
161         msg_print(_("しかし、隊士は誰も来てくれなかった。", "However, no demon slayer member answered the call..."));
162     }
163
164     return count;
165 }
166
167 /*!
168  * @brief ナズグル戦隊召喚の処理。 /
169  * @param player_ptr プレイヤーへの参照ポインタ
170  * @param y 対象の地点のy座標
171  * @param x 対象の地点のx座標
172  * @param m_idx 呪文を唱えるモンスターID
173  * @return 召喚したモンスターの数を返す。
174  */
175 MONSTER_NUMBER summon_NAZGUL(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
176 {
177     BIT_FLAGS mode = 0L;
178     POSITION cy = y;
179     POSITION cx = x;
180     GAME_TEXT m_name[MAX_NLEN];
181     monster_name(player_ptr, m_idx, m_name);
182
183     if (player_ptr->blind) {
184         msg_format(_("%^sが何かをつぶやいた。", "%^s mumbles."), m_name);
185     } else {
186         msg_format(_("%^sが魔法で幽鬼戦隊を召喚した!", "%^s magically summons rangers of Nazgul!"), m_name);
187     }
188
189     msg_print(nullptr);
190
191     int count = 0;
192     for (int k = 0; k < 30; k++) {
193         if (!summon_possible(player_ptr, cy, cx) || !is_cave_empty_bold(player_ptr, cy, cx)) {
194             int j;
195             for (j = 100; j > 0; j--) {
196                 scatter(player_ptr, &cy, &cx, y, x, 2, PROJECT_NONE);
197                 if (is_cave_empty_bold(player_ptr, cy, cx)) {
198                     break;
199                 }
200             }
201
202             if (!j) {
203                 break;
204             }
205         }
206
207         if (!is_cave_empty_bold(player_ptr, cy, cx)) {
208             continue;
209         }
210
211         if (!summon_named_creature(player_ptr, m_idx, cy, cx, MonsterRaceId::NAZGUL, mode)) {
212             continue;
213         }
214
215         y = cy;
216         x = cx;
217         count++;
218         if (count == 1) {
219             msg_format(_("「幽鬼戦隊%d号、ナズグル・ブラック!」", "A Nazgul says 'Nazgul-Rangers Number %d, Nazgul-Black!'"), count);
220         } else {
221             msg_format(_("「同じく%d号、ナズグル・ブラック!」", "Another one says 'Number %d, Nazgul-Black!'"), count);
222         }
223
224         msg_print(nullptr);
225     }
226
227     msg_format(_("「%d人そろって、リングレンジャー!」", "They say 'The %d meets! We are the Ring-Ranger!'."), count);
228     msg_print(nullptr);
229     return count;
230 }
231
232 MONSTER_NUMBER summon_APOCRYPHA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
233 {
234     int count = 0;
235     int num = 4 + randint1(4);
236     summon_type followers = one_in_(2) ? SUMMON_APOCRYPHA_FOLLOWERS : SUMMON_APOCRYPHA_DRAGONS;
237     for (int k = 0; k < num; k++) {
238         count += summon_specific(player_ptr, m_idx, y, x, 200, followers, PM_ALLOW_UNIQUE);
239     }
240
241     return count;
242 }
243
244 MONSTER_NUMBER summon_HIGHEST_DRAGON(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
245 {
246     int count = 0;
247     int num = 4 + randint1(4);
248     for (int k = 0; k < num; k++) {
249         count += summon_specific(player_ptr, m_idx, y, x, 100, SUMMON_APOCRYPHA_DRAGONS, PM_ALLOW_UNIQUE);
250     }
251
252     return count;
253 }
254
255 MONSTER_NUMBER summon_PYRAMID(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
256 {
257     int count = 0;
258     int num = 2 + randint1(3);
259     for (int k = 0; k < num; k++) {
260         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_PYRAMID, PM_NONE);
261     }
262
263     return count;
264 }
265
266 MONSTER_NUMBER summon_EYE_PHORN(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
267 {
268     int count = 0;
269     int num = 2 + randint1(1 + rlev / 20);
270     for (int k = 0; k < num; k++) {
271         count += summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::EYE_PHORN, PM_NONE);
272     }
273
274     return count;
275 }
276
277 MONSTER_NUMBER summon_VESPOID(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
278 {
279     int count = 0;
280     int num = 2 + randint1(3);
281     for (int k = 0; k < num; k++) {
282         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_VESPOID, PM_NONE);
283     }
284
285     return count;
286 }
287
288 MONSTER_NUMBER summon_THUNDERS(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
289 {
290     auto count = (MONSTER_NUMBER)0;
291     auto num = 11;
292     for (auto k = 0; k < num; k++) {
293         count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_ANTI_TIGERS, PM_NONE);
294     }
295
296     return count;
297 }
298
299 /*!
300  * @brief イェンダーの魔法使いの召喚の処理。 /
301  * @param player_ptr プレイヤーへの参照ポインタ
302  * @param y 対象の地点のy座標
303  * @param x 対象の地点のx座標
304  * @param m_idx 呪文を唱えるモンスターID
305  * @return 召喚したモンスターの数を返す。
306  */
307 MONSTER_NUMBER summon_YENDER_WIZARD(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
308 {
309     auto *r_ptr = &r_info[MonsterRaceId::YENDOR_WIZARD_2];
310     if (r_ptr->max_num == 0) {
311         msg_print(_("しかし、誰も来なかった…。", "However, no kin was appeared..."));
312         return 0;
313     }
314
315     auto count = (MONSTER_NUMBER)summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::YENDOR_WIZARD_2, PM_NONE);
316     if (count == 0) {
317         msg_print(_("どこからか声が聞こえる…「三重苦は負わぬ。。。」", "Heard a voice from somewhere... 'I will deny the triple suffering...'"));
318         return 0;
319     }
320
321     msg_print(_("二重苦だ。。。", "THIS is double suffering..."));
322     return count;
323 }
324
325 MONSTER_NUMBER summon_PLASMA(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
326 {
327     auto count = 0;
328     auto num = 2 + randint1(1 + rlev / 20);
329     for (auto k = 0; k < num; k++) {
330         count += summon_named_creature(player_ptr, m_idx, y, x, MonsterRaceId::PLASMA_VORTEX, PM_NONE);
331     }
332
333     msg_print(_("プーラーズーマーッ!!", "P--la--s--ma--!!"));
334     return count;
335 }