OSDN Git Service

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