OSDN Git Service

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