OSDN Git Service

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