OSDN Git Service

[Refactor] #37353 get_bloody_moon_flags() を spells-object.c に移動。 / Move get_bloody_mo...
[hengband/hengband.git] / src / spells-object.c
1 
2 #include "angband.h"
3 #include "artifact.h"
4 #include "spells-object.h"
5 #include "object-hook.h"
6 #include "player-status.h"
7 #include "avatar.h"
8
9
10 typedef struct
11 {
12         OBJECT_TYPE_VALUE tval;
13         OBJECT_SUBTYPE_VALUE sval;
14         PERCENTAGE prob;
15         byte flag;
16 } amuse_type;
17
18 /*
19  * Scatter some "amusing" objects near the player
20  */
21
22 #define AMS_NOTHING   0x00 /* No restriction */
23 #define AMS_NO_UNIQUE 0x01 /* Don't make the amusing object of uniques */
24 #define AMS_FIXED_ART 0x02 /* Make a fixed artifact based on the amusing object */
25 #define AMS_MULTIPLE  0x04 /* Drop 1-3 objects for one type */
26 #define AMS_PILE      0x08 /* Drop 1-99 pile objects for one type */
27
28 static amuse_type amuse_info[] =
29 {
30         { TV_BOTTLE, SV_ANY, 5, AMS_NOTHING },
31         { TV_JUNK, SV_ANY, 3, AMS_MULTIPLE },
32         { TV_SPIKE, SV_ANY, 10, AMS_PILE },
33         { TV_STATUE, SV_ANY, 15, AMS_NOTHING },
34         { TV_CORPSE, SV_ANY, 15, AMS_NO_UNIQUE },
35         { TV_SKELETON, SV_ANY, 10, AMS_NO_UNIQUE },
36         { TV_FIGURINE, SV_ANY, 10, AMS_NO_UNIQUE },
37         { TV_PARCHMENT, SV_ANY, 1, AMS_NOTHING },
38         { TV_POLEARM, SV_TSURIZAO, 3, AMS_NOTHING }, //Fishing Pole of Taikobo
39         { TV_SWORD, SV_BROKEN_DAGGER, 3, AMS_FIXED_ART }, //Broken Dagger of Magician
40         { TV_SWORD, SV_BROKEN_DAGGER, 10, AMS_NOTHING },
41         { TV_SWORD, SV_BROKEN_SWORD, 5, AMS_NOTHING },
42         { TV_SCROLL, SV_SCROLL_AMUSEMENT, 10, AMS_NOTHING },
43
44         { 0, 0, 0 }
45 };
46
47 /*!
48  * @brief「弾/矢の製造」処理 / do_cmd_cast calls this function if the player's class is 'archer'.
49  * Hook to determine if an object is contertible in an arrow/bolt
50  * @return 製造を実際に行ったらTRUE、キャンセルしたらFALSEを返す
51  */
52 bool create_ammo(void)
53 {
54         int ext = 0;
55         char ch;
56
57         object_type     forge;
58         object_type *q_ptr;
59
60         char com[80];
61         GAME_TEXT o_name[MAX_NLEN];
62
63         q_ptr = &forge;
64
65         if (p_ptr->lev >= 20)
66                 sprintf(com, _("[S]弾, [A]矢, [B]クロスボウの矢 :", "Create [S]hots, Create [A]rrow or Create [B]olt ?"));
67         else if (p_ptr->lev >= 10)
68                 sprintf(com, _("[S]弾, [A]矢:", "Create [S]hots or Create [A]rrow ?"));
69         else
70                 sprintf(com, _("[S]弾:", "Create [S]hots ?"));
71
72         if (p_ptr->confused)
73         {
74                 msg_print(_("混乱してる!", "You are too confused!"));
75                 return FALSE;
76         }
77
78         if (p_ptr->blind)
79         {
80                 msg_print(_("目が見えない!", "You are blind!"));
81                 return FALSE;
82         }
83
84         while (TRUE)
85         {
86                 if (!get_com(com, &ch, TRUE))
87                 {
88                         return FALSE;
89                 }
90                 if (ch == 'S' || ch == 's')
91                 {
92                         ext = 1;
93                         break;
94                 }
95                 if ((ch == 'A' || ch == 'a') && (p_ptr->lev >= 10))
96                 {
97                         ext = 2;
98                         break;
99                 }
100                 if ((ch == 'B' || ch == 'b') && (p_ptr->lev >= 20))
101                 {
102                         ext = 3;
103                         break;
104                 }
105         }
106
107         /**********Create shots*********/
108         if (ext == 1)
109         {
110                 POSITION x, y;
111                 DIRECTION dir;
112                 grid_type *g_ptr;
113
114                 if (!get_rep_dir(&dir, FALSE)) return FALSE;
115                 y = p_ptr->y + ddy[dir];
116                 x = p_ptr->x + ddx[dir];
117                 g_ptr = &grid_array[y][x];
118
119                 if (!have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_CAN_DIG))
120                 {
121                         msg_print(_("そこには岩石がない。", "You need pile of rubble."));
122                         return FALSE;
123                 }
124                 else if (!cave_have_flag_grid(g_ptr, FF_CAN_DIG) || !cave_have_flag_grid(g_ptr, FF_HURT_ROCK))
125                 {
126                         msg_print(_("硬すぎて崩せなかった。", "You failed to make ammo."));
127                 }
128                 else
129                 {
130                         s16b slot;
131                         q_ptr = &forge;
132
133                         /* Hack -- Give the player some small firestones */
134                         object_prep(q_ptr, lookup_kind(TV_SHOT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
135                         q_ptr->number = (byte)rand_range(15, 30);
136                         object_aware(q_ptr);
137                         object_known(q_ptr);
138                         apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
139                         q_ptr->discount = 99;
140
141                         slot = inven_carry(q_ptr);
142
143                         object_desc(o_name, q_ptr, 0);
144                         msg_format(_("%sを作った。", "You make some ammo."), o_name);
145
146                         /* Auto-inscription */
147                         if (slot >= 0) autopick_alter_item(slot, FALSE);
148
149                         /* Destroy the wall */
150                         cave_alter_feat(y, x, FF_HURT_ROCK);
151
152                         p_ptr->update |= (PU_FLOW);
153                 }
154         }
155         /**********Create arrows*********/
156         else if (ext == 2)
157         {
158                 OBJECT_IDX item;
159                 concptr q, s;
160                 s16b slot;
161
162                 item_tester_hook = item_tester_hook_convertible;
163
164                 q = _("どのアイテムから作りますか? ", "Convert which item? ");
165                 s = _("材料を持っていない。", "You have no item to convert.");
166                 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
167                 if (!q_ptr) return FALSE;
168
169                 q_ptr = &forge;
170
171                 /* Hack -- Give the player some small firestones */
172                 object_prep(q_ptr, lookup_kind(TV_ARROW, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
173                 q_ptr->number = (byte)rand_range(5, 10);
174                 object_aware(q_ptr);
175                 object_known(q_ptr);
176                 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
177
178                 q_ptr->discount = 99;
179
180                 object_desc(o_name, q_ptr, 0);
181                 msg_format(_("%sを作った。", "You make some ammo."), o_name);
182
183                 if (item >= 0)
184                 {
185                         inven_item_increase(item, -1);
186                         inven_item_describe(item);
187                         inven_item_optimize(item);
188                 }
189                 else
190                 {
191                         floor_item_increase(0 - item, -1);
192                         floor_item_describe(0 - item);
193                         floor_item_optimize(0 - item);
194                 }
195
196                 slot = inven_carry(q_ptr);
197
198                 /* Auto-inscription */
199                 if (slot >= 0) autopick_alter_item(slot, FALSE);
200         }
201         /**********Create bolts*********/
202         else if (ext == 3)
203         {
204                 OBJECT_IDX item;
205                 concptr q, s;
206                 s16b slot;
207
208                 item_tester_hook = item_tester_hook_convertible;
209
210                 q = _("どのアイテムから作りますか? ", "Convert which item? ");
211                 s = _("材料を持っていない。", "You have no item to convert.");
212
213                 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
214                 if (!q_ptr) return FALSE;
215
216                 q_ptr = &forge;
217
218                 /* Hack -- Give the player some small firestones */
219                 object_prep(q_ptr, lookup_kind(TV_BOLT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
220                 q_ptr->number = (byte)rand_range(4, 8);
221                 object_aware(q_ptr);
222                 object_known(q_ptr);
223                 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
224
225                 q_ptr->discount = 99;
226
227                 object_desc(o_name, q_ptr, 0);
228                 msg_format(_("%sを作った。", "You make some ammo."), o_name);
229
230                 if (item >= 0)
231                 {
232                         inven_item_increase(item, -1);
233                         inven_item_describe(item);
234                         inven_item_optimize(item);
235                 }
236                 else
237                 {
238                         floor_item_increase(0 - item, -1);
239                         floor_item_describe(0 - item);
240                         floor_item_optimize(0 - item);
241                 }
242
243                 slot = inven_carry(q_ptr);
244
245                 /* Auto-inscription */
246                 if (slot >= 0) autopick_alter_item(slot, FALSE);
247         }
248         return TRUE;
249 }
250
251 /*!
252  * @brief 魔道具術師の魔力取り込み処理
253  * @return 取り込みを実行したらTRUE、キャンセルしたらFALSEを返す
254  */
255 bool import_magic_device(void)
256 {
257         OBJECT_IDX item;
258         PARAMETER_VALUE pval;
259         int ext = 0;
260         concptr q, s;
261         object_type *o_ptr;
262         GAME_TEXT o_name[MAX_NLEN];
263
264         /* Only accept legal items */
265         item_tester_hook = item_tester_hook_recharge;
266
267         q = _("どのアイテムの魔力を取り込みますか? ", "Gain power of which item? ");
268         s = _("魔力を取り込めるアイテムがない。", "You have nothing to gain power.");
269
270         o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
271         if (!o_ptr) return (FALSE);
272
273         if (o_ptr->tval == TV_STAFF && o_ptr->sval == SV_STAFF_NOTHING)
274         {
275                 msg_print(_("この杖には発動の為の能力は何も備わっていないようだ。", "This staff doesn't have any magical ability."));
276                 return FALSE;
277         }
278
279         if (!object_is_known(o_ptr))
280         {
281                 msg_print(_("鑑定されていないと取り込めない。", "You need to identify before absorbing."));
282                 return FALSE;
283         }
284
285         if (o_ptr->timeout)
286         {
287                 msg_print(_("充填中のアイテムは取り込めない。", "This item is still charging."));
288                 return FALSE;
289         }
290
291         pval = o_ptr->pval;
292         if (o_ptr->tval == TV_ROD)
293                 ext = 72;
294         else if (o_ptr->tval == TV_WAND)
295                 ext = 36;
296
297         if (o_ptr->tval == TV_ROD)
298         {
299                 p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)o_ptr->number;
300                 if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
301         }
302         else
303         {
304                 int num;
305                 for (num = o_ptr->number; num; num--)
306                 {
307                         int gain_num = pval;
308                         if (o_ptr->tval == TV_WAND) gain_num = (pval + num - 1) / num;
309                         if (p_ptr->magic_num2[o_ptr->sval + ext])
310                         {
311                                 gain_num *= 256;
312                                 gain_num = (gain_num / 3 + randint0(gain_num / 3)) / 256;
313                                 if (gain_num < 1) gain_num = 1;
314                         }
315                         p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)gain_num;
316                         if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
317                         p_ptr->magic_num1[o_ptr->sval + ext] += pval * 0x10000;
318                         if (p_ptr->magic_num1[o_ptr->sval + ext] > 99 * 0x10000) p_ptr->magic_num1[o_ptr->sval + ext] = 99 * 0x10000;
319                         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;
320                         if (o_ptr->tval == TV_WAND) pval -= (pval + num - 1) / num;
321                 }
322         }
323
324         object_desc(o_name, o_ptr, 0);
325         msg_format(_("%sの魔力を取り込んだ。", "You absorb magic of %s."), o_name);
326
327         /* Eliminate the item (from the pack) */
328         if (item >= 0)
329         {
330                 inven_item_increase(item, -999);
331                 inven_item_describe(item);
332                 inven_item_optimize(item);
333         }
334
335         /* Eliminate the item (from the floor) */
336         else
337         {
338                 floor_item_increase(0 - item, -999);
339                 floor_item_describe(0 - item);
340                 floor_item_optimize(0 - item);
341         }
342         take_turn(p_ptr, 100);
343         return TRUE;
344 }
345
346 /*!
347  * @brief 誰得ドロップを行う。
348  * @param y1 配置したいフロアのY座標
349  * @param x1 配置したいフロアのX座標
350  * @param num 誰得の処理回数
351  * @param known TRUEならばオブジェクトが必ず*鑑定*済になる
352  * @return なし
353  */
354 void amusement(POSITION y1, POSITION x1, int num, bool known)
355 {
356         object_type *i_ptr;
357         object_type object_type_body;
358         int n, t = 0;
359
360         for (n = 0; amuse_info[n].tval != 0; n++)
361         {
362                 t += amuse_info[n].prob;
363         }
364
365         /* Acquirement */
366         while (num)
367         {
368                 int i;
369                 KIND_OBJECT_IDX k_idx;
370                 ARTIFACT_IDX a_idx = 0;
371                 int r = randint0(t);
372                 bool insta_art, fixed_art;
373
374                 for (i = 0; ; i++)
375                 {
376                         r -= amuse_info[i].prob;
377                         if (r <= 0) break;
378                 }
379                 i_ptr = &object_type_body;
380                 object_wipe(i_ptr);
381                 k_idx = lookup_kind(amuse_info[i].tval, amuse_info[i].sval);
382
383                 /* Paranoia - reroll if nothing */
384                 if (!k_idx) continue;
385
386                 /* Search an artifact index if need */
387                 insta_art = (k_info[k_idx].gen_flags & TRG_INSTA_ART);
388                 fixed_art = (amuse_info[i].flag & AMS_FIXED_ART);
389
390                 if (insta_art || fixed_art)
391                 {
392                         for (a_idx = 1; a_idx < max_a_idx; a_idx++)
393                         {
394                                 if (insta_art && !(a_info[a_idx].gen_flags & TRG_INSTA_ART)) continue;
395                                 if (a_info[a_idx].tval != k_info[k_idx].tval) continue;
396                                 if (a_info[a_idx].sval != k_info[k_idx].sval) continue;
397                                 if (a_info[a_idx].cur_num > 0) continue;
398                                 break;
399                         }
400
401                         if (a_idx >= max_a_idx) continue;
402                 }
403
404                 /* Make an object (if possible) */
405                 object_prep(i_ptr, k_idx);
406                 if (a_idx) i_ptr->name1 = a_idx;
407                 apply_magic(i_ptr, 1, AM_NO_FIXED_ART);
408
409                 if (amuse_info[i].flag & AMS_NO_UNIQUE)
410                 {
411                         if (r_info[i_ptr->pval].flags1 & RF1_UNIQUE) continue;
412                 }
413
414                 if (amuse_info[i].flag & AMS_MULTIPLE) i_ptr->number = randint1(3);
415                 if (amuse_info[i].flag & AMS_PILE) i_ptr->number = randint1(99);
416
417                 if (known)
418                 {
419                         object_aware(i_ptr);
420                         object_known(i_ptr);
421                 }
422
423                 /* Paranoia - reroll if nothing */
424                 if (!(i_ptr->k_idx)) continue;
425
426                 (void)drop_near(i_ptr, -1, y1, x1);
427
428                 num--;
429         }
430 }
431
432
433
434 /*!
435  * @brief 獲得ドロップを行う。
436  * Scatter some "great" objects near the player
437  * @param y1 配置したいフロアのY座標
438  * @param x1 配置したいフロアのX座標
439  * @param num 獲得の処理回数
440  * @param great TRUEならば必ず高級品以上を落とす
441  * @param special TRUEならば必ず特別品を落とす
442  * @param known TRUEならばオブジェクトが必ず*鑑定*済になる
443  * @return なし
444  */
445 void acquirement(POSITION y1, POSITION x1, int num, bool great, bool special, bool known)
446 {
447         object_type *i_ptr;
448         object_type object_type_body;
449         BIT_FLAGS mode = AM_GOOD | (great || special ? AM_GREAT : 0L) | (special ? AM_SPECIAL : 0L);
450
451         /* Acquirement */
452         while (num--)
453         {
454                 i_ptr = &object_type_body;
455                 object_wipe(i_ptr);
456
457                 /* Make a good (or great) object (if possible) */
458                 if (!make_object(i_ptr, mode)) continue;
459
460                 if (known)
461                 {
462                         object_aware(i_ptr);
463                         object_known(i_ptr);
464                 }
465
466                 (void)drop_near(i_ptr, -1, y1, x1);
467         }
468 }
469
470 void acquire_chaos_weapon(player_type *creature_ptr)
471 {
472         object_type forge;
473         object_type *q_ptr = &forge;
474         OBJECT_TYPE_VALUE dummy = TV_SWORD;
475         OBJECT_SUBTYPE_VALUE dummy2;
476         switch (randint1(creature_ptr->lev))
477         {
478         case 0: case 1:
479                 dummy2 = SV_DAGGER;
480                 break;
481         case 2: case 3:
482                 dummy2 = SV_MAIN_GAUCHE;
483                 break;
484         case 4:
485                 dummy2 = SV_TANTO;
486                 break;
487         case 5: case 6:
488                 dummy2 = SV_RAPIER;
489                 break;
490         case 7: case 8:
491                 dummy2 = SV_SMALL_SWORD;
492                 break;
493         case 9: case 10:
494                 dummy2 = SV_BASILLARD;
495                 break;
496         case 11: case 12: case 13:
497                 dummy2 = SV_SHORT_SWORD;
498                 break;
499         case 14: case 15:
500                 dummy2 = SV_SABRE;
501                 break;
502         case 16: case 17:
503                 dummy2 = SV_CUTLASS;
504                 break;
505         case 18:
506                 dummy2 = SV_WAKIZASHI;
507                 break;
508         case 19:
509                 dummy2 = SV_KHOPESH;
510                 break;
511         case 20:
512                 dummy2 = SV_TULWAR;
513                 break;
514         case 21:
515                 dummy2 = SV_BROAD_SWORD;
516                 break;
517         case 22: case 23:
518                 dummy2 = SV_LONG_SWORD;
519                 break;
520         case 24: case 25:
521                 dummy2 = SV_SCIMITAR;
522                 break;
523         case 26:
524                 dummy2 = SV_NINJATO;
525                 break;
526         case 27:
527                 dummy2 = SV_KATANA;
528                 break;
529         case 28: case 29:
530                 dummy2 = SV_BASTARD_SWORD;
531                 break;
532         case 30:
533                 dummy2 = SV_GREAT_SCIMITAR;
534                 break;
535         case 31:
536                 dummy2 = SV_CLAYMORE;
537                 break;
538         case 32:
539                 dummy2 = SV_ESPADON;
540                 break;
541         case 33:
542                 dummy2 = SV_TWO_HANDED_SWORD;
543                 break;
544         case 34:
545                 dummy2 = SV_FLAMBERGE;
546                 break;
547         case 35:
548                 dummy2 = SV_NO_DACHI;
549                 break;
550         case 36:
551                 dummy2 = SV_EXECUTIONERS_SWORD;
552                 break;
553         case 37:
554                 dummy2 = SV_ZWEIHANDER;
555                 break;
556         case 38:
557                 dummy2 = SV_HAYABUSA;
558                 break;
559         default:
560                 dummy2 = SV_BLADE_OF_CHAOS;
561         }
562
563         object_prep(q_ptr, lookup_kind(dummy, dummy2));
564         q_ptr->to_h = 3 + randint1(dun_level) % 10;
565         q_ptr->to_d = 3 + randint1(dun_level) % 10;
566         one_resistance(q_ptr);
567         q_ptr->name2 = EGO_CHAOTIC;
568         (void)drop_near(q_ptr, -1, creature_ptr->y, creature_ptr->x);
569 }
570
571
572 /*!
573  * @brief 防具呪縛処理 /
574  * Curse the players armor
575  * @return 実際に呪縛されたらTRUEを返す
576  */
577 bool curse_armor(void)
578 {
579         int i;
580         object_type *o_ptr;
581
582         GAME_TEXT o_name[MAX_NLEN];
583
584         /* Curse the body armor */
585         o_ptr = &inventory[INVEN_BODY];
586
587         /* Nothing to curse */
588         if (!o_ptr->k_idx) return (FALSE);
589
590         object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
591
592         /* Attempt a saving throw for artifacts */
593         if (object_is_artifact(o_ptr) && (randint0(100) < 50))
594         {
595                 /* Cool */
596 #ifdef JP
597                 msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!",
598                         "恐怖の暗黒オーラ", "防具", o_name);
599 #else
600                 msg_format("A %s tries to %s, but your %s resists the effects!",
601                         "terrible black aura", "surround your armor", o_name);
602 #endif
603
604         }
605
606         /* not artifact or failed save... */
607         else
608         {
609                 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
610                 chg_virtue(V_ENCHANT, -5);
611
612                 /* Blast the armor */
613                 o_ptr->name1 = 0;
614                 o_ptr->name2 = EGO_BLASTED;
615                 o_ptr->to_a = 0 - randint1(5) - randint1(5);
616                 o_ptr->to_h = 0;
617                 o_ptr->to_d = 0;
618                 o_ptr->ac = 0;
619                 o_ptr->dd = 0;
620                 o_ptr->ds = 0;
621
622                 for (i = 0; i < TR_FLAG_SIZE; i++)
623                         o_ptr->art_flags[i] = 0;
624
625                 /* Curse it */
626                 o_ptr->curse_flags = TRC_CURSED;
627
628                 /* Break it */
629                 o_ptr->ident |= (IDENT_BROKEN);
630                 p_ptr->update |= (PU_BONUS | PU_MANA);
631                 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
632         }
633
634         return (TRUE);
635 }
636
637 /*!
638  * @brief 武器呪縛処理 /
639  * Curse the players weapon
640  * @param force 無条件に呪縛を行うならばTRUE
641  * @param o_ptr 呪縛する武器のアイテム情報参照ポインタ
642  * @return 実際に呪縛されたらTRUEを返す
643  */
644 bool curse_weapon_object(bool force, object_type *o_ptr)
645 {
646         int i;
647         GAME_TEXT o_name[MAX_NLEN];
648
649         /* Nothing to curse */
650         if (!o_ptr->k_idx) return (FALSE);
651         object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
652
653         /* Attempt a saving throw */
654         if (object_is_artifact(o_ptr) && (randint0(100) < 50) && !force)
655         {
656                 /* Cool */
657 #ifdef JP
658                 msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!",
659                         "恐怖の暗黒オーラ", "武器", o_name);
660 #else
661                 msg_format("A %s tries to %s, but your %s resists the effects!",
662                         "terrible black aura", "surround your weapon", o_name);
663 #endif
664         }
665
666         /* not artifact or failed save... */
667         else
668         {
669                 if (!force) msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
670                 chg_virtue(V_ENCHANT, -5);
671
672                 /* Shatter the weapon */
673                 o_ptr->name1 = 0;
674                 o_ptr->name2 = EGO_SHATTERED;
675                 o_ptr->to_h = 0 - randint1(5) - randint1(5);
676                 o_ptr->to_d = 0 - randint1(5) - randint1(5);
677                 o_ptr->to_a = 0;
678                 o_ptr->ac = 0;
679                 o_ptr->dd = 0;
680                 o_ptr->ds = 0;
681
682                 for (i = 0; i < TR_FLAG_SIZE; i++)
683                         o_ptr->art_flags[i] = 0;
684
685                 /* Curse it */
686                 o_ptr->curse_flags = TRC_CURSED;
687
688                 /* Break it */
689                 o_ptr->ident |= (IDENT_BROKEN);
690                 p_ptr->update |= (PU_BONUS | PU_MANA);
691                 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
692         }
693
694         return (TRUE);
695 }
696
697 /*!
698  * @brief 武器呪縛処理のメインルーチン /
699  * Curse the players weapon
700  * @param force 無条件に呪縛を行うならばTRUE
701  * @param slot 呪縛する武器の装備スロット
702  * @return 実際に呪縛されたらTRUEを返す
703  */
704 bool curse_weapon(bool force, int slot)
705 {
706         /* Curse the weapon */
707         return curse_weapon_object(force, &inventory[slot]);
708 }
709
710
711 /*!
712  * @brief 防具の錆止め防止処理
713  * @return ターン消費を要する処理を行ったならばTRUEを返す
714  */
715 bool rustproof(void)
716 {
717         OBJECT_IDX item;
718         object_type *o_ptr;
719         GAME_TEXT o_name[MAX_NLEN];
720         concptr q, s;
721
722         /* Select a piece of armour */
723         item_tester_hook = object_is_armour;
724
725         q = _("どの防具に錆止めをしますか?", "Rustproof which piece of armour? ");
726         s = _("錆止めできるものがありません。", "You have nothing to rustproof.");
727
728         o_ptr = choose_object(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT));
729         if (!o_ptr) return FALSE;
730
731         object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
732
733         add_flag(o_ptr->art_flags, TR_IGNORE_ACID);
734
735         if ((o_ptr->to_a < 0) && !object_is_cursed(o_ptr))
736         {
737 #ifdef JP
738                 msg_format("%sは新品同様になった!", o_name);
739 #else
740                 msg_format("%s %s look%s as good as new!", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "" : "s"));
741 #endif
742
743                 o_ptr->to_a = 0;
744         }
745
746 #ifdef JP
747         msg_format("%sは腐食しなくなった。", o_name);
748 #else
749         msg_format("%s %s %s now protected against corrosion.", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "are" : "is"));
750 #endif
751
752         calc_android_exp();
753         return TRUE;
754 }
755
756 /*!
757  * @brief ボルトのエゴ化処理(火炎エゴのみ) /
758  * Enchant some bolts
759  * @return 常にTRUEを返す
760  */
761 bool brand_bolts(void)
762 {
763         int i;
764
765         /* Use the first acceptable bolts */
766         for (i = 0; i < INVEN_PACK; i++)
767         {
768                 object_type *o_ptr = &inventory[i];
769
770                 /* Skip non-bolts */
771                 if (o_ptr->tval != TV_BOLT) continue;
772
773                 /* Skip artifacts and ego-items */
774                 if (object_is_artifact(o_ptr) || object_is_ego(o_ptr))
775                         continue;
776
777                 /* Skip cursed/broken items */
778                 if (object_is_cursed(o_ptr) || object_is_broken(o_ptr)) continue;
779
780                 /* Randomize */
781                 if (randint0(100) < 75) continue;
782
783                 msg_print(_("クロスボウの矢が炎のオーラに包まれた!", "Your bolts are covered in a fiery aura!"));
784
785                 /* Ego-item */
786                 o_ptr->name2 = EGO_FLAME;
787                 enchant(o_ptr, randint0(3) + 4, ENCH_TOHIT | ENCH_TODAM);
788                 return (TRUE);
789         }
790
791         if (flush_failure) flush();
792
793         /* Fail */
794         msg_print(_("炎で強化するのに失敗した。", "The fiery enchantment failed."));
795
796         return (TRUE);
797 }
798
799
800 bool perilous_secrets(player_type *creature_ptr)
801 {
802         if (!ident_spell(FALSE)) return FALSE;
803
804         if (mp_ptr->spell_book)
805         {
806                 /* Sufficient mana */
807                 if (20 <= creature_ptr->csp)
808                 {
809                         /* Use some mana */
810                         creature_ptr->csp -= 20;
811                 }
812
813                 /* Over-exert the player */
814                 else
815                 {
816                         int oops = 20 - creature_ptr->csp;
817
818                         /* No mana left */
819                         creature_ptr->csp = 0;
820                         creature_ptr->csp_frac = 0;
821
822                         msg_print(_("石を制御できない!", "You are too weak to control the stone!"));
823                         /* Hack -- Bypass free action */
824                         (void)set_paralyzed(creature_ptr->paralyzed + randint1(5 * oops + 1));
825
826                         /* Confusing. */
827                         (void)set_confused(creature_ptr->confused + randint1(5 * oops + 1));
828                 }
829                 creature_ptr->redraw |= (PR_MANA);
830         }
831         take_hit(DAMAGE_LOSELIFE, damroll(1, 12), _("危険な秘密", "perilous secrets"), -1);
832         /* Confusing. */
833         if (one_in_(5)) (void)set_confused(creature_ptr->confused + randint1(10));
834
835         /* Exercise a little care... */
836         if (one_in_(20)) take_hit(DAMAGE_LOSELIFE, damroll(4, 10), _("危険な秘密", "perilous secrets"), -1);
837         return TRUE;
838
839 }
840
841 /*!
842  * @brief 固定アーティファクト『ブラッディムーン』の特性を変更する。
843  * @details スレイ2d2種、及びone_resistance()による耐性1d2種、pval2種を得る。
844  * @param o_ptr 対象のオブジェクト構造体(ブラッディムーン)のポインタ
845  * @return なし
846  */
847 void get_bloody_moon_flags(object_type *o_ptr)
848 {
849         int dummy, i;
850
851         for (i = 0; i < TR_FLAG_SIZE; i++)
852                 o_ptr->art_flags[i] = a_info[ART_BLOOD].flags[i];
853
854         dummy = randint1(2) + randint1(2);
855         for (i = 0; i < dummy; i++)
856         {
857                 int flag = randint0(26);
858                 if (flag >= 20) add_flag(o_ptr->art_flags, TR_KILL_UNDEAD + flag - 20);
859                 else if (flag == 19) add_flag(o_ptr->art_flags, TR_KILL_ANIMAL);
860                 else if (flag == 18) add_flag(o_ptr->art_flags, TR_SLAY_HUMAN);
861                 else add_flag(o_ptr->art_flags, TR_CHAOTIC + flag);
862         }
863
864         dummy = randint1(2);
865         for (i = 0; i < dummy; i++) one_resistance(o_ptr);
866
867         for (i = 0; i < 2; i++)
868         {
869                 int tmp = randint0(11);
870                 if (tmp < A_MAX) add_flag(o_ptr->art_flags, TR_STR + tmp);
871                 else add_flag(o_ptr->art_flags, TR_STEALTH + tmp - 6);
872         }
873 }
874
875