OSDN Git Service

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