OSDN Git Service

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