OSDN Git Service

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