OSDN Git Service

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