3 #include "spells-object.h"
4 #include "object-hook.h"
5 #include "player-status.h"
11 OBJECT_TYPE_VALUE tval;
12 OBJECT_SUBTYPE_VALUE sval;
18 * Scatter some "amusing" objects near the player
21 #define AMS_NOTHING 0x00 /* No restriction */
22 #define AMS_NO_UNIQUE 0x01 /* Don't make the amusing object of uniques */
23 #define AMS_FIXED_ART 0x02 /* Make a fixed artifact based on the amusing object */
24 #define AMS_MULTIPLE 0x04 /* Drop 1-3 objects for one type */
25 #define AMS_PILE 0x08 /* Drop 1-99 pile objects for one type */
27 static amuse_type amuse_info[] =
29 { TV_BOTTLE, SV_ANY, 5, AMS_NOTHING },
30 { TV_JUNK, SV_ANY, 3, AMS_MULTIPLE },
31 { TV_SPIKE, SV_ANY, 10, AMS_PILE },
32 { TV_STATUE, SV_ANY, 15, AMS_NOTHING },
33 { TV_CORPSE, SV_ANY, 15, AMS_NO_UNIQUE },
34 { TV_SKELETON, SV_ANY, 10, AMS_NO_UNIQUE },
35 { TV_FIGURINE, SV_ANY, 10, AMS_NO_UNIQUE },
36 { TV_PARCHMENT, SV_ANY, 1, AMS_NOTHING },
37 { TV_POLEARM, SV_TSURIZAO, 3, AMS_NOTHING }, //Fishing Pole of Taikobo
38 { TV_SWORD, SV_BROKEN_DAGGER, 3, AMS_FIXED_ART }, //Broken Dagger of Magician
39 { TV_SWORD, SV_BROKEN_DAGGER, 10, AMS_NOTHING },
40 { TV_SWORD, SV_BROKEN_SWORD, 5, AMS_NOTHING },
41 { TV_SCROLL, SV_SCROLL_AMUSEMENT, 10, AMS_NOTHING },
47 * @brief「弾/矢の製造」処理 / do_cmd_cast calls this function if the player's class is 'archer'.
48 * Hook to determine if an object is contertible in an arrow/bolt
49 * @return 製造を実際に行ったらTRUE、キャンセルしたらFALSEを返す
51 bool create_ammo(void)
60 GAME_TEXT o_name[MAX_NLEN];
65 sprintf(com, _("[S]弾, [A]矢, [B]クロスボウの矢 :", "Create [S]hots, Create [A]rrow or Create [B]olt ?"));
66 else if (p_ptr->lev >= 10)
67 sprintf(com, _("[S]弾, [A]矢:", "Create [S]hots or Create [A]rrow ?"));
69 sprintf(com, _("[S]弾:", "Create [S]hots ?"));
73 msg_print(_("混乱してる!", "You are too confused!"));
79 msg_print(_("目が見えない!", "You are blind!"));
85 if (!get_com(com, &ch, TRUE))
89 if (ch == 'S' || ch == 's')
94 if ((ch == 'A' || ch == 'a') && (p_ptr->lev >= 10))
99 if ((ch == 'B' || ch == 'b') && (p_ptr->lev >= 20))
106 /**********Create shots*********/
113 if (!get_rep_dir(&dir, FALSE)) return FALSE;
114 y = p_ptr->y + ddy[dir];
115 x = p_ptr->x + ddx[dir];
116 g_ptr = &grid_array[y][x];
118 if (!have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_CAN_DIG))
120 msg_print(_("そこには岩石がない。", "You need pile of rubble."));
123 else if (!cave_have_flag_grid(g_ptr, FF_CAN_DIG) || !cave_have_flag_grid(g_ptr, FF_HURT_ROCK))
125 msg_print(_("硬すぎて崩せなかった。", "You failed to make ammo."));
132 /* Hack -- Give the player some small firestones */
133 object_prep(q_ptr, lookup_kind(TV_SHOT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
134 q_ptr->number = (byte)rand_range(15, 30);
137 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
138 q_ptr->discount = 99;
140 slot = inven_carry(q_ptr);
142 object_desc(o_name, q_ptr, 0);
143 msg_format(_("%sを作った。", "You make some ammo."), o_name);
145 /* Auto-inscription */
146 if (slot >= 0) autopick_alter_item(slot, FALSE);
148 /* Destroy the wall */
149 cave_alter_feat(y, x, FF_HURT_ROCK);
151 p_ptr->update |= (PU_FLOW);
154 /**********Create arrows*********/
161 item_tester_hook = item_tester_hook_convertible;
163 q = _("どのアイテムから作りますか? ", "Convert which item? ");
164 s = _("材料を持っていない。", "You have no item to convert.");
165 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
166 if (!q_ptr) return FALSE;
170 /* Hack -- Give the player some small firestones */
171 object_prep(q_ptr, lookup_kind(TV_ARROW, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
172 q_ptr->number = (byte)rand_range(5, 10);
175 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
177 q_ptr->discount = 99;
179 object_desc(o_name, q_ptr, 0);
180 msg_format(_("%sを作った。", "You make some ammo."), o_name);
184 inven_item_increase(item, -1);
185 inven_item_describe(item);
186 inven_item_optimize(item);
190 floor_item_increase(0 - item, -1);
191 floor_item_describe(0 - item);
192 floor_item_optimize(0 - item);
195 slot = inven_carry(q_ptr);
197 /* Auto-inscription */
198 if (slot >= 0) autopick_alter_item(slot, FALSE);
200 /**********Create bolts*********/
207 item_tester_hook = item_tester_hook_convertible;
209 q = _("どのアイテムから作りますか? ", "Convert which item? ");
210 s = _("材料を持っていない。", "You have no item to convert.");
212 q_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
213 if (!q_ptr) return FALSE;
217 /* Hack -- Give the player some small firestones */
218 object_prep(q_ptr, lookup_kind(TV_BOLT, (OBJECT_SUBTYPE_VALUE)m_bonus(1, p_ptr->lev) + 1));
219 q_ptr->number = (byte)rand_range(4, 8);
222 apply_magic(q_ptr, p_ptr->lev, AM_NO_FIXED_ART);
224 q_ptr->discount = 99;
226 object_desc(o_name, q_ptr, 0);
227 msg_format(_("%sを作った。", "You make some ammo."), o_name);
231 inven_item_increase(item, -1);
232 inven_item_describe(item);
233 inven_item_optimize(item);
237 floor_item_increase(0 - item, -1);
238 floor_item_describe(0 - item);
239 floor_item_optimize(0 - item);
242 slot = inven_carry(q_ptr);
244 /* Auto-inscription */
245 if (slot >= 0) autopick_alter_item(slot, FALSE);
251 * @brief 魔道具術師の魔力取り込み処理
252 * @return 取り込みを実行したらTRUE、キャンセルしたらFALSEを返す
254 bool import_magic_device(void)
257 PARAMETER_VALUE pval;
261 GAME_TEXT o_name[MAX_NLEN];
263 /* Only accept legal items */
264 item_tester_hook = item_tester_hook_recharge;
266 q = _("どのアイテムの魔力を取り込みますか? ", "Gain power of which item? ");
267 s = _("魔力を取り込めるアイテムがない。", "You have nothing to gain power.");
269 o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
270 if (!o_ptr) return (FALSE);
272 if (o_ptr->tval == TV_STAFF && o_ptr->sval == SV_STAFF_NOTHING)
274 msg_print(_("この杖には発動の為の能力は何も備わっていないようだ。", "This staff doesn't have any magical ability."));
278 if (!object_is_known(o_ptr))
280 msg_print(_("鑑定されていないと取り込めない。", "You need to identify before absorbing."));
286 msg_print(_("充填中のアイテムは取り込めない。", "This item is still charging."));
291 if (o_ptr->tval == TV_ROD)
293 else if (o_ptr->tval == TV_WAND)
296 if (o_ptr->tval == TV_ROD)
298 p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)o_ptr->number;
299 if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
304 for (num = o_ptr->number; num; num--)
307 if (o_ptr->tval == TV_WAND) gain_num = (pval + num - 1) / num;
308 if (p_ptr->magic_num2[o_ptr->sval + ext])
311 gain_num = (gain_num / 3 + randint0(gain_num / 3)) / 256;
312 if (gain_num < 1) gain_num = 1;
314 p_ptr->magic_num2[o_ptr->sval + ext] += (MAGIC_NUM2)gain_num;
315 if (p_ptr->magic_num2[o_ptr->sval + ext] > 99) p_ptr->magic_num2[o_ptr->sval + ext] = 99;
316 p_ptr->magic_num1[o_ptr->sval + ext] += pval * 0x10000;
317 if (p_ptr->magic_num1[o_ptr->sval + ext] > 99 * 0x10000) p_ptr->magic_num1[o_ptr->sval + ext] = 99 * 0x10000;
318 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;
319 if (o_ptr->tval == TV_WAND) pval -= (pval + num - 1) / num;
323 object_desc(o_name, o_ptr, 0);
324 msg_format(_("%sの魔力を取り込んだ。", "You absorb magic of %s."), o_name);
326 /* Eliminate the item (from the pack) */
329 inven_item_increase(item, -999);
330 inven_item_describe(item);
331 inven_item_optimize(item);
334 /* Eliminate the item (from the floor) */
337 floor_item_increase(0 - item, -999);
338 floor_item_describe(0 - item);
339 floor_item_optimize(0 - item);
341 take_turn(p_ptr, 100);;
347 * @param y1 配置したいフロアのY座標
348 * @param x1 配置したいフロアのX座標
350 * @param known TRUEならばオブジェクトが必ず*鑑定*済になる
353 void amusement(POSITION y1, POSITION x1, int num, bool known)
356 object_type object_type_body;
359 for (n = 0; amuse_info[n].tval != 0; n++)
361 t += amuse_info[n].prob;
368 KIND_OBJECT_IDX k_idx;
369 ARTIFACT_IDX a_idx = 0;
371 bool insta_art, fixed_art;
375 r -= amuse_info[i].prob;
378 i_ptr = &object_type_body;
380 k_idx = lookup_kind(amuse_info[i].tval, amuse_info[i].sval);
382 /* Paranoia - reroll if nothing */
383 if (!k_idx) continue;
385 /* Search an artifact index if need */
386 insta_art = (k_info[k_idx].gen_flags & TRG_INSTA_ART);
387 fixed_art = (amuse_info[i].flag & AMS_FIXED_ART);
389 if (insta_art || fixed_art)
391 for (a_idx = 1; a_idx < max_a_idx; a_idx++)
393 if (insta_art && !(a_info[a_idx].gen_flags & TRG_INSTA_ART)) continue;
394 if (a_info[a_idx].tval != k_info[k_idx].tval) continue;
395 if (a_info[a_idx].sval != k_info[k_idx].sval) continue;
396 if (a_info[a_idx].cur_num > 0) continue;
400 if (a_idx >= max_a_idx) continue;
403 /* Make an object (if possible) */
404 object_prep(i_ptr, k_idx);
405 if (a_idx) i_ptr->name1 = a_idx;
406 apply_magic(i_ptr, 1, AM_NO_FIXED_ART);
408 if (amuse_info[i].flag & AMS_NO_UNIQUE)
410 if (r_info[i_ptr->pval].flags1 & RF1_UNIQUE) continue;
413 if (amuse_info[i].flag & AMS_MULTIPLE) i_ptr->number = randint1(3);
414 if (amuse_info[i].flag & AMS_PILE) i_ptr->number = randint1(99);
422 /* Paranoia - reroll if nothing */
423 if (!(i_ptr->k_idx)) continue;
425 (void)drop_near(i_ptr, -1, y1, x1);
435 * Scatter some "great" objects near the player
436 * @param y1 配置したいフロアのY座標
437 * @param x1 配置したいフロアのX座標
439 * @param great TRUEならば必ず高級品以上を落とす
440 * @param special TRUEならば必ず特別品を落とす
441 * @param known TRUEならばオブジェクトが必ず*鑑定*済になる
444 void acquirement(POSITION y1, POSITION x1, int num, bool great, bool special, bool known)
447 object_type object_type_body;
448 BIT_FLAGS mode = AM_GOOD | (great || special ? AM_GREAT : 0L) | (special ? AM_SPECIAL : 0L);
453 i_ptr = &object_type_body;
456 /* Make a good (or great) object (if possible) */
457 if (!make_object(i_ptr, mode)) continue;
465 (void)drop_near(i_ptr, -1, y1, x1);
471 * Curse the players armor
472 * @return 実際に呪縛されたらTRUEを返す
474 bool curse_armor(void)
479 GAME_TEXT o_name[MAX_NLEN];
481 /* Curse the body armor */
482 o_ptr = &inventory[INVEN_BODY];
484 /* Nothing to curse */
485 if (!o_ptr->k_idx) return (FALSE);
487 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
489 /* Attempt a saving throw for artifacts */
490 if (object_is_artifact(o_ptr) && (randint0(100) < 50))
494 msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!",
495 "恐怖の暗黒オーラ", "防具", o_name);
497 msg_format("A %s tries to %s, but your %s resists the effects!",
498 "terrible black aura", "surround your armor", o_name);
503 /* not artifact or failed save... */
506 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
507 chg_virtue(V_ENCHANT, -5);
509 /* Blast the armor */
511 o_ptr->name2 = EGO_BLASTED;
512 o_ptr->to_a = 0 - randint1(5) - randint1(5);
519 for (i = 0; i < TR_FLAG_SIZE; i++)
520 o_ptr->art_flags[i] = 0;
523 o_ptr->curse_flags = TRC_CURSED;
526 o_ptr->ident |= (IDENT_BROKEN);
527 p_ptr->update |= (PU_BONUS | PU_MANA);
528 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
536 * Curse the players weapon
537 * @param force 無条件に呪縛を行うならばTRUE
538 * @param o_ptr 呪縛する武器のアイテム情報参照ポインタ
539 * @return 実際に呪縛されたらTRUEを返す
541 bool curse_weapon_object(bool force, object_type *o_ptr)
544 GAME_TEXT o_name[MAX_NLEN];
546 /* Nothing to curse */
547 if (!o_ptr->k_idx) return (FALSE);
548 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
550 /* Attempt a saving throw */
551 if (object_is_artifact(o_ptr) && (randint0(100) < 50) && !force)
555 msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!",
556 "恐怖の暗黒オーラ", "武器", o_name);
558 msg_format("A %s tries to %s, but your %s resists the effects!",
559 "terrible black aura", "surround your weapon", o_name);
563 /* not artifact or failed save... */
566 if (!force) msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
567 chg_virtue(V_ENCHANT, -5);
569 /* Shatter the weapon */
571 o_ptr->name2 = EGO_SHATTERED;
572 o_ptr->to_h = 0 - randint1(5) - randint1(5);
573 o_ptr->to_d = 0 - randint1(5) - randint1(5);
579 for (i = 0; i < TR_FLAG_SIZE; i++)
580 o_ptr->art_flags[i] = 0;
583 o_ptr->curse_flags = TRC_CURSED;
586 o_ptr->ident |= (IDENT_BROKEN);
587 p_ptr->update |= (PU_BONUS | PU_MANA);
588 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
595 * @brief 武器呪縛処理のメインルーチン /
596 * Curse the players weapon
597 * @param force 無条件に呪縛を行うならばTRUE
598 * @param slot 呪縛する武器の装備スロット
599 * @return 実際に呪縛されたらTRUEを返す
601 bool curse_weapon(bool force, int slot)
603 /* Curse the weapon */
604 return curse_weapon_object(force, &inventory[slot]);
610 * @return ターン消費を要する処理を行ったならばTRUEを返す
616 GAME_TEXT o_name[MAX_NLEN];
619 /* Select a piece of armour */
620 item_tester_hook = object_is_armour;
622 q = _("どの防具に錆止めをしますか?", "Rustproof which piece of armour? ");
623 s = _("錆止めできるものがありません。", "You have nothing to rustproof.");
625 o_ptr = choose_object(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT));
626 if (!o_ptr) return FALSE;
628 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
630 add_flag(o_ptr->art_flags, TR_IGNORE_ACID);
632 if ((o_ptr->to_a < 0) && !object_is_cursed(o_ptr))
635 msg_format("%sは新品同様になった!", o_name);
637 msg_format("%s %s look%s as good as new!", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "" : "s"));
644 msg_format("%sは腐食しなくなった。", o_name);
646 msg_format("%s %s %s now protected against corrosion.", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "are" : "is"));
654 * @brief ボルトのエゴ化処理(火炎エゴのみ) /
658 bool brand_bolts(void)
662 /* Use the first acceptable bolts */
663 for (i = 0; i < INVEN_PACK; i++)
665 object_type *o_ptr = &inventory[i];
668 if (o_ptr->tval != TV_BOLT) continue;
670 /* Skip artifacts and ego-items */
671 if (object_is_artifact(o_ptr) || object_is_ego(o_ptr))
674 /* Skip cursed/broken items */
675 if (object_is_cursed(o_ptr) || object_is_broken(o_ptr)) continue;
678 if (randint0(100) < 75) continue;
680 msg_print(_("クロスボウの矢が炎のオーラに包まれた!", "Your bolts are covered in a fiery aura!"));
683 o_ptr->name2 = EGO_FLAME;
684 enchant(o_ptr, randint0(3) + 4, ENCH_TOHIT | ENCH_TODAM);
688 if (flush_failure) flush();
691 msg_print(_("炎で強化するのに失敗した。", "The fiery enchantment failed."));