3 #include "spells-summon.h"
6 * @brief 箱からアイテムを引き出す /
7 * Allocates objects upon opening a chest -BEN-
8 * @param scatter TRUEならばトラップによるアイテムの拡散処理
9 * @param y 箱の存在するマスのY座標
10 * @param x 箱の存在するマスのX座標
11 * @param o_idx 箱のオブジェクトID
15 * Disperse treasures from the given chest, centered at (x,y).
17 * Small chests often contain "gold", while Large chests always contain
18 * items. Wooden chests contain 2 items, Iron chests contain 4 items,
19 * and Steel chests contain 6 items. The "value" of the items in a
20 * chest is based on the "power" of the chest, which is in turn based
21 * on the level on which the chest is generated.
24 void chest_death(bool scatter, POSITION y, POSITION x, OBJECT_IDX o_idx)
29 BIT_FLAGS mode = AM_GOOD;
34 object_type *o_ptr = &o_list[o_idx];
37 /* Small chests often hold "gold" */
38 small = (o_ptr->sval < SV_CHEST_MIN_LARGE);
40 /* Determine how much to drop (see above) */
41 number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;
43 if (o_ptr->sval == SV_CHEST_KANDUME)
48 object_level = o_ptr->xtra3;
52 /* Determine the "value" of the items */
53 object_level = ABS(o_ptr->pval) + 10;
56 /* Zero pval means empty chest */
57 if (!o_ptr->pval) number = 0;
62 /* Drop some objects (non-chests) */
63 for (; number > 0; --number)
68 /* Small chests often drop gold */
69 if (small && (randint0(100) < 25))
72 if (!make_gold(q_ptr)) continue;
75 /* Otherwise drop an item */
78 /* Make a good object */
79 if (!make_object(q_ptr, mode)) continue;
82 /* If chest scatters its contents, pick any floor square. */
86 for (i = 0; i < 200; i++)
88 /* Pick a totally random spot. */
89 y = randint0(MAX_HGT);
90 x = randint0(MAX_WID);
92 /* Must be an empty floor. */
93 if (!cave_empty_bold(y, x)) continue;
95 /* Place the object there. */
96 (void)drop_near(q_ptr, -1, y, x);
102 /* Normally, drop object near the chest. */
103 else (void)drop_near(q_ptr, -1, y, x);
106 /* Reset the object level */
107 object_level = current_floor->base_level;
109 /* No longer opening a chest */
110 opening_chest = FALSE;
122 * Chests have traps too.
123 * @param y 箱の存在するマスのY座標
124 * @param x 箱の存在するマスのX座標
125 * @param o_idx 箱のオブジェクトID
129 * Exploding chest destroys contents (and traps).
130 * Note that the chest itself is never destroyed.
133 void chest_trap(POSITION y, POSITION x, OBJECT_IDX o_idx)
137 object_type *o_ptr = &o_list[o_idx];
139 int mon_level = o_ptr->xtra3;
141 /* Ignore disarmed chests */
142 if (o_ptr->pval <= 0) return;
144 /* Obtain the traps */
145 trap = chest_traps[o_ptr->pval];
148 if (trap & (CHEST_LOSE_STR))
150 msg_print(_("仕掛けられていた小さな針に刺されてしまった!", "A small needle has pricked you!"));
151 take_hit(DAMAGE_NOESCAPE, damroll(1, 4), _("毒針", "a poison needle"), -1);
152 (void)do_dec_stat(A_STR);
155 /* Lose constitution */
156 if (trap & (CHEST_LOSE_CON))
158 msg_print(_("仕掛けられていた小さな針に刺されてしまった!", "A small needle has pricked you!"));
159 take_hit(DAMAGE_NOESCAPE, damroll(1, 4), _("毒針", "a poison needle"), -1);
160 (void)do_dec_stat(A_CON);
164 if (trap & (CHEST_POISON))
166 msg_print(_("突如吹き出した緑色のガスに包み込まれた!", "A puff of green gas surrounds you!"));
167 if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))
169 (void)set_poisoned(p_ptr->poisoned + 10 + randint1(20));
174 if (trap & (CHEST_PARALYZE))
176 msg_print(_("突如吹き出した黄色いガスに包み込まれた!", "A puff of yellow gas surrounds you!"));
177 if (!p_ptr->free_act)
179 (void)set_paralyzed(p_ptr->paralyzed + 10 + randint1(20));
183 /* Summon monsters */
184 if (trap & (CHEST_SUMMON))
186 int num = 2 + randint1(3);
187 msg_print(_("突如吹き出した煙に包み込まれた!", "You are enveloped in a cloud of smoke!"));
188 for (i = 0; i < num; i++)
190 if (randint1(100)<dun_level)
191 activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
193 (void)summon_specific(0, y, x, mon_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
197 /* Elemental summon. */
198 if (trap & (CHEST_E_SUMMON))
200 msg_print(_("宝を守るためにエレメンタルが現れた!", "Elemental beings appear to protect their treasures!"));
201 for (i = 0; i < randint1(3) + 5; i++)
203 (void)summon_specific(0, y, x, mon_level, SUMMON_ELEMENTAL, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
207 /* Force clouds, then summon birds. */
208 if (trap & (CHEST_BIRD_STORM))
210 msg_print(_("鳥の群れがあなたを取り巻いた!", "A storm of birds swirls around you!"));
212 for (i = 0; i < randint1(3) + 3; i++)
213 (void)fire_meteor(-1, GF_FORCE, y, x, o_ptr->pval / 5, 7);
215 for (i = 0; i < randint1(5) + o_ptr->pval / 5; i++)
217 (void)summon_specific(0, y, x, mon_level, SUMMON_BIRD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
221 /* Various colorful summonings. */
222 if (trap & (CHEST_H_SUMMON))
227 msg_print(_("炎と硫黄の雲の中に悪魔が姿を現した!", "Demons materialize in clouds of fire and brimstone!"));
228 for (i = 0; i < randint1(3) + 2; i++)
230 (void)fire_meteor(-1, GF_FIRE, y, x, 10, 5);
231 (void)summon_specific(0, y, x, mon_level, SUMMON_DEMON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
235 /* Summon dragons. */
238 msg_print(_("暗闇にドラゴンの影がぼんやりと現れた!", "Draconic forms loom out of the darkness!"));
239 for (i = 0; i < randint1(3) + 2; i++)
241 (void)summon_specific(0, y, x, mon_level, SUMMON_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
245 /* Summon hybrids. */
248 msg_print(_("奇妙な姿の怪物が襲って来た!", "Creatures strange and twisted assault you!"));
249 for (i = 0; i < randint1(5) + 3; i++)
251 (void)summon_specific(0, y, x, mon_level, SUMMON_HYBRID, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
255 /* Summon vortices (scattered) */
258 msg_print(_("渦巻が合体し、破裂した!", "Vortices coalesce and wreak destruction!"));
259 for (i = 0; i < randint1(3) + 2; i++)
261 (void)summon_specific(0, y, x, mon_level, SUMMON_VORTEX, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
267 if ((trap & (CHEST_RUNES_OF_EVIL)) && o_ptr->k_idx)
269 /* Determine how many nasty tricks can be played. */
270 int nasty_tricks_count = 4 + randint0(3);
272 msg_print(_("恐ろしい声が響いた: 「暗闇が汝をつつまん!」", "Hideous voices bid: 'Let the darkness have thee!'"));
273 /* This is gonna hurt... */
274 for (; nasty_tricks_count > 0; nasty_tricks_count--)
276 /* ...but a high saving throw does help a little. */
277 if (randint1(100 + o_ptr->pval * 2) > p_ptr->skill_sav)
279 if (one_in_(6)) take_hit(DAMAGE_NOESCAPE, damroll(5, 20), _("破滅のトラップの宝箱", "a chest dispel-player trap"), -1);
280 else if (one_in_(5)) (void)set_cut(p_ptr->cut + 200);
283 if (!p_ptr->free_act)
284 (void)set_paralyzed(p_ptr->paralyzed + 2 +
287 (void)set_stun(p_ptr->stun + 10 +
290 else if (one_in_(3)) apply_disenchant(0);
293 (void)do_dec_stat(A_STR);
294 (void)do_dec_stat(A_DEX);
295 (void)do_dec_stat(A_CON);
296 (void)do_dec_stat(A_INT);
297 (void)do_dec_stat(A_WIS);
298 (void)do_dec_stat(A_CHR);
300 else (void)fire_meteor(-1, GF_NETHER, y, x, 150, 1);
305 /* Aggravate monsters. */
306 if (trap & (CHEST_ALARM))
308 msg_print(_("けたたましい音が鳴り響いた!", "An alarm sounds!"));
309 aggravate_monsters(0);
313 if ((trap & (CHEST_EXPLODE)) && o_ptr->k_idx)
315 msg_print(_("突然、箱が爆発した!", "There is a sudden explosion!"));
316 msg_print(_("箱の中の物はすべて粉々に砕け散った!", "Everything inside the chest is destroyed!"));
318 sound(SOUND_EXPLODE);
319 take_hit(DAMAGE_ATTACK, damroll(5, 8), _("爆発する箱", "an exploding chest"), -1);
321 /* Scatter contents. */
322 if ((trap & (CHEST_SCATTER)) && o_ptr->k_idx)
324 msg_print(_("宝箱の中身はダンジョンじゅうに散乱した!", "The contents of the chest scatter all over the dungeon!"));
325 chest_death(TRUE, y, x, o_idx);