OSDN Git Service

[Refactor] #38997 detect_*() にplayer_type * 引数を追加 / Added player_type * argument...
[hengband/hengband.git] / src / cmd / cmd-read.c
1 /*!
2  * @file cmd-read.c
3  * @brief プレイヤーの読むコマンド実装
4  * @date 2018/09/07
5  * @details
6  * cmd6.cより分離。
7  */
8
9 #include "angband.h"
10 #include "util.h"
11
12 #include "object-flavor.h"
13 #include "object-hook.h"
14 #include "artifact.h"
15 #include "avatar.h"
16 #include "player-status.h"
17 #include "player-damage.h"
18 #include "player-class.h"
19 #include "player-effects.h"
20 #include "player-inventory.h"
21 #include "rumor.h"
22 #include "realm-hex.h"
23
24 #include "spells.h"
25 #include "spells-object.h"
26 #include "spells-floor.h"
27 #include "spells-summon.h"
28 #include "spells-status.h"
29
30 #include "cmd-basic.h"
31 #include "files.h"
32 #include "floor.h"
33 #include "objectkind.h"
34 #include "realm-song.h"
35 #include "view-mainwindow.h"
36
37 /*!
38  * @brief 巻物を読むコマンドのサブルーチン
39  * Read a scroll (from the pack or floor).
40  * @param creature_ptr プレーヤーへの参照ポインタ
41  * @param item 読むオブジェクトの所持品ID
42  * @param known 判明済ならばTRUE
43  * @return なし
44  * @details
45  * <pre>
46  * Certain scrolls can be "aborted" without losing the scroll.  These
47  * include scrolls with no effects but recharge or identify, which are
48  * cancelled before use.  XXX Reading them still takes a turn, though.
49  * </pre>
50  */
51 void exe_read(player_type *creature_ptr, INVENTORY_IDX item, bool known)
52 {
53         int k, used_up, ident, lev;
54         object_type *o_ptr;
55
56         o_ptr = REF_ITEM(creature_ptr, creature_ptr->current_floor_ptr, item);
57
58         take_turn(creature_ptr, 100);
59         if (cmd_limit_time_walk(creature_ptr)) return;
60
61         if (creature_ptr->pclass == CLASS_BERSERKER)
62         {
63                 msg_print(_("巻物なんて読めない。", "You cannot read."));
64                 return;
65         }
66
67         if (music_singing_any(creature_ptr)) stop_singing(creature_ptr);
68         if (hex_spelling_any(creature_ptr) && ((creature_ptr->lev < 35) || hex_spell_fully(creature_ptr))) stop_hex_spell_all(creature_ptr);
69
70         /* Not identified yet */
71         ident = FALSE;
72
73         /* Object level */
74         lev = k_info[o_ptr->k_idx].level;
75
76         /* Assume the scroll will get used up */
77         used_up = TRUE;
78
79         if (o_ptr->tval == TV_SCROLL)
80         {
81         /* Analyze the scroll */
82         switch (o_ptr->sval)
83         {
84                 case SV_SCROLL_DARKNESS:
85                 {
86                         if (!(creature_ptr->resist_blind) && !(creature_ptr->resist_dark))
87                         {
88                                 (void)set_blind(creature_ptr, creature_ptr->blind + 3 + randint1(5));
89                         }
90                         if (unlite_area(10, 3)) ident = TRUE;
91                         break;
92                 }
93
94                 case SV_SCROLL_AGGRAVATE_MONSTER:
95                 {
96                         msg_print(_("カン高くうなる様な音が辺りを覆った。", "There is a high pitched humming noise."));
97                         aggravate_monsters(0);
98                         ident = TRUE;
99                         break;
100                 }
101
102                 case SV_SCROLL_CURSE_ARMOR:
103                 {
104                         if (curse_armor(creature_ptr)) ident = TRUE;
105                         break;
106                 }
107
108                 case SV_SCROLL_CURSE_WEAPON:
109                 {
110                         k = 0;
111                         if (has_melee_weapon(creature_ptr, INVEN_RARM))
112                         {
113                                 k = INVEN_RARM;
114                                 if (has_melee_weapon(creature_ptr, INVEN_LARM) && one_in_(2)) k = INVEN_LARM;
115                         }
116                         else if (has_melee_weapon(creature_ptr, INVEN_LARM)) k = INVEN_LARM;
117                         if (k && curse_weapon_object(creature_ptr, FALSE, &creature_ptr->inventory_list[k])) ident = TRUE;
118                         break;
119                 }
120
121                 case SV_SCROLL_SUMMON_MONSTER:
122                 {
123                         for (k = 0; k < randint1(3); k++)
124                         {
125                                 if (summon_specific(0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)))
126                                 {
127                                         ident = TRUE;
128                                 }
129                         }
130                         break;
131                 }
132
133                 case SV_SCROLL_SUMMON_UNDEAD:
134                 {
135                         for (k = 0; k < randint1(3); k++)
136                         {
137                                 if (summon_specific(0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_UNDEAD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)))
138                                 {
139                                         ident = TRUE;
140                                 }
141                         }
142                         break;
143                 }
144
145                 case SV_SCROLL_SUMMON_PET:
146                 {
147                         if (summon_specific(-1, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, 0, (PM_ALLOW_GROUP | PM_FORCE_PET)))
148                         {
149                                 ident = TRUE;
150                         }
151                         break;
152                 }
153
154                 case SV_SCROLL_SUMMON_KIN:
155                 {
156                         if (summon_kin_player(creature_ptr->lev, creature_ptr->y, creature_ptr->x, (PM_FORCE_PET | PM_ALLOW_GROUP)))
157                         {
158                                 ident = TRUE;
159                         }
160                         break;
161                 }
162
163                 case SV_SCROLL_TRAP_CREATION:
164                 {
165                         if (trap_creation(creature_ptr, creature_ptr->y, creature_ptr->x)) ident = TRUE;
166                         break;
167                 }
168
169                 case SV_SCROLL_PHASE_DOOR:
170                 {
171                         teleport_player(creature_ptr, 10, 0L);
172                         ident = TRUE;
173                         break;
174                 }
175
176                 case SV_SCROLL_TELEPORT:
177                 {
178                         teleport_player(creature_ptr, 100, 0L);
179                         ident = TRUE;
180                         break;
181                 }
182
183                 case SV_SCROLL_TELEPORT_LEVEL:
184                 {
185                         (void)teleport_level(creature_ptr, 0);
186                         ident = TRUE;
187                         break;
188                 }
189
190                 case SV_SCROLL_WORD_OF_RECALL:
191                 {
192                         if (!recall_player(creature_ptr, randint0(21) + 15)) used_up = FALSE;
193                         ident = TRUE;
194                         break;
195                 }
196
197                 case SV_SCROLL_IDENTIFY:
198                 {
199                         if (!ident_spell(creature_ptr, FALSE)) used_up = FALSE;
200                         ident = TRUE;
201                         break;
202                 }
203
204                 case SV_SCROLL_STAR_IDENTIFY:
205                 {
206                         if (!identify_fully(FALSE)) used_up = FALSE;
207                         ident = TRUE;
208                         break;
209                 }
210
211                 case SV_SCROLL_REMOVE_CURSE:
212                 {
213                         if (remove_curse(creature_ptr))
214                         {
215                                 ident = TRUE;
216                         }
217                         break;
218                 }
219
220                 case SV_SCROLL_STAR_REMOVE_CURSE:
221                 {
222                         if (remove_all_curse(creature_ptr))
223                         {
224                                 ident = TRUE;
225                         }
226                         break;
227                 }
228
229                 case SV_SCROLL_ENCHANT_ARMOR:
230                 {
231                         ident = TRUE;
232                         if (!enchant_spell(creature_ptr, 0, 0, 1)) used_up = FALSE;
233                         break;
234                 }
235
236                 case SV_SCROLL_ENCHANT_WEAPON_TO_HIT:
237                 {
238                         if (!enchant_spell(creature_ptr, 1, 0, 0)) used_up = FALSE;
239                         ident = TRUE;
240                         break;
241                 }
242
243                 case SV_SCROLL_ENCHANT_WEAPON_TO_DAM:
244                 {
245                         if (!enchant_spell(creature_ptr, 0, 1, 0)) used_up = FALSE;
246                         ident = TRUE;
247                         break;
248                 }
249
250                 case SV_SCROLL_STAR_ENCHANT_ARMOR:
251                 {
252                         if (!enchant_spell(creature_ptr, 0, 0, randint1(3) + 2)) used_up = FALSE;
253                         ident = TRUE;
254                         break;
255                 }
256
257                 case SV_SCROLL_STAR_ENCHANT_WEAPON:
258                 {
259                         if (!enchant_spell(creature_ptr, randint1(3), randint1(3), 0)) used_up = FALSE;
260                         ident = TRUE;
261                         break;
262                 }
263
264                 case SV_SCROLL_RECHARGING:
265                 {
266                         if (!recharge(creature_ptr, 130)) used_up = FALSE;
267                         ident = TRUE;
268                         break;
269                 }
270
271                 case SV_SCROLL_MUNDANITY:
272                 {
273                         ident = TRUE;
274                         if (!mundane_spell(creature_ptr, FALSE)) used_up = FALSE;
275                         break;
276                 }
277
278                 case SV_SCROLL_LIGHT:
279                 {
280                         if (lite_area(damroll(2, 8), 2)) ident = TRUE;
281                         break;
282                 }
283
284                 case SV_SCROLL_MAPPING:
285                 {
286                         map_area(creature_ptr, DETECT_RAD_MAP);
287                         ident = TRUE;
288                         break;
289                 }
290
291                 case SV_SCROLL_DETECT_GOLD:
292                 {
293                         if (detect_treasure(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
294                         if (detect_objects_gold(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
295                         break;
296                 }
297
298                 case SV_SCROLL_DETECT_ITEM:
299                 {
300                         if (detect_objects_normal(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
301                         break;
302                 }
303
304                 case SV_SCROLL_DETECT_TRAP:
305                 {
306                         if (detect_traps(creature_ptr, DETECT_RAD_DEFAULT, known)) ident = TRUE;
307                         break;
308                 }
309
310                 case SV_SCROLL_DETECT_DOOR:
311                 {
312                         if (detect_doors(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
313                         if (detect_stairs(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
314                         break;
315                 }
316
317                 case SV_SCROLL_DETECT_INVIS:
318                 {
319                         if (detect_monsters_invis(creature_ptr, DETECT_RAD_DEFAULT)) ident = TRUE;
320                         break;
321                 }
322
323                 case SV_SCROLL_SATISFY_HUNGER:
324                 {
325                         if (set_food(creature_ptr, PY_FOOD_MAX - 1)) ident = TRUE;
326                         break;
327                 }
328
329                 case SV_SCROLL_BLESSING:
330                 {
331                         if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(12) + 6, FALSE)) ident = TRUE;
332                         break;
333                 }
334
335                 case SV_SCROLL_HOLY_CHANT:
336                 {
337                         if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(24) + 12, FALSE)) ident = TRUE;
338                         break;
339                 }
340
341                 case SV_SCROLL_HOLY_PRAYER:
342                 {
343                         if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(48) + 24, FALSE)) ident = TRUE;
344                         break;
345                 }
346
347                 case SV_SCROLL_MONSTER_CONFUSION:
348                 {
349                         if (!(creature_ptr->special_attack & ATTACK_CONFUSE))
350                         {
351                                 msg_print(_("手が輝き始めた。", "Your hands begin to glow."));
352                                 creature_ptr->special_attack |= ATTACK_CONFUSE;
353                                 creature_ptr->redraw |= (PR_STATUS);
354                                 ident = TRUE;
355                         }
356                         break;
357                 }
358
359                 case SV_SCROLL_PROTECTION_FROM_EVIL:
360                 {
361                         k = 3 * creature_ptr->lev;
362                         if (set_protevil(creature_ptr, creature_ptr->protevil + randint1(25) + k, FALSE)) ident = TRUE;
363                         break;
364                 }
365
366                 case SV_SCROLL_RUNE_OF_PROTECTION:
367                 {
368                         warding_glyph(creature_ptr);
369                         ident = TRUE;
370                         break;
371                 }
372
373                 case SV_SCROLL_TRAP_DOOR_DESTRUCTION:
374                 {
375                         if (destroy_doors_touch()) ident = TRUE;
376                         break;
377                 }
378
379                 case SV_SCROLL_STAR_DESTRUCTION:
380                 {
381                         if (destroy_area(creature_ptr->current_floor_ptr, creature_ptr->y, creature_ptr->x, 13 + randint0(5), FALSE))
382                                 ident = TRUE;
383                         else
384                                 msg_print(_("ダンジョンが揺れた...", "The dungeon trembles..."));
385
386                         break;
387                 }
388
389                 case SV_SCROLL_DISPEL_UNDEAD:
390                 {
391                         if (dispel_undead(80)) ident = TRUE;
392                         break;
393                 }
394
395                 case SV_SCROLL_SPELL:
396                 {
397                         if ((creature_ptr->pclass == CLASS_WARRIOR) ||
398                                 (creature_ptr->pclass == CLASS_IMITATOR) ||
399                                 (creature_ptr->pclass == CLASS_MINDCRAFTER) ||
400                                 (creature_ptr->pclass == CLASS_SORCERER) ||
401                                 (creature_ptr->pclass == CLASS_ARCHER) ||
402                                 (creature_ptr->pclass == CLASS_MAGIC_EATER) ||
403                                 (creature_ptr->pclass == CLASS_RED_MAGE) ||
404                                 (creature_ptr->pclass == CLASS_SAMURAI) ||
405                                 (creature_ptr->pclass == CLASS_BLUE_MAGE) ||
406                                 (creature_ptr->pclass == CLASS_CAVALRY) ||
407                                 (creature_ptr->pclass == CLASS_BERSERKER) ||
408                                 (creature_ptr->pclass == CLASS_SMITH) ||
409                                 (creature_ptr->pclass == CLASS_MIRROR_MASTER) ||
410                                 (creature_ptr->pclass == CLASS_NINJA) ||
411                                 (creature_ptr->pclass == CLASS_SNIPER)) break;
412                         creature_ptr->add_spells++;
413                         creature_ptr->update |= (PU_SPELLS);
414                         ident = TRUE;
415                         break;
416                 }
417
418                 case SV_SCROLL_GENOCIDE:
419                 {
420                         (void)symbol_genocide(creature_ptr, 300, TRUE);
421                         ident = TRUE;
422                         break;
423                 }
424
425                 case SV_SCROLL_MASS_GENOCIDE:
426                 {
427                         (void)mass_genocide(creature_ptr, 300, TRUE);
428                         ident = TRUE;
429                         break;
430                 }
431
432                 case SV_SCROLL_ACQUIREMENT:
433                 {
434                         acquirement(creature_ptr->y, creature_ptr->x, 1, TRUE, FALSE, FALSE);
435                         ident = TRUE;
436                         break;
437                 }
438
439                 case SV_SCROLL_STAR_ACQUIREMENT:
440                 {
441                         acquirement(creature_ptr->y, creature_ptr->x, randint1(2) + 1, TRUE, FALSE, FALSE);
442                         ident = TRUE;
443                         break;
444                 }
445
446                 /* New Hengband scrolls */
447                 case SV_SCROLL_FIRE:
448                 {
449                         fire_ball(creature_ptr, GF_FIRE, 0, 666, 4);
450                         /* Note: "Double" damage since it is centered on the player ... */
451                         if (!(IS_OPPOSE_FIRE() || creature_ptr->resist_fire || creature_ptr->immune_fire))
452                                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 50+randint1(50), _("炎の巻物", "a Scroll of Fire"), -1);
453
454                         ident = TRUE;
455                         break;
456                 }
457
458
459                 case SV_SCROLL_ICE:
460                 {
461                         fire_ball(creature_ptr, GF_ICE, 0, 777, 4);
462                         if (!(IS_OPPOSE_COLD() || creature_ptr->resist_cold || creature_ptr->immune_cold))
463                                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 100+randint1(100), _("氷の巻物", "a Scroll of Ice"), -1);
464
465                         ident = TRUE;
466                         break;
467                 }
468
469                 case SV_SCROLL_CHAOS:
470                 {
471                         fire_ball(creature_ptr, GF_CHAOS, 0, 1000, 4);
472                         if (!creature_ptr->resist_chaos)
473                                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 111+randint1(111), _("ログルスの巻物", "a Scroll of Logrus"), -1);
474
475                         ident = TRUE;
476                         break;
477                 }
478
479                 case SV_SCROLL_RUMOR:
480                 {
481                         msg_print(_("巻物にはメッセージが書かれている:", "There is message on the scroll. It says:"));
482                         msg_print(NULL);
483                         display_rumor(TRUE);
484                         msg_print(NULL);
485                         msg_print(_("巻物は煙を立てて消え去った!", "The scroll disappears in a puff of smoke!"));
486
487                         ident = TRUE;
488                         break;
489                 }
490
491                 case SV_SCROLL_ARTIFACT:
492                 {
493                         ident = TRUE;
494                         if (!artifact_scroll()) used_up = FALSE;
495                         break;
496                 }
497
498                 case SV_SCROLL_RESET_RECALL:
499                 {
500                         ident = TRUE;
501                         if (!reset_recall()) used_up = FALSE;
502                         break;
503                 }
504
505                 case SV_SCROLL_AMUSEMENT:
506                 {
507                         ident = TRUE;
508                         amusement(creature_ptr->y, creature_ptr->x, 1, FALSE);
509                         break;
510                 }
511
512                 case SV_SCROLL_STAR_AMUSEMENT:
513                 {
514                         ident = TRUE;
515                         amusement(creature_ptr->y, creature_ptr->x,  randint1(2) + 1, FALSE);
516                         break;
517                 }
518         }
519         }
520         else if (o_ptr->name1 == ART_GHB)
521         {
522                 msg_print(_("私は苦労して『グレーター・ヘル=ビースト』を倒した。", "I had a very hard time to kill the Greater hell-beast, "));
523                 msg_print(_("しかし手に入ったのはこのきたないTシャツだけだった。", "but all I got was this lousy t-shirt!"));
524                 used_up = FALSE;
525         }
526         else if (o_ptr->name1 == ART_POWER)
527         {
528                 msg_print(_("「一つの指輪は全てを統べ、", "'One Ring to rule them all, "));
529                 msg_print(NULL);
530                 msg_print(_("一つの指輪は全てを見つけ、", "One Ring to find them, "));
531                 msg_print(NULL);
532                 msg_print(_("一つの指輪は全てを捕らえて", "One Ring to bring them all "));
533                 msg_print(NULL);
534                 msg_print(_("暗闇の中に繋ぎとめる。」", "and in the darkness bind them.'"));
535                 used_up = FALSE;
536         }
537         else if (o_ptr->tval==TV_PARCHMENT)
538         {
539                 concptr q;
540                 GAME_TEXT o_name[MAX_NLEN];
541                 char buf[1024];
542                 screen_save();
543
544                 q=format("book-%d_jp.txt",o_ptr->sval);
545
546                 /* Display object description */
547                 object_desc(o_name, o_ptr, OD_NAME_ONLY);
548                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, q);
549
550                 /* Peruse the help file */
551                 (void)show_file(TRUE, buf, o_name, 0, 0);
552                 screen_load();
553
554                 used_up=FALSE;
555         }
556
557         creature_ptr->update |= (PU_COMBINE | PU_REORDER);
558
559         if (!(object_is_aware(o_ptr)))
560         {
561                 chg_virtue(creature_ptr, V_PATIENCE, -1);
562                 chg_virtue(creature_ptr, V_CHANCE, 1);
563                 chg_virtue(creature_ptr, V_KNOWLEDGE, -1);
564         }
565
566         /* The item was tried */
567         object_tried(o_ptr);
568
569         /* An identification was made */
570         if (ident && !object_is_aware(o_ptr))
571         {
572                 object_aware(o_ptr);
573                 gain_exp(creature_ptr, (lev + (creature_ptr->lev >> 1)) / creature_ptr->lev);
574         }
575
576         creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
577
578
579         /* Hack -- allow certain scrolls to be "preserved" */
580         if (!used_up)
581         {
582                 return;
583         }
584
585         sound(SOUND_SCROLL);
586         vary_item(item, -1);
587 }
588
589 /*!
590  * @brief 読むコマンドのメインルーチン /
591  * Eat some food (from the pack or floor)
592  * @return なし
593  */
594 void do_cmd_read_scroll(player_type *creature_ptr)
595 {
596         object_type *o_ptr;
597         OBJECT_IDX item;
598         concptr q, s;
599
600         if (creature_ptr->wild_mode)
601         {
602                 return;
603         }
604
605         if (cmd_limit_arena(creature_ptr)) return;
606
607         if (creature_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
608         {
609                 set_action(creature_ptr, ACTION_NONE);
610         }
611
612         if (cmd_limit_blind(creature_ptr)) return;
613         if (cmd_limit_confused(creature_ptr)) return;
614
615         /* Restrict choices to scrolls */
616         item_tester_hook = item_tester_hook_readable;
617
618         q = _("どの巻物を読みますか? ", "Read which scroll? ");
619         s = _("読める巻物がない。", "You have no scrolls to read.");
620
621         o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
622         if (!o_ptr) return;
623
624         /* Read the scroll */
625         exe_read(creature_ptr, item, object_is_aware(o_ptr));
626 }