OSDN Git Service

[Refactor] #38993 m_cnt, m_max を floor_type 構造体に取り込み.
[hengband/hengband.git] / src / spells-summon.c
1 #include "angband.h"
2 #include "util.h"
3
4 #include "spells-summon.h"
5 #include "monster-status.h"
6 #include "floor.h"
7
8 /*!
9 * @brief トランプ魔法独自の召喚処理を行う / Handle summoning and failure of trump spells
10 * @param num summon_specific()関数を呼び出す回数
11 * @param pet ペット化として召喚されるか否か
12 * @param y 召喚位置のy座標
13 * @param x 召喚位置のx座標
14 * @param lev 召喚レベル
15 * @param type 召喚条件ID
16 * @param mode モンスター生成条件フラグ
17 * @return モンスターが(敵対も含めて)召還されたならばTRUEを返す。
18 */
19 bool trump_summoning(int num, bool pet, POSITION y, POSITION x, DEPTH lev, int type, BIT_FLAGS mode)
20 {
21         PLAYER_LEVEL plev = p_ptr->lev;
22
23         MONSTER_IDX who;
24         int i;
25         bool success = FALSE;
26
27         /* Default level */
28         if (!lev) lev = plev * 2 / 3 + randint1(plev / 2);
29
30         if (pet)
31         {
32                 /* Become pet */
33                 mode |= PM_FORCE_PET;
34
35                 /* Only sometimes allow unique monster */
36                 if (mode & PM_ALLOW_UNIQUE)
37                 {
38                         /* Forbid often */
39                         if (randint1(50 + plev) >= plev / 10)
40                                 mode &= ~PM_ALLOW_UNIQUE;
41                 }
42
43                 /* Player is who summons */
44                 who = -1;
45         }
46         else
47         {
48                 /* Prevent taming, allow unique monster */
49                 mode |= PM_NO_PET;
50
51                 /* Behave as if they appear by themselfs */
52                 who = 0;
53         }
54
55         for (i = 0; i < num; i++)
56         {
57                 if (summon_specific(who, y, x, lev, type, mode, '\0'))
58                         success = TRUE;
59         }
60
61         if (!success)
62         {
63                 msg_print(_("誰もあなたのカードの呼び声に答えない。", "Nobody answers to your Trump call."));
64         }
65
66         return success;
67 }
68
69
70 bool cast_summon_demon(int power)
71 {
72         u32b flg = 0L;
73         bool pet = !one_in_(3);
74
75         if (pet) flg |= PM_FORCE_PET;
76         else flg |= PM_NO_PET;
77         if (!(pet && (p_ptr->lev < 50))) flg |= PM_ALLOW_GROUP;
78
79         if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, power, SUMMON_DEMON, flg, '\0'))
80         {
81                 msg_print(_("硫黄の悪臭が充満した。", "The area fills with a stench of sulphur and brimstone."));
82                 if (pet)
83                 {
84                         msg_print(_("「ご用でございますか、ご主人様」", "'What is thy bidding... Master?'"));
85                 }
86                 else
87                 {
88                         msg_print(_("「卑しき者よ、我は汝の下僕にあらず! お前の魂を頂くぞ!」",
89                                 "'NON SERVIAM! Wretch! I shall feast on thy mortal soul!'"));
90                 }
91         }
92         return TRUE;
93 }
94
95 bool cast_summon_undead(player_type *creature_ptr, int power)
96 {
97         bool pet = one_in_(3);
98         int type;
99         BIT_FLAGS mode = 0L;
100
101         type = (creature_ptr->lev > 47 ? SUMMON_HI_UNDEAD : SUMMON_UNDEAD);
102
103         if (!pet || ((creature_ptr->lev > 24) && one_in_(3))) mode |= PM_ALLOW_GROUP;
104         if (pet) mode |= PM_FORCE_PET;
105         else mode |= (PM_ALLOW_UNIQUE | PM_NO_PET);
106
107         if (summon_specific((pet ? -1 : 0), creature_ptr->y, creature_ptr->x, power, type, mode, '\0'))
108         {
109                 msg_print(_("冷たい風があなたの周りに吹き始めた。それは腐敗臭を運んでいる...",
110                         "Cold winds begin to blow around you, carrying with them the stench of decay..."));
111                 if (pet)
112                         msg_print(_("古えの死せる者共があなたに仕えるため土から甦った!",
113                                 "Ancient, long-dead forms arise from the ground to serve you!"));
114                 else
115                         msg_print(_("死者が甦った。眠りを妨げるあなたを罰するために!",
116                                 "'The dead arise... to punish you for disturbing them!'"));
117         }
118         return TRUE;
119 }
120
121
122 bool cast_summon_hound(player_type *creature_ptr, int power)
123 {
124         BIT_FLAGS mode = PM_ALLOW_GROUP;
125         bool pet = !one_in_(5);
126         if (pet) mode |= PM_FORCE_PET;
127         else mode |= PM_NO_PET;
128
129         if (summon_specific((pet ? -1 : 0), creature_ptr->y, creature_ptr->x, power, SUMMON_HOUND, mode, '\0'))
130         {
131                 if (pet)
132                         msg_print(_("ハウンドがあなたの下僕として出現した。", "A group of hounds appear as your servant."));
133                 else
134                         msg_print(_("ハウンドはあなたに牙を向けている!", "A group of hounds appear as your enemy!"));
135         }
136         return TRUE;
137 }
138
139 bool cast_summon_elemental(player_type *creature_ptr, int power)
140 {
141         bool pet = one_in_(3);
142         BIT_FLAGS mode = 0L;
143
144         if (!(pet && (creature_ptr->lev < 50))) mode |= PM_ALLOW_GROUP;
145         if (pet) mode |= PM_FORCE_PET;
146         else mode |= PM_NO_PET;
147
148         if (summon_specific((pet ? -1 : 0), creature_ptr->y, creature_ptr->x, power, SUMMON_ELEMENTAL, mode, '\0'))
149         {
150                 msg_print(_("エレメンタルが現れた...", "An elemental materializes..."));
151                 if (pet)
152                         msg_print(_("あなたに服従しているようだ。", "It seems obedient to you."));
153                 else
154                         msg_print(_("それをコントロールできなかった!", "You fail to control it!"));
155         }
156
157         return TRUE;
158 }
159
160
161 bool cast_summon_octopus(player_type *creature_ptr)
162 {
163         BIT_FLAGS mode = PM_ALLOW_GROUP;
164         bool pet = !one_in_(5);
165         if (pet) mode |= PM_FORCE_PET;
166
167         if (summon_named_creature(0, creature_ptr->y, creature_ptr->x, MON_JIZOTAKO, mode))
168         {
169                 if (pet)
170                         msg_print(_("蛸があなたの下僕として出現した。", "A group of octopuses appear as your servant."));
171                 else
172                         msg_print(_("蛸はあなたを睨んでいる!", "A group of octopuses appear as your enemy!"));
173         }
174
175         return TRUE;
176 }
177
178 /*!
179 * @brief 悪魔領域のグレーターデーモン召喚に利用可能な死体かどうかを返す。 / An "item_tester_hook" for offer
180 * @param o_ptr オブジェクト構造体の参照ポインタ
181 * @return 生贄に使用可能な死体ならばTRUEを返す。
182 */
183 bool item_tester_offer(object_type *o_ptr)
184 {
185         /* Flasks of oil are okay */
186         if (o_ptr->tval != TV_CORPSE) return (FALSE);
187         if (o_ptr->sval != SV_CORPSE) return (FALSE);
188
189         if (my_strchr("pht", r_info[o_ptr->pval].d_char)) return (TRUE);
190
191         /* Assume not okay */
192         return (FALSE);
193 }
194
195 /*!
196 * @brief 悪魔領域のグレーターデーモン召喚を処理する / Daemon spell Summon Greater Demon
197 * @return 処理を実行したならばTRUEを返す。
198 */
199 bool cast_summon_greater_demon(void)
200 {
201         PLAYER_LEVEL plev = p_ptr->lev;
202         OBJECT_IDX item;
203         concptr q, s;
204         int summon_lev;
205         object_type *o_ptr;
206
207         item_tester_hook = item_tester_offer;
208         q = _("どの死体を捧げますか? ", "Sacrifice which corpse? ");
209         s = _("捧げられる死体を持っていない。", "You have nothing to scrifice.");
210         o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
211         if (!o_ptr) return FALSE;
212
213         summon_lev = plev * 2 / 3 + r_info[o_ptr->pval].level;
214
215         if (summon_specific(-1, p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_DEMON, (PM_ALLOW_GROUP | PM_FORCE_PET), '\0'))
216         {
217                 msg_print(_("硫黄の悪臭が充満した。", "The area fills with a stench of sulphur and brimstone."));
218                 msg_print(_("「ご用でございますか、ご主人様」", "'What is thy bidding... Master?'"));
219
220                 /* Decrease the item (from the pack) */
221                 if (item >= 0)
222                 {
223                         inven_item_increase(item, -1);
224                         inven_item_describe(item);
225                         inven_item_optimize(item);
226                 }
227
228                 /* Decrease the item (from the floor) */
229                 else
230                 {
231                         floor_item_increase(0 - item, -1);
232                         floor_item_describe(0 - item);
233                         floor_item_optimize(0 - item);
234                 }
235         }
236         else
237         {
238                 msg_print(_("悪魔は現れなかった。", "No Greater Demon arrive."));
239         }
240
241         return TRUE;
242 }
243
244 /*!
245  * @brief 同族召喚(援軍)処理
246  * @param level 召喚基準レベル
247  * @param y 召喚先Y座標
248  * @param x 召喚先X座標
249  * @param mode 召喚オプション
250  * @return ターンを消費した場合TRUEを返す
251  */
252 bool summon_kin_player(DEPTH level, POSITION y, POSITION x, BIT_FLAGS mode)
253 {
254         bool pet = (bool)(mode & PM_FORCE_PET);
255         SYMBOL_CODE symbol = '\0';
256         if (!pet) mode |= PM_NO_PET;
257
258         switch (p_ptr->mimic_form)
259         {
260         case MIMIC_NONE:
261                 switch (p_ptr->prace)
262                 {
263                 case RACE_HUMAN:
264                 case RACE_AMBERITE:
265                 case RACE_BARBARIAN:
266                 case RACE_BEASTMAN:
267                 case RACE_DUNADAN:
268                         symbol = 'p';
269                         break;
270                 case RACE_HALF_ELF:
271                 case RACE_ELF:
272                 case RACE_HOBBIT:
273                 case RACE_GNOME:
274                 case RACE_DWARF:
275                 case RACE_HIGH_ELF:
276                 case RACE_NIBELUNG:
277                 case RACE_DARK_ELF:
278                 case RACE_MIND_FLAYER:
279                 case RACE_KUTAR:
280                 case RACE_S_FAIRY:
281                         symbol = 'h';
282                         break;
283                 case RACE_HALF_ORC:
284                         symbol = 'o';
285                         break;
286                 case RACE_HALF_TROLL:
287                         symbol = 'T';
288                         break;
289                 case RACE_HALF_OGRE:
290                         symbol = 'O';
291                         break;
292                 case RACE_HALF_GIANT:
293                 case RACE_HALF_TITAN:
294                 case RACE_CYCLOPS:
295                         symbol = 'P';
296                         break;
297                 case RACE_YEEK:
298                         symbol = 'y';
299                         break;
300                 case RACE_KLACKON:
301                         symbol = 'K';
302                         break;
303                 case RACE_KOBOLD:
304                         symbol = 'k';
305                         break;
306                 case RACE_IMP:
307                         if (one_in_(13)) symbol = 'U';
308                         else symbol = 'u';
309                         break;
310                 case RACE_DRACONIAN:
311                         symbol = 'd';
312                         break;
313                 case RACE_GOLEM:
314                 case RACE_ANDROID:
315                         symbol = 'g';
316                         break;
317                 case RACE_SKELETON:
318                         if (one_in_(13)) symbol = 'L';
319                         else symbol = 's';
320                         break;
321                 case RACE_ZOMBIE:
322                         symbol = 'z';
323                         break;
324                 case RACE_VAMPIRE:
325                         symbol = 'V';
326                         break;
327                 case RACE_SPECTRE:
328                         symbol = 'G';
329                         break;
330                 case RACE_SPRITE:
331                         symbol = 'I';
332                         break;
333                 case RACE_ENT:
334                         symbol = '#';
335                         break;
336                 case RACE_ANGEL:
337                         symbol = 'A';
338                         break;
339                 case RACE_DEMON:
340                         symbol = 'U';
341                         break;
342                 default:
343                         symbol = 'p';
344                         break;
345                 }
346                 break;
347         case MIMIC_DEMON:
348                 if (one_in_(13)) symbol = 'U';
349                 else symbol = 'u';
350                 break;
351         case MIMIC_DEMON_LORD:
352                 symbol = 'U';
353                 break;
354         case MIMIC_VAMPIRE:
355                 symbol = 'V';
356                 break;
357         }
358         return summon_specific((pet ? -1 : 0), y, x, level, SUMMON_KIN, mode, symbol);
359 }
360
361 /*!
362  * @brief サイバーデーモンの召喚
363  * @param who 召喚主のモンスターID(0ならばプレイヤー)
364  * @param y 召喚位置Y座標
365  * @param x 召喚位置X座標
366  * @return 作用が実際にあった場合TRUEを返す
367  */
368 int summon_cyber(MONSTER_IDX who, POSITION y, POSITION x)
369 {
370         int i;
371         int max_cyber = (easy_band ? 1 : (current_floor_ptr->dun_level / 50) + randint1(2));
372         int count = 0;
373         BIT_FLAGS mode = PM_ALLOW_GROUP;
374
375         /* Summoned by a monster */
376         if (who > 0)
377         {
378                 monster_type *m_ptr = &current_floor_ptr->m_list[who];
379                 if (is_pet(m_ptr)) mode |= PM_FORCE_PET;
380         }
381
382         if (max_cyber > 4) max_cyber = 4;
383
384         for (i = 0; i < max_cyber; i++)
385         {
386                 count += summon_specific(who, y, x, 100, SUMMON_CYBER, mode, '\0');
387         }
388
389         return count;
390 }
391
392
393 void mitokohmon(void)
394 {
395         int count = 0, i;
396         monster_type *m_ptr;
397         concptr kakusan = "";
398
399         if (summon_named_creature(0, p_ptr->y, p_ptr->x, MON_SUKE, PM_FORCE_PET))
400         {
401                 msg_print(_("『助さん』が現れた。", "Suke-san apperars."));
402                 kakusan = "Suke-san";
403                 count++;
404         }
405         if (summon_named_creature(0, p_ptr->y, p_ptr->x, MON_KAKU, PM_FORCE_PET))
406         {
407                 msg_print(_("『格さん』が現れた。", "Kaku-san appears."));
408                 kakusan = "Kaku-san";
409                 count++;
410         }
411         if (!count)
412         {
413                 for (i = current_floor_ptr->m_max - 1; i > 0; i--)
414                 {
415                         m_ptr = &current_floor_ptr->m_list[i];
416                         if (!monster_is_valid(m_ptr)) continue;
417                         if (!((m_ptr->r_idx == MON_SUKE) || (m_ptr->r_idx == MON_KAKU))) continue;
418                         if (!los(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x)) continue;
419                         if (!projectable(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x)) continue;
420                         count++;
421                         break;
422                 }
423         }
424
425         if (count)
426         {
427                 msg_format(_("「者ども、ひかえおろう!!!このお方をどなたとこころえる。」",
428                         "%^s says 'WHO do you think this person is! Bow your head, down your knees!'"), kakusan);
429                 sukekaku = TRUE;
430                 stun_monsters(120);
431                 confuse_monsters(120);
432                 turn_monsters(120);
433                 stasis_monsters(120);
434                 sukekaku = FALSE;
435         }
436         else
437         {
438                 msg_print(_("しかし、何も起きなかった。", "Nothing happen."));
439         }
440 }