OSDN Git Service

[Fix] #37353 take_turn()の余分なセミコロンを削除。 / Delete duplicated ';' on take_turn().
[hengband/hengband.git] / src / cmd-eat.c
1 /*!
2  * @file cmd-eat.c
3  * @brief プレイヤーの食べるコマンド実装
4  * @date 2018/09/07
5  * @details
6  * cmd6.cより分離。
7  */
8
9
10 #include "angband.h"
11 #include "object-hook.h"
12 #include "avatar.h"
13 #include "spells-status.h"
14 #include "realm-hex.h"
15 #include "player-status.h"
16
17 /*!
18  * @brief 食料を食べるコマンドのサブルーチン
19  * @param item 食べるオブジェクトの所持品ID
20  * @return なし
21  */
22 void do_cmd_eat_food_aux(INVENTORY_IDX item)
23 {
24         int ident, lev;
25         object_type *o_ptr;
26
27         if (music_singing_any()) stop_singing(p_ptr);
28         if (hex_spelling_any()) stop_hex_spell_all();
29
30         /* Get the item (in the pack) */
31         if (item >= 0)
32         {
33                 o_ptr = &inventory[item];
34         }
35
36         /* Get the item (on the floor) */
37         else
38         {
39                 o_ptr = &o_list[0 - item];
40         }
41
42         sound(SOUND_EAT);
43
44         take_turn(p_ptr, 100);
45
46         /* Identity not known yet */
47         ident = FALSE;
48
49         /* Object level */
50         lev = k_info[o_ptr->k_idx].level;
51
52         if (o_ptr->tval == TV_FOOD)
53         {
54                 /* Analyze the food */
55                 switch (o_ptr->sval)
56                 {
57                 case SV_FOOD_POISON:
58                 {
59                         if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))
60                         {
61                                 if (set_poisoned(p_ptr->poisoned + randint0(10) + 10))
62                                 {
63                                         ident = TRUE;
64                                 }
65                         }
66                         break;
67                 }
68
69                 case SV_FOOD_BLINDNESS:
70                 {
71                         if (!p_ptr->resist_blind)
72                         {
73                                 if (set_blind(p_ptr->blind + randint0(200) + 200))
74                                 {
75                                         ident = TRUE;
76                                 }
77                         }
78                         break;
79                 }
80
81                 case SV_FOOD_PARANOIA:
82                 {
83                         if (!p_ptr->resist_fear)
84                         {
85                                 if (set_afraid(p_ptr->afraid + randint0(10) + 10))
86                                 {
87                                         ident = TRUE;
88                                 }
89                         }
90                         break;
91                 }
92
93                 case SV_FOOD_CONFUSION:
94                 {
95                         if (!p_ptr->resist_conf)
96                         {
97                                 if (set_confused(p_ptr->confused + randint0(10) + 10))
98                                 {
99                                         ident = TRUE;
100                                 }
101                         }
102                         break;
103                 }
104
105                 case SV_FOOD_HALLUCINATION:
106                 {
107                         if (!p_ptr->resist_chaos)
108                         {
109                                 if (set_image(p_ptr->image + randint0(250) + 250))
110                                 {
111                                         ident = TRUE;
112                                 }
113                         }
114                         break;
115                 }
116
117                 case SV_FOOD_PARALYSIS:
118                 {
119                         if (!p_ptr->free_act)
120                         {
121                                 if (set_paralyzed(p_ptr->paralyzed + randint0(10) + 10))
122                                 {
123                                         ident = TRUE;
124                                 }
125                         }
126                         break;
127                 }
128
129                 case SV_FOOD_WEAKNESS:
130                 {
131                         take_hit(DAMAGE_NOESCAPE, damroll(6, 6), _("毒入り食料", "poisonous food"), -1);
132                         (void)do_dec_stat(A_STR);
133                         ident = TRUE;
134                         break;
135                 }
136
137                 case SV_FOOD_SICKNESS:
138                 {
139                         take_hit(DAMAGE_NOESCAPE, damroll(6, 6), _("毒入り食料", "poisonous food"), -1);
140                         (void)do_dec_stat(A_CON);
141                         ident = TRUE;
142                         break;
143                 }
144
145                 case SV_FOOD_STUPIDITY:
146                 {
147                         take_hit(DAMAGE_NOESCAPE, damroll(8, 8), _("毒入り食料", "poisonous food"), -1);
148                         (void)do_dec_stat(A_INT);
149                         ident = TRUE;
150                         break;
151                 }
152
153                 case SV_FOOD_NAIVETY:
154                 {
155                         take_hit(DAMAGE_NOESCAPE, damroll(8, 8), _("毒入り食料", "poisonous food"), -1);
156                         (void)do_dec_stat(A_WIS);
157                         ident = TRUE;
158                         break;
159                 }
160
161                 case SV_FOOD_UNHEALTH:
162                 {
163                         take_hit(DAMAGE_NOESCAPE, damroll(10, 10), _("毒入り食料", "poisonous food"), -1);
164                         (void)do_dec_stat(A_CON);
165                         ident = TRUE;
166                         break;
167                 }
168
169                 case SV_FOOD_DISEASE:
170                 {
171                         take_hit(DAMAGE_NOESCAPE, damroll(10, 10), _("毒入り食料", "poisonous food"), -1);
172                         (void)do_dec_stat(A_STR);
173                         ident = TRUE;
174                         break;
175                 }
176
177                 case SV_FOOD_CURE_POISON:
178                 {
179                         if (set_poisoned(0)) ident = TRUE;
180                         break;
181                 }
182
183                 case SV_FOOD_CURE_BLINDNESS:
184                 {
185                         if (set_blind(0)) ident = TRUE;
186                         break;
187                 }
188
189                 case SV_FOOD_CURE_PARANOIA:
190                 {
191                         if (set_afraid(0)) ident = TRUE;
192                         break;
193                 }
194
195                 case SV_FOOD_CURE_CONFUSION:
196                 {
197                         if (set_confused(0)) ident = TRUE;
198                         break;
199                 }
200
201                 case SV_FOOD_CURE_SERIOUS:
202                 {
203                         ident = cure_serious_wounds(4, 8);
204                         break;
205                 }
206
207                 case SV_FOOD_RESTORE_STR:
208                 {
209                         if (do_res_stat(A_STR)) ident = TRUE;
210                         break;
211                 }
212
213                 case SV_FOOD_RESTORE_CON:
214                 {
215                         if (do_res_stat(A_CON)) ident = TRUE;
216                         break;
217                 }
218
219                 case SV_FOOD_RESTORING:
220                 {
221                         ident = restore_all_status();
222                         break;
223                 }
224
225
226 #ifdef JP
227                 /* それぞれの食べ物の感想をオリジナルより細かく表現 */
228                 case SV_FOOD_BISCUIT:
229                 {
230                         msg_print("甘くてサクサクしてとてもおいしい。");
231                         ident = TRUE;
232                         break;
233                 }
234
235                 case SV_FOOD_JERKY:
236                 {
237                         msg_print("歯ごたえがあっておいしい。");
238                         ident = TRUE;
239                         break;
240                 }
241
242                 case SV_FOOD_SLIME_MOLD:
243                 {
244                         msg_print("これはなんとも形容しがたい味だ。");
245                         ident = TRUE;
246                         break;
247                 }
248
249                 case SV_FOOD_RATION:
250                 {
251                         msg_print("これはおいしい。");
252                         ident = TRUE;
253                         break;
254                 }
255 #else
256                 case SV_FOOD_RATION:
257                 case SV_FOOD_BISCUIT:
258                 case SV_FOOD_JERKY:
259                 case SV_FOOD_SLIME_MOLD:
260                 {
261                         msg_print("That tastes good.");
262                         ident = TRUE;
263                         break;
264                 }
265 #endif
266
267
268                 case SV_FOOD_WAYBREAD:
269                 {
270                         msg_print(_("これはひじょうに美味だ。", "That tastes good."));
271                         (void)set_poisoned(0);
272                         (void)hp_player(damroll(4, 8));
273                         ident = TRUE;
274                         break;
275                 }
276
277 #ifdef JP
278                 case SV_FOOD_PINT_OF_ALE:
279                 {
280                         msg_print("のどごし爽やかだ。");
281                         ident = TRUE;
282                         break;
283                 }
284
285                 case SV_FOOD_PINT_OF_WINE:
286                 {
287                         msg_print("That tastes good.");
288                         ident = TRUE;
289                         break;
290                 }
291 #else
292                 case SV_FOOD_PINT_OF_ALE:
293                 case SV_FOOD_PINT_OF_WINE:
294                 {
295                         msg_print("That tastes good.");
296                         ident = TRUE;
297                         break;
298                 }
299 #endif
300
301                 }
302         }
303         p_ptr->update |= (PU_COMBINE | PU_REORDER);
304
305         if (!(object_is_aware(o_ptr)))
306         {
307                 chg_virtue(V_KNOWLEDGE, -1);
308                 chg_virtue(V_PATIENCE, -1);
309                 chg_virtue(V_CHANCE, 1);
310         }
311
312         /* We have tried it */
313         if (o_ptr->tval == TV_FOOD) object_tried(o_ptr);
314
315         /* The player is now aware of the object */
316         if (ident && !object_is_aware(o_ptr))
317         {
318                 object_aware(o_ptr);
319                 gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
320         }
321
322         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
323
324
325         /* Food can feed the player */
326         if (prace_is_(RACE_VAMPIRE) || (p_ptr->mimic_form == MIMIC_VAMPIRE))
327         {
328                 /* Reduced nutritional benefit */
329                 (void)set_food(p_ptr->food + (o_ptr->pval / 10));
330                 msg_print(_("あなたのような者にとって食糧など僅かな栄養にしかならない。",
331                         "Mere victuals hold scant sustenance for a being such as yourself."));
332
333                 if (p_ptr->food < PY_FOOD_ALERT)   /* Hungry */
334                         msg_print(_("あなたの飢えは新鮮な血によってのみ満たされる!",
335                                 "Your hunger can only be satisfied with fresh blood!"));
336         }
337         else if ((prace_is_(RACE_SKELETON) ||
338                 prace_is_(RACE_GOLEM) ||
339                 prace_is_(RACE_ZOMBIE) ||
340                 prace_is_(RACE_SPECTRE)) &&
341                 (o_ptr->tval == TV_STAFF || o_ptr->tval == TV_WAND))
342         {
343                 concptr staff;
344
345                 if (o_ptr->tval == TV_STAFF &&
346                         (item < 0) && (o_ptr->number > 1))
347                 {
348                         msg_print(_("まずは杖を拾わなければ。", "You must first pick up the staffs."));
349                         return;
350                 }
351                 staff = (o_ptr->tval == TV_STAFF) ? _("杖", "staff") : _("魔法棒", "wand");
352
353                 /* "Eat" charges */
354                 if (o_ptr->pval == 0)
355                 {
356                         msg_format(_("この%sにはもう魔力が残っていない。", "The %s has no charges left."), staff);
357                         o_ptr->ident |= (IDENT_EMPTY);
358                         p_ptr->update |= (PU_COMBINE | PU_REORDER);
359                         p_ptr->window |= (PW_INVEN);
360
361                         return;
362                 }
363                 msg_format(_("あなたは%sの魔力をエネルギー源として吸収した。", "You absorb mana of the %s as your energy."), staff);
364
365                 /* Use a single charge */
366                 o_ptr->pval--;
367
368                 /* Eat a charge */
369                 set_food(p_ptr->food + 5000);
370
371                 /* XXX Hack -- unstack if necessary */
372                 if (o_ptr->tval == TV_STAFF &&
373                         (item >= 0) && (o_ptr->number > 1))
374                 {
375                         object_type forge;
376                         object_type *q_ptr;
377                         q_ptr = &forge;
378
379                         /* Obtain a local object */
380                         object_copy(q_ptr, o_ptr);
381
382                         /* Modify quantity */
383                         q_ptr->number = 1;
384
385                         /* Restore the charges */
386                         o_ptr->pval++;
387
388                         /* Unstack the used item */
389                         o_ptr->number--;
390                         p_ptr->total_weight -= q_ptr->weight;
391                         item = inven_carry(q_ptr);
392
393                         msg_format(_("杖をまとめなおした。", "You unstack your staff."));
394                 }
395
396                 /* Describe charges in the pack */
397                 if (item >= 0)
398                 {
399                         inven_item_charges(item);
400                 }
401
402                 /* Describe charges on the floor */
403                 else
404                 {
405                         floor_item_charges(0 - item);
406                 }
407
408                 p_ptr->window |= (PW_INVEN | PW_EQUIP);
409
410                 /* Don't eat a staff/wand itself */
411                 return;
412         }
413         else if ((prace_is_(RACE_DEMON) ||
414                 (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_DEMON)) &&
415                 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE &&
416                         my_strchr("pht", r_info[o_ptr->pval].d_char)))
417         {
418                 /* Drain vitality of humanoids */
419                 GAME_TEXT o_name[MAX_NLEN];
420                 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
421                 msg_format(_("%sは燃え上り灰になった。精力を吸収した気がする。", "%^s is burnt to ashes.  You absorb its vitality!"), o_name);
422                 (void)set_food(PY_FOOD_MAX - 1);
423         }
424         else if (prace_is_(RACE_SKELETON))
425         {
426 #if 0
427                 if (o_ptr->tval == TV_SKELETON ||
428                         (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
429                 {
430                         msg_print(_("あなたは骨で自分の体を補った。", "Your body absorbs the bone."));
431                         set_food(p_ptr->food + 5000);
432                 }
433                 else
434 #endif
435
436                         if (!((o_ptr->sval == SV_FOOD_WAYBREAD) ||
437                                 (o_ptr->sval < SV_FOOD_BISCUIT)))
438                         {
439                                 object_type forge;
440                                 object_type *q_ptr = &forge;
441
442                                 msg_print(_("食べ物がアゴを素通りして落ちた!", "The food falls through your jaws!"));
443                                 object_prep(q_ptr, lookup_kind(o_ptr->tval, o_ptr->sval));
444
445                                 /* Drop the object from heaven */
446                                 (void)drop_near(q_ptr, -1, p_ptr->y, p_ptr->x);
447                         }
448                         else
449                         {
450                                 msg_print(_("食べ物がアゴを素通りして落ち、消えた!", "The food falls through your jaws and vanishes!"));
451                         }
452         }
453         else if (prace_is_(RACE_GOLEM) ||
454                 prace_is_(RACE_ZOMBIE) ||
455                 prace_is_(RACE_ENT) ||
456                 prace_is_(RACE_DEMON) ||
457                 prace_is_(RACE_ANDROID) ||
458                 prace_is_(RACE_SPECTRE) ||
459                 (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))
460         {
461                 msg_print(_("生者の食物はあなたにとってほとんど栄養にならない。", "The food of mortals is poor sustenance for you."));
462                 set_food(p_ptr->food + ((o_ptr->pval) / 20));
463         }
464         else if (o_ptr->tval == TV_FOOD && o_ptr->sval == SV_FOOD_WAYBREAD)
465         {
466                 /* Waybread is always fully satisfying. */
467                 set_food(MAX(p_ptr->food, PY_FOOD_MAX - 1));
468         }
469         else
470         {
471                 /* Food can feed the player */
472                 (void)set_food(p_ptr->food + o_ptr->pval);
473         }
474
475         /* Destroy a food in the pack */
476         if (item >= 0)
477         {
478                 inven_item_increase(item, -1);
479                 inven_item_describe(item);
480                 inven_item_optimize(item);
481         }
482
483         /* Destroy a food on the floor */
484         else
485         {
486                 floor_item_increase(0 - item, -1);
487                 floor_item_describe(0 - item);
488                 floor_item_optimize(0 - item);
489         }
490 }
491
492
493 /*!
494  * @brief 食料を食べるコマンドのメインルーチン /
495  * Eat some food (from the pack or floor)
496  * @return なし
497  */
498 void do_cmd_eat_food(void)
499 {
500         OBJECT_IDX item;
501         concptr        q, s;
502
503         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
504         {
505                 set_action(ACTION_NONE);
506         }
507
508         /* Restrict choices to food */
509         item_tester_hook = item_tester_hook_eatable;
510
511         q = _("どれを食べますか? ", "Eat which item? ");
512         s = _("食べ物がない。", "You have nothing to eat.");
513
514         if (!choose_object(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
515
516         /* Eat the object */
517         do_cmd_eat_food_aux(item);
518 }
519