OSDN Git Service

[Refactor] #37287 #37353 型の置換。 / Type replacement.
[hengband/hengband.git] / src / chest.c
1 \r
2 #include "angband.h"\r
3 \r
4 /*!\r
5 * @brief \94 \82©\82ç\83A\83C\83e\83\80\82ð\88ø\82«\8fo\82· /\r
6 * Allocates objects upon opening a chest    -BEN-\r
7 * @param scatter TRUE\82È\82ç\82Î\83g\83\89\83b\83v\82É\82æ\82é\83A\83C\83e\83\80\82Ì\8ag\8eU\8f\88\97\9d\r
8 * @param y \94 \82Ì\91\8dÝ\82·\82é\83}\83X\82ÌY\8dÀ\95W\r
9 * @param x \94 \82Ì\91\8dÝ\82·\82é\83}\83X\82ÌX\8dÀ\95W\r
10 * @param o_idx \94 \82Ì\83I\83u\83W\83F\83N\83gID\r
11 * @return \82È\82µ\r
12 * @details\r
13 * <pre>\r
14 * Disperse treasures from the given chest, centered at (x,y).\r
15 *\r
16 * Small chests often contain "gold", while Large chests always contain\r
17 * items.  Wooden chests contain 2 items, Iron chests contain 4 items,\r
18 * and Steel chests contain 6 items.  The "value" of the items in a\r
19 * chest is based on the "power" of the chest, which is in turn based\r
20 * on the level on which the chest is generated.\r
21 * </pre>\r
22 */\r
23 void chest_death(bool scatter, POSITION y, POSITION x, OBJECT_IDX o_idx)\r
24 {\r
25         int number;\r
26 \r
27         bool small;\r
28         BIT_FLAGS mode = AM_GOOD;\r
29 \r
30         object_type forge;\r
31         object_type *q_ptr;\r
32 \r
33         object_type *o_ptr = &o_list[o_idx];\r
34 \r
35 \r
36         /* Small chests often hold "gold" */\r
37         small = (o_ptr->sval < SV_CHEST_MIN_LARGE);\r
38 \r
39         /* Determine how much to drop (see above) */\r
40         number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;\r
41 \r
42         if (o_ptr->sval == SV_CHEST_KANDUME)\r
43         {\r
44                 number = 5;\r
45                 small = FALSE;\r
46                 mode |= AM_GREAT;\r
47                 object_level = o_ptr->xtra3;\r
48         }\r
49         else\r
50         {\r
51                 /* Determine the "value" of the items */\r
52                 object_level = ABS(o_ptr->pval) + 10;\r
53         }\r
54 \r
55         /* Zero pval means empty chest */\r
56         if (!o_ptr->pval) number = 0;\r
57 \r
58         /* Opening a chest */\r
59         opening_chest = TRUE;\r
60 \r
61         /* Drop some objects (non-chests) */\r
62         for (; number > 0; --number)\r
63         {\r
64                 /* Get local object */\r
65                 q_ptr = &forge;\r
66 \r
67                 /* Wipe the object */\r
68                 object_wipe(q_ptr);\r
69 \r
70                 /* Small chests often drop gold */\r
71                 if (small && (randint0(100) < 25))\r
72                 {\r
73                         /* Make some gold */\r
74                         if (!make_gold(q_ptr)) continue;\r
75                 }\r
76 \r
77                 /* Otherwise drop an item */\r
78                 else\r
79                 {\r
80                         /* Make a good object */\r
81                         if (!make_object(q_ptr, mode)) continue;\r
82                 }\r
83 \r
84                 /* If chest scatters its contents, pick any floor square. */\r
85                 if (scatter)\r
86                 {\r
87                         int i;\r
88                         for (i = 0; i < 200; i++)\r
89                         {\r
90                                 /* Pick a totally random spot. */\r
91                                 y = randint0(MAX_HGT);\r
92                                 x = randint0(MAX_WID);\r
93 \r
94                                 /* Must be an empty floor. */\r
95                                 if (!cave_empty_bold(y, x)) continue;\r
96 \r
97                                 /* Place the object there. */\r
98                                 (void)drop_near(q_ptr, -1, y, x);\r
99 \r
100                                 /* Done. */\r
101                                 break;\r
102                         }\r
103                 }\r
104                 /* Normally, drop object near the chest. */\r
105                 else (void)drop_near(q_ptr, -1, y, x);\r
106         }\r
107 \r
108         /* Reset the object level */\r
109         object_level = base_level;\r
110 \r
111         /* No longer opening a chest */\r
112         opening_chest = FALSE;\r
113 \r
114         /* Empty */\r
115         o_ptr->pval = 0;\r
116 \r
117         /* Known */\r
118         object_known(o_ptr);\r
119 }\r
120 \r
121 \r
122 /*!\r
123 * @brief \94 \82Ì\83g\83\89\83b\83v\8f\88\97\9d /\r
124 * Chests have traps too.\r
125 * @param y \94 \82Ì\91\8dÝ\82·\82é\83}\83X\82ÌY\8dÀ\95W\r
126 * @param x \94 \82Ì\91\8dÝ\82·\82é\83}\83X\82ÌX\8dÀ\95W\r
127 * @param o_idx \94 \82Ì\83I\83u\83W\83F\83N\83gID\r
128 * @return \82È\82µ\r
129 * @details\r
130 * <pre>\r
131 * Exploding chest destroys contents (and traps).\r
132 * Note that the chest itself is never destroyed.\r
133 * </pre>\r
134 */\r
135 void chest_trap(POSITION y, POSITION x, OBJECT_IDX o_idx)\r
136 {\r
137         int i, trap;\r
138 \r
139         object_type *o_ptr = &o_list[o_idx];\r
140 \r
141         int mon_level = o_ptr->xtra3;\r
142 \r
143         /* Ignore disarmed chests */\r
144         if (o_ptr->pval <= 0) return;\r
145 \r
146         /* Obtain the traps */\r
147         trap = chest_traps[o_ptr->pval];\r
148 \r
149         /* Lose strength */\r
150         if (trap & (CHEST_LOSE_STR))\r
151         {\r
152                 msg_print(_("\8ed\8a|\82¯\82ç\82ê\82Ä\82¢\82½\8f¬\82³\82È\90j\82É\8eh\82³\82ê\82Ä\82µ\82Ü\82Á\82½\81I", "A small needle has pricked you!"));\r
153                 take_hit(DAMAGE_NOESCAPE, damroll(1, 4), _("\93Å\90j", "a poison needle"), -1);\r
154                 (void)do_dec_stat(A_STR);\r
155         }\r
156 \r
157         /* Lose constitution */\r
158         if (trap & (CHEST_LOSE_CON))\r
159         {\r
160                 msg_print(_("\8ed\8a|\82¯\82ç\82ê\82Ä\82¢\82½\8f¬\82³\82È\90j\82É\8eh\82³\82ê\82Ä\82µ\82Ü\82Á\82½\81I", "A small needle has pricked you!"));\r
161                 take_hit(DAMAGE_NOESCAPE, damroll(1, 4), _("\93Å\90j", "a poison needle"), -1);\r
162                 (void)do_dec_stat(A_CON);\r
163         }\r
164 \r
165         /* Poison */\r
166         if (trap & (CHEST_POISON))\r
167         {\r
168                 msg_print(_("\93Ë\94@\90\81\82«\8fo\82µ\82½\97Î\90F\82Ì\83K\83X\82É\95ï\82Ý\8d\9e\82Ü\82ê\82½\81I", "A puff of green gas surrounds you!"));\r
169                 if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))\r
170                 {\r
171                         (void)set_poisoned(p_ptr->poisoned + 10 + randint1(20));\r
172                 }\r
173         }\r
174 \r
175         /* Paralyze */\r
176         if (trap & (CHEST_PARALYZE))\r
177         {\r
178                 msg_print(_("\93Ë\94@\90\81\82«\8fo\82µ\82½\89©\90F\82¢\83K\83X\82É\95ï\82Ý\8d\9e\82Ü\82ê\82½\81I", "A puff of yellow gas surrounds you!"));\r
179                 if (!p_ptr->free_act)\r
180                 {\r
181                         (void)set_paralyzed(p_ptr->paralyzed + 10 + randint1(20));\r
182                 }\r
183         }\r
184 \r
185         /* Summon monsters */\r
186         if (trap & (CHEST_SUMMON))\r
187         {\r
188                 int num = 2 + randint1(3);\r
189                 msg_print(_("\93Ë\94@\90\81\82«\8fo\82µ\82½\89\8c\82É\95ï\82Ý\8d\9e\82Ü\82ê\82½\81I", "You are enveloped in a cloud of smoke!"));\r
190                 for (i = 0; i < num; i++)\r
191                 {\r
192                         if (randint1(100)<dun_level)\r
193                                 activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);\r
194                         else\r
195                                 (void)summon_specific(0, y, x, mon_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
196                 }\r
197         }\r
198 \r
199         /* Elemental summon. */\r
200         if (trap & (CHEST_E_SUMMON))\r
201         {\r
202                 msg_print(_("\95ó\82ð\8eç\82é\82½\82ß\82É\83G\83\8c\83\81\83\93\83^\83\8b\82ª\8c»\82ê\82½\81I", "Elemental beings appear to protect their treasures!"));\r
203                 for (i = 0; i < randint1(3) + 5; i++)\r
204                 {\r
205                         (void)summon_specific(0, y, x, mon_level, SUMMON_ELEMENTAL, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
206                 }\r
207         }\r
208 \r
209         /* Force clouds, then summon birds. */\r
210         if (trap & (CHEST_BIRD_STORM))\r
211         {\r
212                 msg_print(_("\92¹\82Ì\8cQ\82ê\82ª\82 \82È\82½\82ð\8eæ\82è\8aª\82¢\82½\81I", "A storm of birds swirls around you!"));\r
213 \r
214                 for (i = 0; i < randint1(3) + 3; i++)\r
215                         (void)fire_meteor(-1, GF_FORCE, y, x, o_ptr->pval / 5, 7);\r
216 \r
217                 for (i = 0; i < randint1(5) + o_ptr->pval / 5; i++)\r
218                 {\r
219                         (void)summon_specific(0, y, x, mon_level, SUMMON_BIRD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
220                 }\r
221         }\r
222 \r
223         /* Various colorful summonings. */\r
224         if (trap & (CHEST_H_SUMMON))\r
225         {\r
226                 /* Summon demons. */\r
227                 if (one_in_(4))\r
228                 {\r
229                         msg_print(_("\89\8a\82Æ\97°\89©\82Ì\89_\82Ì\92\86\82É\88«\96\82\82ª\8ep\82ð\8c»\82µ\82½\81I", "Demons materialize in clouds of fire and brimstone!"));\r
230                         for (i = 0; i < randint1(3) + 2; i++)\r
231                         {\r
232                                 (void)fire_meteor(-1, GF_FIRE, y, x, 10, 5);\r
233                                 (void)summon_specific(0, y, x, mon_level, SUMMON_DEMON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
234                         }\r
235                 }\r
236 \r
237                 /* Summon dragons. */\r
238                 else if (one_in_(3))\r
239                 {\r
240                         msg_print(_("\88Ã\88Å\82É\83h\83\89\83S\83\93\82Ì\89e\82ª\82Ú\82ñ\82â\82è\82Æ\8c»\82ê\82½\81I", "Draconic forms loom out of the darkness!"));\r
241                         for (i = 0; i < randint1(3) + 2; i++)\r
242                         {\r
243                                 (void)summon_specific(0, y, x, mon_level, SUMMON_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
244                         }\r
245                 }\r
246 \r
247                 /* Summon hybrids. */\r
248                 else if (one_in_(2))\r
249                 {\r
250                         msg_print(_("\8aï\96­\82È\8ep\82Ì\89ö\95¨\82ª\8fP\82Á\82Ä\97\88\82½\81I", "Creatures strange and twisted assault you!"));\r
251                         for (i = 0; i < randint1(5) + 3; i++)\r
252                         {\r
253                                 (void)summon_specific(0, y, x, mon_level, SUMMON_HYBRID, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
254                         }\r
255                 }\r
256 \r
257                 /* Summon vortices (scattered) */\r
258                 else\r
259                 {\r
260                         msg_print(_("\89Q\8aª\82ª\8d\87\91Ì\82µ\81A\94j\97ô\82µ\82½\81I", "Vortices coalesce and wreak destruction!"));\r
261                         for (i = 0; i < randint1(3) + 2; i++)\r
262                         {\r
263                                 (void)summon_specific(0, y, x, mon_level, SUMMON_VORTEX, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));\r
264                         }\r
265                 }\r
266         }\r
267 \r
268         /* Dispel player. */\r
269         if ((trap & (CHEST_RUNES_OF_EVIL)) && o_ptr->k_idx)\r
270         {\r
271                 /* Determine how many nasty tricks can be played. */\r
272                 int nasty_tricks_count = 4 + randint0(3);\r
273 \r
274                 /* Message. */\r
275                 msg_print(_("\8b°\82ë\82µ\82¢\90º\82ª\8b¿\82¢\82½:  \81u\88Ã\88Å\82ª\93ð\82ð\82Â\82Â\82Ü\82ñ\81I\81v", "Hideous voices bid:  'Let the darkness have thee!'"));\r
276                 /* This is gonna hurt... */\r
277                 for (; nasty_tricks_count > 0; nasty_tricks_count--)\r
278                 {\r
279                         /* ...but a high saving throw does help a little. */\r
280                         if (randint1(100 + o_ptr->pval * 2) > p_ptr->skill_sav)\r
281                         {\r
282                                 if (one_in_(6)) take_hit(DAMAGE_NOESCAPE, damroll(5, 20), _("\94j\96Å\82Ì\83g\83\89\83b\83v\82Ì\95ó\94 ", "a chest dispel-player trap"), -1);\r
283                                 else if (one_in_(5)) (void)set_cut(p_ptr->cut + 200);\r
284                                 else if (one_in_(4))\r
285                                 {\r
286                                         if (!p_ptr->free_act)\r
287                                                 (void)set_paralyzed(p_ptr->paralyzed + 2 +\r
288                                                         randint0(6));\r
289                                         else\r
290                                                 (void)set_stun(p_ptr->stun + 10 +\r
291                                                         randint0(100));\r
292                                 }\r
293                                 else if (one_in_(3)) apply_disenchant(0);\r
294                                 else if (one_in_(2))\r
295                                 {\r
296                                         (void)do_dec_stat(A_STR);\r
297                                         (void)do_dec_stat(A_DEX);\r
298                                         (void)do_dec_stat(A_CON);\r
299                                         (void)do_dec_stat(A_INT);\r
300                                         (void)do_dec_stat(A_WIS);\r
301                                         (void)do_dec_stat(A_CHR);\r
302                                 }\r
303                                 else (void)fire_meteor(-1, GF_NETHER, y, x, 150, 1);\r
304                         }\r
305                 }\r
306         }\r
307 \r
308         /* Aggravate monsters. */\r
309         if (trap & (CHEST_ALARM))\r
310         {\r
311                 msg_print(_("\82¯\82½\82½\82Ü\82µ\82¢\89¹\82ª\96Â\82è\8b¿\82¢\82½\81I", "An alarm sounds!"));\r
312                 aggravate_monsters(0);\r
313         }\r
314 \r
315         /* Explode */\r
316         if ((trap & (CHEST_EXPLODE)) && o_ptr->k_idx)\r
317         {\r
318                 msg_print(_("\93Ë\91R\81A\94 \82ª\94\9a\94­\82µ\82½\81I", "There is a sudden explosion!"));\r
319                 msg_print(_("\94 \82Ì\92\86\82Ì\95¨\82Í\82·\82×\82Ä\95²\81X\82É\8dÓ\82¯\8eU\82Á\82½\81I", "Everything inside the chest is destroyed!"));\r
320                 o_ptr->pval = 0;\r
321                 sound(SOUND_EXPLODE);\r
322                 take_hit(DAMAGE_ATTACK, damroll(5, 8), _("\94\9a\94­\82·\82é\94 ", "an exploding chest"), -1);\r
323         }\r
324         /* Scatter contents. */\r
325         if ((trap & (CHEST_SCATTER)) && o_ptr->k_idx)\r
326         {\r
327                 msg_print(_("\95ó\94 \82Ì\92\86\90g\82Í\83_\83\93\83W\83\87\83\93\82\82ã\82¤\82É\8eU\97\90\82µ\82½\81I", "The contents of the chest scatter all over the dungeon!"));\r
328                 chest_death(TRUE, y, x, o_idx);\r
329                 o_ptr->pval = 0;\r
330         }\r
331 }\r
332 \r