OSDN Git Service

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