OSDN Git Service

6ca2239a9137081d238cd5e82e76c05fba899fb6
[hengbandforosx/hengbandosx.git] / src / object-use / read-execution.c
1 /*!
2  * todo 長い、要分割
3  * @brief 巻物を読んだ際の効果処理
4  * @date 2020/07/23
5  * @author Hourier
6  */
7
8 #include "object-use/read-execution.h"
9 #include "action/action-limited.h"
10 #include "artifact/fixed-art-types.h"
11 #include "core/player-redraw-types.h"
12 #include "core/player-update-types.h"
13 #include "core/show-file.h"
14 #include "core/window-redrawer.h"
15 #include "flavor/flavor-describer.h"
16 #include "flavor/object-flavor-types.h"
17 #include "inventory/inventory-object.h"
18 #include "inventory/inventory-slot-types.h"
19 #include "io/files-util.h"
20 #include "main/sound-definitions-table.h"
21 #include "main/sound-of-music.h"
22 #include "monster-floor/monster-summon.h"
23 #include "monster-floor/place-monster-types.h"
24 #include "object/object-info.h"
25 #include "object/object-kind.h"
26 #include "perception/object-perception.h"
27 #include "player-info/avatar.h"
28 #include "player/attack-defense-types.h"
29 #include "player/digestion-processor.h"
30 #include "player/player-damage.h"
31 #include "player/player-status-flags.h"
32 #include "spell-kind/magic-item-recharger.h"
33 #include "spell-kind/spells-curse-removal.h"
34 #include "spell-kind/spells-detection.h"
35 #include "spell-kind/spells-enchant.h"
36 #include "spell-kind/spells-floor.h"
37 #include "spell-kind/spells-genocide.h"
38 #include "spell-kind/spells-grid.h"
39 #include "spell-kind/spells-launcher.h"
40 #include "spell-kind/spells-lite.h"
41 #include "spell-kind/spells-neighbor.h"
42 #include "spell-kind/spells-perception.h"
43 #include "spell-kind/spells-sight.h"
44 #include "spell-kind/spells-teleport.h"
45 #include "spell-kind/spells-world.h"
46 #include "spell-realm/spells-hex.h"
47 #include "spell/spell-types.h"
48 #include "spell/spells-object.h"
49 #include "spell/spells-summon.h"
50 #include "spell/summon-types.h"
51 #include "status/bad-status-setter.h"
52 #include "status/body-improvement.h"
53 #include "status/buff-setter.h"
54 #include "status/element-resistance.h"
55 #include "status/experience.h"
56 #include "store/rumor.h"
57 #include "sv-definition/sv-scroll-types.h"
58 #include "system/floor-type-definition.h"
59 #include "system/object-type-definition.h"
60 #include "term/screen-processor.h"
61 #include "util/angband-files.h"
62 #include "view/display-messages.h"
63
64 /*!
65  * @brief 巻物を読むコマンドのサブルーチン
66  * Read a scroll (from the pack or floor).
67  * @param creature_ptr プレーヤーへの参照ポインタ
68  * @param item 読むオブジェクトの所持品ID
69  * @param known 判明済ならばTRUE
70  * @return なし
71  * @details
72  * <pre>
73  * Certain scrolls can be "aborted" without losing the scroll.  These
74  * include scrolls with no effects but recharge or identify, which are
75  * cancelled before use.  XXX Reading them still takes a turn, though.
76  * </pre>
77  */
78 void exe_read(player_type *creature_ptr, INVENTORY_IDX item, bool known)
79 {
80     int k, used_up, ident, lev;
81     object_type *o_ptr;
82     o_ptr = ref_item(creature_ptr, item);
83     take_turn(creature_ptr, 100);
84     if (cmd_limit_time_walk(creature_ptr))
85         return;
86
87     if (creature_ptr->pclass == CLASS_BERSERKER) {
88         msg_print(_("巻物なんて読めない。", "You cannot read."));
89         return;
90     }
91
92     if (music_singing_any(creature_ptr))
93         stop_singing(creature_ptr);
94
95     if (hex_spelling_any(creature_ptr) && ((creature_ptr->lev < 35) || hex_spell_fully(creature_ptr)))
96         stop_hex_spell_all(creature_ptr);
97
98     ident = FALSE;
99     lev = k_info[o_ptr->k_idx].level;
100     used_up = TRUE;
101     if (o_ptr->tval == TV_SCROLL) {
102         switch (o_ptr->sval) {
103         case SV_SCROLL_DARKNESS: {
104             if (!has_resist_blind(creature_ptr) && !has_resist_dark(creature_ptr))
105                 (void)set_blind(creature_ptr, creature_ptr->blind + 3 + randint1(5));
106
107             if (unlite_area(creature_ptr, 10, 3))
108                 ident = TRUE;
109
110             break;
111         }
112         case SV_SCROLL_AGGRAVATE_MONSTER: {
113             msg_print(_("カン高くうなる様な音が辺りを覆った。", "There is a high pitched humming noise."));
114             aggravate_monsters(creature_ptr, 0);
115             ident = TRUE;
116             break;
117         }
118         case SV_SCROLL_CURSE_ARMOR: {
119             if (curse_armor(creature_ptr))
120                 ident = TRUE;
121
122             break;
123         }
124         case SV_SCROLL_CURSE_WEAPON: {
125             k = 0;
126             if (has_melee_weapon(creature_ptr, INVEN_MAIN_HAND)) {
127                 k = INVEN_MAIN_HAND;
128                 if (has_melee_weapon(creature_ptr, INVEN_SUB_HAND) && one_in_(2))
129                     k = INVEN_SUB_HAND;
130             } else if (has_melee_weapon(creature_ptr, INVEN_SUB_HAND))
131                 k = INVEN_SUB_HAND;
132
133             if (k && curse_weapon_object(creature_ptr, FALSE, &creature_ptr->inventory_list[k]))
134                 ident = TRUE;
135
136             break;
137         }
138         case SV_SCROLL_SUMMON_MONSTER: {
139             for (k = 0; k < randint1(3); k++) {
140                 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, 0,
141                         PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)) {
142                     ident = TRUE;
143                 }
144             }
145
146             break;
147         }
148         case SV_SCROLL_SUMMON_UNDEAD: {
149             for (k = 0; k < randint1(3); k++) {
150                 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_UNDEAD,
151                         PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)) {
152                     ident = TRUE;
153                 }
154             }
155
156             break;
157         }
158         case SV_SCROLL_SUMMON_PET: {
159             if (summon_specific(
160                     creature_ptr, -1, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, 0, PM_ALLOW_GROUP | PM_FORCE_PET))
161                 ident = TRUE;
162
163             break;
164         }
165         case SV_SCROLL_SUMMON_KIN: {
166             if (summon_kin_player(creature_ptr, creature_ptr->lev, creature_ptr->y, creature_ptr->x, PM_FORCE_PET | PM_ALLOW_GROUP))
167                 ident = TRUE;
168
169             break;
170         }
171         case SV_SCROLL_TRAP_CREATION: {
172             if (trap_creation(creature_ptr, creature_ptr->y, creature_ptr->x))
173                 ident = TRUE;
174
175             break;
176         }
177         case SV_SCROLL_PHASE_DOOR: {
178             teleport_player(creature_ptr, 10, TELEPORT_SPONTANEOUS);
179             ident = TRUE;
180             break;
181         }
182         case SV_SCROLL_TELEPORT: {
183             teleport_player(creature_ptr, 100, TELEPORT_SPONTANEOUS);
184             ident = TRUE;
185             break;
186         }
187         case SV_SCROLL_TELEPORT_LEVEL: {
188             (void)teleport_level(creature_ptr, 0);
189             ident = TRUE;
190             break;
191         }
192         case SV_SCROLL_WORD_OF_RECALL: {
193             if (!recall_player(creature_ptr, randint0(21) + 15))
194                 used_up = FALSE;
195
196             ident = TRUE;
197             break;
198         }
199         case SV_SCROLL_IDENTIFY: {
200             if (!ident_spell(creature_ptr, FALSE, 0))
201                 used_up = FALSE;
202
203             ident = TRUE;
204             break;
205         }
206         case SV_SCROLL_STAR_IDENTIFY: {
207             if (!identify_fully(creature_ptr, FALSE, 0))
208                 used_up = FALSE;
209
210             ident = TRUE;
211             break;
212         }
213         case SV_SCROLL_REMOVE_CURSE: {
214             if (remove_curse(creature_ptr))
215                 ident = TRUE;
216
217             break;
218         }
219         case SV_SCROLL_STAR_REMOVE_CURSE: {
220             if (remove_all_curse(creature_ptr))
221                 ident = TRUE;
222
223             break;
224         }
225         case SV_SCROLL_ENCHANT_ARMOR: {
226             ident = TRUE;
227             if (!enchant_spell(creature_ptr, 0, 0, 1))
228                 used_up = FALSE;
229
230             break;
231         }
232         case SV_SCROLL_ENCHANT_WEAPON_TO_HIT: {
233             if (!enchant_spell(creature_ptr, 1, 0, 0))
234                 used_up = FALSE;
235
236             ident = TRUE;
237             break;
238         }
239         case SV_SCROLL_ENCHANT_WEAPON_TO_DAM: {
240             if (!enchant_spell(creature_ptr, 0, 1, 0))
241                 used_up = FALSE;
242
243             ident = TRUE;
244             break;
245         }
246         case SV_SCROLL_STAR_ENCHANT_ARMOR: {
247             if (!enchant_spell(creature_ptr, 0, 0, randint1(3) + 2))
248                 used_up = FALSE;
249
250             ident = TRUE;
251             break;
252         }
253         case SV_SCROLL_STAR_ENCHANT_WEAPON: {
254             if (!enchant_spell(creature_ptr, randint1(3), randint1(3), 0))
255                 used_up = FALSE;
256
257             ident = TRUE;
258             break;
259         }
260         case SV_SCROLL_RECHARGING: {
261             if (!recharge(creature_ptr, 130))
262                 used_up = FALSE;
263
264             ident = TRUE;
265             break;
266         }
267         case SV_SCROLL_MUNDANITY: {
268             ident = TRUE;
269             if (!mundane_spell(creature_ptr, FALSE))
270                 used_up = FALSE;
271
272             break;
273         }
274         case SV_SCROLL_LIGHT: {
275             if (lite_area(creature_ptr, damroll(2, 8), 2))
276                 ident = TRUE;
277             break;
278         }
279
280         case SV_SCROLL_MAPPING: {
281             map_area(creature_ptr, DETECT_RAD_MAP);
282             ident = TRUE;
283             break;
284         }
285         case SV_SCROLL_DETECT_GOLD: {
286             if (detect_treasure(creature_ptr, DETECT_RAD_DEFAULT) || detect_objects_gold(creature_ptr, DETECT_RAD_DEFAULT))
287                 ident = TRUE;
288
289             break;
290         }
291         case SV_SCROLL_DETECT_ITEM: {
292             if (detect_objects_normal(creature_ptr, DETECT_RAD_DEFAULT))
293                 ident = TRUE;
294
295             break;
296         }
297         case SV_SCROLL_DETECT_TRAP: {
298             if (detect_traps(creature_ptr, DETECT_RAD_DEFAULT, known))
299                 ident = TRUE;
300
301             break;
302         }
303         case SV_SCROLL_DETECT_DOOR: {
304             if (detect_doors(creature_ptr, DETECT_RAD_DEFAULT) || detect_stairs(creature_ptr, DETECT_RAD_DEFAULT))
305                 ident = TRUE;
306
307             break;
308         }
309         case SV_SCROLL_DETECT_INVIS: {
310             if (detect_monsters_invis(creature_ptr, DETECT_RAD_DEFAULT))
311                 ident = TRUE;
312
313             break;
314         }
315         case SV_SCROLL_SATISFY_HUNGER: {
316             if (set_food(creature_ptr, PY_FOOD_MAX - 1))
317                 ident = TRUE;
318
319             break;
320         }
321         case SV_SCROLL_BLESSING: {
322             if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(12) + 6, FALSE))
323                 ident = TRUE;
324
325             break;
326         }
327         case SV_SCROLL_HOLY_CHANT: {
328             if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(24) + 12, FALSE))
329                 ident = TRUE;
330             break;
331         }
332
333         case SV_SCROLL_HOLY_PRAYER: {
334             if (set_blessed(creature_ptr, creature_ptr->blessed + randint1(48) + 24, FALSE))
335                 ident = TRUE;
336
337             break;
338         }
339         case SV_SCROLL_MONSTER_CONFUSION: {
340             if (!(creature_ptr->special_attack & ATTACK_CONFUSE)) {
341                 msg_print(_("手が輝き始めた。", "Your hands begin to glow."));
342                 creature_ptr->special_attack |= ATTACK_CONFUSE;
343                 creature_ptr->redraw |= PR_STATUS;
344                 ident = TRUE;
345             }
346
347             break;
348         }
349         case SV_SCROLL_PROTECTION_FROM_EVIL: {
350             k = 3 * creature_ptr->lev;
351             if (set_protevil(creature_ptr, creature_ptr->protevil + randint1(25) + k, FALSE))
352                 ident = TRUE;
353
354             break;
355         }
356         case SV_SCROLL_RUNE_OF_PROTECTION: {
357             create_rune_protection_one(creature_ptr);
358             ident = TRUE;
359             break;
360         }
361         case SV_SCROLL_TRAP_DOOR_DESTRUCTION: {
362             if (destroy_doors_touch(creature_ptr))
363                 ident = TRUE;
364
365             break;
366         }
367         case SV_SCROLL_STAR_DESTRUCTION: {
368             if (destroy_area(creature_ptr, creature_ptr->y, creature_ptr->x, 13 + randint0(5), FALSE))
369                 ident = TRUE;
370             else
371                 msg_print(_("ダンジョンが揺れた...", "The dungeon trembles..."));
372
373             break;
374         }
375         case SV_SCROLL_DISPEL_UNDEAD: {
376             if (dispel_undead(creature_ptr, 80))
377                 ident = TRUE;
378
379             break;
380         }
381         case SV_SCROLL_SPELL: {
382             if ((creature_ptr->pclass == CLASS_WARRIOR) || (creature_ptr->pclass == CLASS_IMITATOR) || (creature_ptr->pclass == CLASS_MINDCRAFTER)
383                 || (creature_ptr->pclass == CLASS_SORCERER) || (creature_ptr->pclass == CLASS_ARCHER) || (creature_ptr->pclass == CLASS_MAGIC_EATER)
384                 || (creature_ptr->pclass == CLASS_RED_MAGE) || (creature_ptr->pclass == CLASS_SAMURAI) || (creature_ptr->pclass == CLASS_BLUE_MAGE)
385                 || (creature_ptr->pclass == CLASS_CAVALRY) || (creature_ptr->pclass == CLASS_BERSERKER) || (creature_ptr->pclass == CLASS_SMITH)
386                 || (creature_ptr->pclass == CLASS_MIRROR_MASTER) || (creature_ptr->pclass == CLASS_NINJA) || (creature_ptr->pclass == CLASS_SNIPER))
387                 break;
388
389             creature_ptr->add_spells++;
390             creature_ptr->update |= PU_SPELLS;
391             ident = TRUE;
392             break;
393         }
394         case SV_SCROLL_GENOCIDE: {
395             (void)symbol_genocide(creature_ptr, 300, TRUE);
396             ident = TRUE;
397             break;
398         }
399         case SV_SCROLL_MASS_GENOCIDE: {
400             (void)mass_genocide(creature_ptr, 300, TRUE);
401             ident = TRUE;
402             break;
403         }
404         case SV_SCROLL_ACQUIREMENT: {
405             acquirement(creature_ptr, creature_ptr->y, creature_ptr->x, 1, TRUE, FALSE, FALSE);
406             ident = TRUE;
407             break;
408         }
409         case SV_SCROLL_STAR_ACQUIREMENT: {
410             acquirement(creature_ptr, creature_ptr->y, creature_ptr->x, randint1(2) + 1, TRUE, FALSE, FALSE);
411             ident = TRUE;
412             break;
413         }
414         case SV_SCROLL_FIRE: {
415             fire_ball(creature_ptr, GF_FIRE, 0, 666, 4);
416             if (!(is_oppose_fire(creature_ptr) || has_resist_fire(creature_ptr) || has_immune_fire(creature_ptr)))
417                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 50 + randint1(50), _("炎の巻物", "a Scroll of Fire"), -1);
418
419             ident = TRUE;
420             break;
421         }
422         case SV_SCROLL_ICE: {
423             fire_ball(creature_ptr, GF_ICE, 0, 777, 4);
424             if (!(is_oppose_cold(creature_ptr) || has_resist_cold(creature_ptr) || has_immune_cold(creature_ptr)))
425                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 100 + randint1(100), _("氷の巻物", "a Scroll of Ice"), -1);
426
427             ident = TRUE;
428             break;
429         }
430         case SV_SCROLL_CHAOS: {
431             fire_ball(creature_ptr, GF_CHAOS, 0, 1000, 4);
432             if (!has_resist_chaos(creature_ptr))
433                 take_hit(creature_ptr, DAMAGE_NOESCAPE, 111 + randint1(111), _("ログルスの巻物", "a Scroll of Logrus"), -1);
434
435             ident = TRUE;
436             break;
437         }
438         case SV_SCROLL_RUMOR: {
439             msg_print(_("巻物にはメッセージが書かれている:", "There is message on the scroll. It says:"));
440             msg_print(NULL);
441             display_rumor(creature_ptr, TRUE);
442             msg_print(NULL);
443             msg_print(_("巻物は煙を立てて消え去った!", "The scroll disappears in a puff of smoke!"));
444             ident = TRUE;
445             break;
446         }
447         case SV_SCROLL_ARTIFACT: {
448             ident = TRUE;
449             if (!artifact_scroll(creature_ptr))
450                 used_up = FALSE;
451
452             break;
453         }
454         case SV_SCROLL_RESET_RECALL: {
455             ident = TRUE;
456             if (!reset_recall(creature_ptr))
457                 used_up = FALSE;
458
459             break;
460         }
461         case SV_SCROLL_AMUSEMENT: {
462             ident = TRUE;
463             amusement(creature_ptr, creature_ptr->y, creature_ptr->x, 1, FALSE);
464             break;
465         }
466         case SV_SCROLL_STAR_AMUSEMENT: {
467             ident = TRUE;
468             amusement(creature_ptr, creature_ptr->y, creature_ptr->x, randint1(2) + 1, FALSE);
469             break;
470         }
471         }
472     } else if (o_ptr->name1 == ART_GHB) {
473         msg_print(_("私は苦労して『グレーター・ヘル=ビースト』を倒した。", "I had a very hard time to kill the Greater hell-beast, "));
474         msg_print(_("しかし手に入ったのはこのきたないTシャツだけだった。", "but all I got was this lousy t-shirt!"));
475         used_up = FALSE;
476     } else if (o_ptr->name1 == ART_POWER) {
477         msg_print(_("「一つの指輪は全てを統べ、", "'One Ring to rule them all, "));
478         msg_print(NULL);
479         msg_print(_("一つの指輪は全てを見つけ、", "One Ring to find them, "));
480         msg_print(NULL);
481         msg_print(_("一つの指輪は全てを捕らえて", "One Ring to bring them all "));
482         msg_print(NULL);
483         msg_print(_("暗闇の中に繋ぎとめる。」", "and in the darkness bind them.'"));
484         used_up = FALSE;
485     } else if (o_ptr->tval == TV_PARCHMENT) {
486         concptr q;
487         GAME_TEXT o_name[MAX_NLEN];
488         char buf[1024];
489         screen_save();
490         q = format("book-%d_jp.txt", o_ptr->sval);
491         describe_flavor(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
492         path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, q);
493         (void)show_file(creature_ptr, TRUE, buf, o_name, 0, 0);
494         screen_load();
495         used_up = FALSE;
496     }
497
498     BIT_FLAGS inventory_flags = PU_COMBINE | PU_REORDER | (creature_ptr->update & PU_AUTODESTROY);
499     creature_ptr->update &= ~(PU_COMBINE | PU_REORDER | PU_AUTODESTROY);
500
501     if (!(object_is_aware(o_ptr))) {
502         chg_virtue(creature_ptr, V_PATIENCE, -1);
503         chg_virtue(creature_ptr, V_CHANCE, 1);
504         chg_virtue(creature_ptr, V_KNOWLEDGE, -1);
505     }
506
507     object_tried(o_ptr);
508     if (ident && !object_is_aware(o_ptr)) {
509         object_aware(creature_ptr, o_ptr);
510         gain_exp(creature_ptr, (lev + (creature_ptr->lev >> 1)) / creature_ptr->lev);
511     }
512
513     creature_ptr->window_flags |= PW_INVEN | PW_EQUIP | PW_PLAYER;
514     creature_ptr->update |= inventory_flags;
515     if (!used_up)
516         return;
517
518     sound(SOUND_SCROLL);
519     vary_item(creature_ptr, item, -1);
520 }