OSDN Git Service

[Refactor] #37353 コメント整理。 / Refactor comments.
[hengband/hengband.git] / src / spells-object.c
1 
2 #include "angband.h"
3 #include "spells-object.h"
4 #include "object-hook.h"
5
6 /*!
7  * @brief「弾/矢の製造」処理 / do_cmd_cast calls this function if the player's class is 'archer'.
8  * Hook to determine if an object is contertible in an arrow/bolt
9  * @return 製造を実際に行ったらTRUE、キャンセルしたらFALSEを返す
10  */
11 bool create_ammo(void)
12 {
13         int ext = 0;
14         char ch;
15
16         object_type     forge;
17         object_type *q_ptr;
18
19         char com[80];
20         GAME_TEXT o_name[MAX_NLEN];
21
22         q_ptr = &forge;
23
24         if (p_ptr->lev >= 20)
25                 sprintf(com, _("[S]弾, [A]矢, [B]クロスボウの矢 :", "Create [S]hots, Create [A]rrow or Create [B]olt ?"));
26         else if (p_ptr->lev >= 10)
27                 sprintf(com, _("[S]弾, [A]矢:", "Create [S]hots or Create [A]rrow ?"));
28         else
29                 sprintf(com, _("[S]弾:", "Create [S]hots ?"));
30
31         if (p_ptr->confused)
32         {
33                 msg_print(_("混乱してる!", "You are too confused!"));
34                 return FALSE;
35         }
36
37         if (p_ptr->blind)
38         {
39                 msg_print(_("目が見えない!", "You are blind!"));
40                 return FALSE;
41         }
42
43         while (TRUE)
44         {
45                 if (!get_com(com, &ch, TRUE))
46                 {
47                         return FALSE;
48                 }
49                 if (ch == 'S' || ch == 's')
50                 {
51                         ext = 1;
52                         break;
53                 }
54                 if ((ch == 'A' || ch == 'a') && (p_ptr->lev >= 10))
55                 {
56                         ext = 2;
57                         break;
58                 }
59                 if ((ch == 'B' || ch == 'b') && (p_ptr->lev >= 20))
60                 {
61                         ext = 3;
62                         break;
63                 }
64         }
65
66         /**********Create shots*********/
67         if (ext == 1)
68         {
69                 POSITION x, y;
70                 DIRECTION dir;
71                 cave_type *c_ptr;
72
73                 if (!get_rep_dir(&dir, FALSE)) return FALSE;
74                 y = p_ptr->y + ddy[dir];
75                 x = p_ptr->x + ddx[dir];
76                 c_ptr = &cave[y][x];
77
78                 if (!have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_CAN_DIG))
79                 {
80                         msg_print(_("そこには岩石がない。", "You need pile of rubble."));
81                         return FALSE;
82                 }
83                 else if (!cave_have_flag_grid(c_ptr, FF_CAN_DIG) || !cave_have_flag_grid(c_ptr, FF_HURT_ROCK))
84                 {
85                         msg_print(_("硬すぎて崩せなかった。", "You failed to make ammo."));
86                 }
87                 else
88                 {
89                         s16b slot;
90                         q_ptr = &forge;
91
92                         /* Hack -- Give the player some small firestones */
93                         object_prep(q_ptr, lookup_kind(TV_SHOT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
94                         q_ptr->number = (byte)rand_range(15, 30);
95                         object_aware(q_ptr);
96                         object_known(q_ptr);
97                         apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
98                         q_ptr->discount = 99;
99
100                         slot = inven_carry(q_ptr);
101
102                         object_desc(o_name, q_ptr, 0);
103                         msg_format(_("%sを作った。", "You make some ammo."), o_name);
104
105                         /* Auto-inscription */
106                         if (slot >= 0) autopick_alter_item(slot, FALSE);
107
108                         /* Destroy the wall */
109                         cave_alter_feat(y, x, FF_HURT_ROCK);
110
111                         p_ptr->update |= (PU_FLOW);
112                 }
113         }
114         /**********Create arrows*********/
115         else if (ext == 2)
116         {
117                 OBJECT_IDX item;
118                 concptr q, s;
119                 s16b slot;
120
121                 item_tester_hook = item_tester_hook_convertible;
122
123                 q = _("どのアイテムから作りますか? ", "Convert which item? ");
124                 s = _("材料を持っていない。", "You have no item to convert.");
125                 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
126                 if (!q_ptr) return FALSE;
127
128                 q_ptr = &forge;
129
130                 /* Hack -- Give the player some small firestones */
131                 object_prep(q_ptr, lookup_kind(TV_ARROW, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
132                 q_ptr->number = (byte)rand_range(5, 10);
133                 object_aware(q_ptr);
134                 object_known(q_ptr);
135                 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
136
137                 q_ptr->discount = 99;
138
139                 object_desc(o_name, q_ptr, 0);
140                 msg_format(_("%sを作った。", "You make some ammo."), o_name);
141
142                 if (item >= 0)
143                 {
144                         inven_item_increase(item, -1);
145                         inven_item_describe(item);
146                         inven_item_optimize(item);
147                 }
148                 else
149                 {
150                         floor_item_increase(0 - item, -1);
151                         floor_item_describe(0 - item);
152                         floor_item_optimize(0 - item);
153                 }
154
155                 slot = inven_carry(q_ptr);
156
157                 /* Auto-inscription */
158                 if (slot >= 0) autopick_alter_item(slot, FALSE);
159         }
160         /**********Create bolts*********/
161         else if (ext == 3)
162         {
163                 OBJECT_IDX item;
164                 concptr q, s;
165                 s16b slot;
166
167                 item_tester_hook = item_tester_hook_convertible;
168
169                 q = _("どのアイテムから作りますか? ", "Convert which item? ");
170                 s = _("材料を持っていない。", "You have no item to convert.");
171
172                 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
173                 if (!q_ptr) return FALSE;
174
175                 q_ptr = &forge;
176
177                 /* Hack -- Give the player some small firestones */
178                 object_prep(q_ptr, lookup_kind(TV_BOLT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
179                 q_ptr->number = (byte)rand_range(4, 8);
180                 object_aware(q_ptr);
181                 object_known(q_ptr);
182                 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
183
184                 q_ptr->discount = 99;
185
186                 object_desc(o_name, q_ptr, 0);
187                 msg_format(_("%sを作った。", "You make some ammo."), o_name);
188
189                 if (item >= 0)
190                 {
191                         inven_item_increase(item, -1);
192                         inven_item_describe(item);
193                         inven_item_optimize(item);
194                 }
195                 else
196                 {
197                         floor_item_increase(0 - item, -1);
198                         floor_item_describe(0 - item);
199                         floor_item_optimize(0 - item);
200                 }
201
202                 slot = inven_carry(q_ptr);
203
204                 /* Auto-inscription */
205                 if (slot >= 0) autopick_alter_item(slot, FALSE);
206         }
207         return TRUE;
208 }
209
210 /*!
211  * @brief 魔道具術師の魔力取り込み処理
212  * @return 取り込みを実行したらTRUE、キャンセルしたらFALSEを返す
213  */
214 bool import_magic_device(void)
215 {
216         OBJECT_IDX item;
217         PARAMETER_VALUE pval;
218         int ext = 0;
219         concptr q, s;
220         object_type *o_ptr;
221         GAME_TEXT o_name[MAX_NLEN];
222
223         /* Only accept legal items */
224         item_tester_hook = item_tester_hook_recharge;
225
226         q = _("どのアイテムの魔力を取り込みますか? ", "Gain power of which item? ");
227         s = _("魔力を取り込めるアイテムがない。", "You have nothing to gain power.");
228
229         o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
230         if (!o_ptr) return (FALSE);
231
232         if (o_ptr->tval == TV_STAFF && o_ptr->sval == SV_STAFF_NOTHING)
233         {
234                 msg_print(_("この杖には発動の為の能力は何も備わっていないようだ。", "This staff doesn't have any magical ability."));
235                 return FALSE;
236         }
237
238         if (!object_is_known(o_ptr))
239         {
240                 msg_print(_("鑑定されていないと取り込めない。", "You need to identify before absorbing."));
241                 return FALSE;
242         }
243
244         if (o_ptr->timeout)
245         {
246                 msg_print(_("充填中のアイテムは取り込めない。", "This item is still charging."));
247                 return FALSE;
248         }
249
250         pval = o_ptr->pval;
251         if (o_ptr->tval == TV_ROD)
252                 ext = 72;
253         else if (o_ptr->tval == TV_WAND)
254                 ext = 36;
255
256         if (o_ptr->tval == TV_ROD)
257         {
258                 p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)o_ptr->number;
259                 if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
260         }
261         else
262         {
263                 int num;
264                 for (num = o_ptr->number; num; num--)
265                 {
266                         int gain_num = pval;
267                         if (o_ptr->tval == TV_WAND) gain_num = (pval + num - 1) / num;
268                         if (p_ptr->magic_num2[o_ptr->sval + ext])
269                         {
270                                 gain_num *= 256;
271                                 gain_num = (gain_num / 3 + randint0(gain_num / 3)) / 256;
272                                 if (gain_num < 1) gain_num = 1;
273                         }
274                         p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)gain_num;
275                         if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
276                         p_ptr->magic_num1[o_ptr->sval + ext] += pval * 0x10000;
277                         if (p_ptr->magic_num1[o_ptr->sval + ext] > 99 * 0x10000) p_ptr->magic_num1[o_ptr->sval + ext] = 99 * 0x10000;
278                         if (p_ptr->magic_num1[o_ptr->sval + ext] > p_ptr->magic_num2[o_ptr->sval + ext] * 0x10000) p_ptr->magic_num1[o_ptr->sval + ext] = p_ptr->magic_num2[o_ptr->sval + ext] * 0x10000;
279                         if (o_ptr->tval == TV_WAND) pval -= (pval + num - 1) / num;
280                 }
281         }
282
283         object_desc(o_name, o_ptr, 0);
284         msg_format(_("%sの魔力を取り込んだ。", "You absorb magic of %s."), o_name);
285
286         /* Eliminate the item (from the pack) */
287         if (item >= 0)
288         {
289                 inven_item_increase(item, -999);
290                 inven_item_describe(item);
291                 inven_item_optimize(item);
292         }
293
294         /* Eliminate the item (from the floor) */
295         else
296         {
297                 floor_item_increase(0 - item, -999);
298                 floor_item_describe(0 - item);
299                 floor_item_optimize(0 - item);
300         }
301         p_ptr->energy_use = 100;
302         return TRUE;
303 }