OSDN Git Service

Merge pull request #1192 from hengband/feature/3.0.0Alpha26
[hengbandforosx/hengbandosx.git] / src / player / digestion-processor.cpp
1 #include "player/digestion-processor.h"
2 #include "core/disturbance.h"
3 #include "core/player-redraw-types.h"
4 #include "core/player-update-types.h"
5 #include "core/speed-table.h"
6 #include "core/stuff-handler.h"
7 #include "floor/wild.h"
8 #include "game-option/disturbance-options.h"
9 #include "main/sound-definitions-table.h"
10 #include "main/sound-of-music.h"
11 #include "object-enchant/trc-types.h"
12 #include "player-info/avatar.h"
13 #include "player/player-damage.h"
14 #include "player/player-status.h"
15 #include "player/special-defense-types.h"
16 #include "status/bad-status-setter.h"
17 #include "system/player-type-definition.h"
18 #include "view/display-messages.h"
19 #include "world/world.h"
20
21 /*!
22  * @brief 10ゲームターンが進行するごとにプレイヤーの腹を減らす
23  * @param creature_ptr プレーヤーへの参照ポインタ
24  */
25 void starve_player(player_type *creature_ptr)
26 {
27     if (creature_ptr->phase_out)
28         return;
29
30     if (creature_ptr->food >= PY_FOOD_MAX) {
31         (void)set_food(creature_ptr, creature_ptr->food - 100);
32     } else if (!(current_world_ptr->game_turn % (TURNS_PER_TICK * 5))) {
33         int digestion = SPEED_TO_ENERGY(creature_ptr->pspeed);
34         if (creature_ptr->regenerate)
35             digestion += 20;
36         if (creature_ptr->special_defense & (KAMAE_MASK | KATA_MASK))
37             digestion += 20;
38         if (creature_ptr->cursed.has(TRC::FAST_DIGEST))
39             digestion += 30;
40
41         if (creature_ptr->slow_digest)
42             digestion -= 5;
43
44         if (digestion < 1)
45             digestion = 1;
46         if (digestion > 100)
47             digestion = 100;
48
49         (void)set_food(creature_ptr, creature_ptr->food - digestion);
50     }
51
52     if ((creature_ptr->food >= PY_FOOD_FAINT))
53         return;
54
55     if (!creature_ptr->paralyzed && (randint0(100) < 10)) {
56         msg_print(_("あまりにも空腹で気絶してしまった。", "You faint from the lack of food."));
57         disturb(creature_ptr, true, true);
58         (void)set_paralyzed(creature_ptr, creature_ptr->paralyzed + 1 + randint0(5));
59     }
60
61     if (creature_ptr->food < PY_FOOD_STARVE) {
62         HIT_POINT dam = (PY_FOOD_STARVE - creature_ptr->food) / 10;
63         if (!is_invuln(creature_ptr))
64             take_hit(creature_ptr, DAMAGE_LOSELIFE, dam, _("空腹", "starvation"));
65     }
66 }
67
68 /*!
69  * @brief 空腹状態をセットする / Set "food", notice observable changes
70  * @param v 継続時間
71  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す
72  * @details
73  * Set "", notice observable changes\n
74  *\n
75  * The "food" variable can get as large as 20000, allowing the
76  * addition of the most "filling" item, Elvish Waybread, which adds
77  * 7500 food units, without overflowing the 32767 maximum limit.\n
78  *\n
79  * Perhaps we should disturb the player with various messages,
80  * especially messages about hunger status changes.  \n
81  *\n
82  * Digestion of food is handled in "dungeon.c", in which, normally,
83  * the player digests about 20 food units per 100 game turns, more
84  * when "fast", more when "regenerating", less with "slow digestion",
85  * but when the player is "gorged", he digests 100 food units per 10
86  * game turns, or a full 1000 food units per 100 game turns.\n
87  *\n
88  * Note that the player's speed is reduced by 10 units while gorged,
89  * so if the player eats a single food ration (5000 food units) when
90  * full (15000 food units), he will be gorged for (5000/100)*10 = 500
91  * game turns, or 500/(100/5) = 25 player turns (if nothing else is
92  * affecting the player speed).\n
93  */
94 bool set_food(player_type *creature_ptr, TIME_EFFECT v)
95 {
96     int old_aux, new_aux;
97
98     bool notice = false;
99     v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;
100     if (creature_ptr->food < PY_FOOD_FAINT) {
101         old_aux = 0;
102     } else if (creature_ptr->food < PY_FOOD_WEAK) {
103         old_aux = 1;
104     } else if (creature_ptr->food < PY_FOOD_ALERT) {
105         old_aux = 2;
106     } else if (creature_ptr->food < PY_FOOD_FULL) {
107         old_aux = 3;
108     } else if (creature_ptr->food < PY_FOOD_MAX) {
109         old_aux = 4;
110     } else {
111         old_aux = 5;
112     }
113
114     if (v < PY_FOOD_FAINT) {
115         new_aux = 0;
116     } else if (v < PY_FOOD_WEAK) {
117         new_aux = 1;
118     } else if (v < PY_FOOD_ALERT) {
119         new_aux = 2;
120     } else if (v < PY_FOOD_FULL) {
121         new_aux = 3;
122     } else if (v < PY_FOOD_MAX) {
123         new_aux = 4;
124     } else {
125         new_aux = 5;
126     }
127
128     if (old_aux < 1 && new_aux > 0)
129         chg_virtue(creature_ptr, V_PATIENCE, 2);
130     else if (old_aux < 3 && (old_aux != new_aux))
131         chg_virtue(creature_ptr, V_PATIENCE, 1);
132     if (old_aux == 2)
133         chg_virtue(creature_ptr, V_TEMPERANCE, 1);
134     if (old_aux == 0)
135         chg_virtue(creature_ptr, V_TEMPERANCE, -1);
136
137     if (new_aux > old_aux) {
138         switch (new_aux) {
139         case 1:
140             msg_print(_("まだ空腹で倒れそうだ。", "You are still weak."));
141             break;
142         case 2:
143             msg_print(_("まだ空腹だ。", "You are still hungry."));
144             break;
145         case 3:
146             msg_print(_("空腹感がおさまった。", "You are no longer hungry."));
147             break;
148         case 4:
149             msg_print(_("満腹だ!", "You are full!"));
150             break;
151
152         case 5:
153             msg_print(_("食べ過ぎだ!", "You have gorged yourself!"));
154             chg_virtue(creature_ptr, V_HARMONY, -1);
155             chg_virtue(creature_ptr, V_PATIENCE, -1);
156             chg_virtue(creature_ptr, V_TEMPERANCE, -2);
157             break;
158         }
159
160         notice = true;
161     } else if (new_aux < old_aux) {
162         switch (new_aux) {
163         case 0:
164             sound(SOUND_FAINT);
165             msg_print(_("あまりにも空腹で気を失ってしまった!", "You are getting faint from hunger!"));
166             break;
167         case 1:
168             sound(SOUND_WEAK);
169             msg_print(_("お腹が空いて倒れそうだ。", "You are getting weak from hunger!"));
170             break;
171         case 2:
172             sound(SOUND_HUNGRY);
173             msg_print(_("お腹が空いてきた。", "You are getting hungry."));
174             break;
175         case 3:
176             msg_print(_("満腹感がなくなった。", "You are no longer full."));
177             break;
178         case 4:
179             msg_print(_("やっとお腹がきつくなくなった。", "You are no longer gorged."));
180             break;
181         }
182
183         if (creature_ptr->wild_mode && (new_aux < 2)) {
184             change_wild_mode(creature_ptr, false);
185         }
186
187         notice = true;
188     }
189
190     creature_ptr->food = v;
191     if (!notice)
192         return false;
193
194     if (disturb_state)
195         disturb(creature_ptr, false, false);
196     creature_ptr->update |= (PU_BONUS);
197     creature_ptr->redraw |= (PR_HUNGER);
198     handle_stuff(creature_ptr);
199
200     return true;
201 }