OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / spell-kind / spells-enchant.c
1 #include "spell-kind/spells-enchant.h"
2 #include "artifact/random-art-generator.h"
3 #include "flavor/flavor-describer.h"
4 #include "flavor/object-flavor-types.h"
5 #include "floor/floor-object.h"
6 #include "game-option/disturbance-options.h"
7 #include "game-option/play-record-options.h"
8 #include "inventory/inventory-object.h"
9 #include "io/write-diary.h"
10 #include "object-hook/hook-enchant.h"
11 #include "object-hook/hook-perception.h"
12 #include "object-hook/hook-weapon.h"
13 #include "object/item-tester-hooker.h"
14 #include "object/item-use-flags.h"
15 #include "object/object-generator.h"
16 #include "player-info/avatar.h"
17 #include "racial/racial-android.h"
18 #include "term/screen-processor.h"
19 #include "view/display-messages.h"
20
21 /*!
22  * @brief アーティファクト生成の巻物処理 /
23  * @param caster_ptr プレーヤーへの参照ポインタ
24  * @return 生成が実際に試みられたらTRUEを返す
25  */
26 bool artifact_scroll(player_type *caster_ptr)
27 {
28     item_tester_hook = item_tester_hook_nameless_weapon_armour;
29
30     concptr q = _("どのアイテムを強化しますか? ", "Enchant which item? ");
31     concptr s = _("強化できるアイテムがない。", "You have nothing to enchant.");
32     object_type *o_ptr;
33     OBJECT_IDX item;
34     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
35     if (!o_ptr)
36         return FALSE;
37
38     GAME_TEXT o_name[MAX_NLEN];
39     describe_flavor(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
40 #ifdef JP
41     msg_format("%s は眩い光を発した!", o_name);
42 #else
43     msg_format("%s %s radiate%s a blinding light!", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "" : "s"));
44 #endif
45
46     bool okay = FALSE;
47     if (object_is_artifact(o_ptr)) {
48 #ifdef JP
49         msg_format("%sは既に伝説のアイテムです!", o_name);
50 #else
51         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "artifacts" : "an artifact"));
52 #endif
53         okay = FALSE;
54     } else if (object_is_ego(o_ptr)) {
55 #ifdef JP
56         msg_format("%sは既に名のあるアイテムです!", o_name);
57 #else
58         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "ego items" : "an ego item"));
59 #endif
60         okay = FALSE;
61     } else if (o_ptr->xtra3) {
62 #ifdef JP
63         msg_format("%sは既に強化されています!", o_name);
64 #else
65         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "customized items" : "a customized item"));
66 #endif
67     } else {
68         if (o_ptr->number > 1) {
69             msg_print(_("複数のアイテムに魔法をかけるだけのエネルギーはありません!", "Not enough energy to enchant more than one object!"));
70 #ifdef JP
71             msg_format("%d 個の%sが壊れた!", (o_ptr->number) - 1, o_name);
72 #else
73             msg_format("%d of your %s %s destroyed!", (o_ptr->number) - 1, o_name, (o_ptr->number > 2 ? "were" : "was"));
74 #endif
75
76             if (item >= 0) {
77                 inven_item_increase(caster_ptr, item, 1 - (o_ptr->number));
78             } else {
79                 floor_item_increase(caster_ptr->current_floor_ptr, 0 - item, 1 - (o_ptr->number));
80             }
81         }
82
83         okay = become_random_artifact(caster_ptr, o_ptr, TRUE);
84     }
85
86     if (!okay) {
87         if (flush_failure)
88             flush();
89
90         msg_print(_("強化に失敗した。", "The enchantment failed."));
91         if (one_in_(3))
92             chg_virtue(caster_ptr, V_ENCHANT, -1);
93
94         calc_android_exp(caster_ptr);
95         return TRUE;
96     }
97
98     if (record_rand_art) {
99         describe_flavor(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
100         exe_write_diary(caster_ptr, DIARY_ART_SCROLL, 0, o_name);
101     }
102
103     chg_virtue(caster_ptr, V_ENCHANT, 1);
104     calc_android_exp(caster_ptr);
105     return TRUE;
106 }
107
108 /*!
109  * @brief アイテム凡庸化のメインルーチン処理 /
110  * Identify an object in the inventory (or on the floor)
111  * @param owner_ptr プレーヤーへの参照ポインタ
112  * @param only_equip 装備品のみを対象とするならばTRUEを返す
113  * @return 実際に凡庸化をを行ったならばTRUEを返す
114  * @details
115  * <pre>
116  * Mundanify an object in the inventory (or on the floor)
117  * This routine does *not* automatically combine objects.
118  * Returns TRUE if something was mundanified, else FALSE.
119  * </pre>
120  */
121 bool mundane_spell(player_type *owner_ptr, bool only_equip)
122 {
123     if (only_equip)
124         item_tester_hook = object_is_weapon_armour_ammo;
125
126     OBJECT_IDX item;
127     object_type *o_ptr;
128     concptr q = _("どれを使いますか?", "Use which item? ");
129     concptr s = _("使えるものがありません。", "You have nothing you can use.");
130
131     o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
132     if (!o_ptr)
133         return FALSE;
134
135     msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
136     POSITION iy = o_ptr->iy;
137     POSITION ix = o_ptr->ix;
138     OBJECT_IDX next_o_idx = o_ptr->next_o_idx;
139     byte marked = o_ptr->marked;
140     WEIGHT weight = o_ptr->number * o_ptr->weight;
141     u16b inscription = o_ptr->inscription;
142
143     object_prep(owner_ptr, o_ptr, o_ptr->k_idx);
144
145     o_ptr->iy = iy;
146     o_ptr->ix = ix;
147     o_ptr->next_o_idx = next_o_idx;
148     o_ptr->marked = marked;
149     o_ptr->inscription = inscription;
150     if (item >= 0)
151         owner_ptr->total_weight += (o_ptr->weight - weight);
152
153     calc_android_exp(owner_ptr);
154     return TRUE;
155 }