OSDN Git Service

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