OSDN Git Service

[Refactor] #40014 Separated eldritch-horror.c/h from player-status.c/h
[hengband/hengband.git] / src / cmd-building / cmd-inn.c
1 #include "cmd-building/cmd-inn.h"
2 #include "cmd-item/cmd-magiceat.h"
3 #include "core/turn-compensator.h"
4 #include "io/write-diary.h"
5 #include "market/building-actions-table.h"
6 #include "player/eldritch-horror.h"
7 #include "player/player-effects.h"
8 #include "player/player-races-table.h"
9 #include "store/rumor.h"
10 #include "world/world.h"
11
12 /*!
13  * @brief 宿屋で食事を摂る
14  * @param customer_ptr プレーヤーへの参照ポインタ
15  * @return 満腹ならFALSE、そうでないならTRUE
16  */
17 static bool buy_food(player_type *customer_ptr)
18 {
19         if (customer_ptr->food >= PY_FOOD_FULL)
20         {
21                 msg_print(_("今は満腹だ。", "You are full now."));
22                 return FALSE;
23         }
24
25         msg_print(_("バーテンはいくらかの食べ物とビールをくれた。", "The barkeep gives you some gruel and a beer."));
26         (void)set_food(customer_ptr, PY_FOOD_MAX - 1);
27         return TRUE;
28 }
29
30
31 /*!
32  * @brief 健康体しか宿屋に泊めない処理
33  * @param customer_ptr プレーヤーへの参照ポインタ
34  * @return 毒でも切り傷でもないならTRUE、そうでないならFALSE
35  */
36 static bool is_healthy_stay(player_type *customer_ptr)
37 {
38         if (!customer_ptr->poisoned && !customer_ptr->cut) return TRUE;
39
40         msg_print(_("あなたに必要なのは部屋ではなく、治療者です。", "You need a healer, not a room."));
41         msg_print(NULL);
42         msg_print(_("すみません、でもうちで誰かに死なれちゃ困りますんで。", "Sorry, but don't want anyone dying in here."));
43         return FALSE;
44 }
45
46
47 static bool is_player_undead(player_type *customer_ptr)
48 {
49         bool is_player_undead = PRACE_IS_(customer_ptr, RACE_SKELETON) ||
50                 PRACE_IS_(customer_ptr, RACE_ZOMBIE) ||
51                 PRACE_IS_(customer_ptr, RACE_VAMPIRE) ||
52                 PRACE_IS_(customer_ptr, RACE_SPECTRE);
53         return is_player_undead;
54 }
55
56
57 /*!
58  * @brief 宿屋に泊まったことを日記に残す
59  * @param customer_ptr プレーヤーへの参照ポインタ
60  * @param prev_hour 宿屋に入った直後のゲーム内時刻
61  * @return なし
62  */
63 static void write_diary_stay_inn(player_type *customer_ptr, int prev_hour)
64 {
65         if ((prev_hour >= 6) && (prev_hour < 18))
66         {
67                 concptr stay_message = _(is_player_undead(customer_ptr) ? "宿屋に泊まった。" : "日が暮れるまで宿屋で過ごした。", "stayed during the day at the inn.");
68                 exe_write_diary(customer_ptr, DIARY_DESCRIPTION, 0, stay_message);
69                 return;
70         }
71
72         concptr stay_message = _(is_player_undead(customer_ptr) ? "夜が明けるまで宿屋で過ごした。" : "宿屋に泊まった。", "stayed overnight at the inn.");
73         exe_write_diary(customer_ptr, DIARY_DESCRIPTION, 0, stay_message);
74 }
75
76
77 /*!
78  * @brief 宿泊によってゲーム内ターンを経過させる
79  * @param なし
80  * @return なし
81  */
82 static void pass_game_turn_by_stay(void)
83 {
84         s32b oldturn = current_world_ptr->game_turn;
85         current_world_ptr->game_turn =
86                 (current_world_ptr->game_turn / (TURNS_PER_TICK * TOWN_DAWN / 2) + 1) *
87                 (TURNS_PER_TICK * TOWN_DAWN / 2);
88         if (current_world_ptr->dungeon_turn >= current_world_ptr->dungeon_turn_limit)
89                 return;
90
91         current_world_ptr->dungeon_turn += MIN((current_world_ptr->game_turn - oldturn), TURNS_PER_TICK * 250) * INN_DUNGEON_TURN_ADJ;
92         if (current_world_ptr->dungeon_turn > current_world_ptr->dungeon_turn_limit)
93                 current_world_ptr->dungeon_turn = current_world_ptr->dungeon_turn_limit;
94 }
95
96
97 /*!
98  * @brief 悪夢モードなら悪夢を見せる
99  * @param customer_ptr プレーヤーへの参照ポインタ
100  * @return 悪夢モードならばTRUE
101  */
102 static bool have_a_nightmare(player_type *customer_ptr)
103 {
104         if (!ironman_nightmare) return FALSE;
105
106         msg_print(_("眠りに就くと恐ろしい光景が心をよぎった。", "Horrible visions flit through your mind as you sleep."));
107
108         while (TRUE)
109         {
110                 sanity_blast(customer_ptr, NULL, FALSE);
111                 if (!one_in_(3)) break;
112         }
113
114         msg_print(_("あなたは絶叫して目を覚ました。", "You awake screaming."));
115         exe_write_diary(customer_ptr, DIARY_DESCRIPTION, 0, _("悪夢にうなされてよく眠れなかった。", "had a nightmare."));
116         return TRUE;
117 }
118
119
120 /*!
121  * @brief 体調を元に戻す
122  * @param customer_ptr プレーヤーへの参照ポインタ
123  * @return なし
124  */
125 static void back_to_health(player_type *customer_ptr)
126 {
127         set_blind(customer_ptr, 0);
128         set_confused(customer_ptr, 0);
129         customer_ptr->stun = 0;
130         customer_ptr->chp = customer_ptr->mhp;
131         customer_ptr->csp = customer_ptr->msp;
132 }
133
134
135 /*!
136  * @brief 魔力喰いの残り回数回復(本当? 要調査)
137  * @param customer_ptr プレーヤーへの参照ポインタ
138  * @return なし
139  */
140 static void charge_magic_eating_energy(player_type *customer_ptr)
141 {
142         if (customer_ptr->pclass != CLASS_MAGIC_EATER)
143                 return;
144
145         int i;
146         for (i = 0; i < 72; i++)
147         {
148                 customer_ptr->magic_num1[i] = customer_ptr->magic_num2[i] * EATER_CHARGE;
149         }
150
151         for (; i < 108; i++)
152         {
153                 customer_ptr->magic_num1[i] = 0;
154         }
155 }
156
157
158 /*!
159  * @brief リフレッシュ結果を画面に表示する
160  * @param customer_ptr プレーヤーへの参照ポインタ
161  * @param prev_hour 宿屋に入った直後のゲーム内時刻
162  */
163 static void display_stay_result(player_type *customer_ptr, int prev_hour)
164 {
165         if ((prev_hour >= 6) && (prev_hour < 18))
166         {
167 #if JP
168                 char refresh_message_jp[50];
169                 sprintf(refresh_message_jp, "%s%s%s", "あなたはリフレッシュして目覚め、", is_player_undead(customer_ptr) ? "夜" : "夕方", "を迎えた。");
170                 msg_print(refresh_message_jp);
171 #else
172                 msg_print("You awake refreshed for the evening.");
173 #endif
174                 concptr awake_message = _(is_player_undead(customer_ptr) ? "すがすがしい夜を迎えた。" : "夕方を迎えた。", "awoke refreshed.");
175                 exe_write_diary(customer_ptr, DIARY_DESCRIPTION, 0, awake_message);
176                 return;
177         }
178
179         msg_print(_("あなたはリフレッシュして目覚め、新たな日を迎えた。", "You awake refreshed for the new day."));
180         concptr awake_message = _(is_player_undead(customer_ptr) ? "すがすがしい朝を迎えた。" : "朝を迎えた。", "awoke refreshed.");
181         exe_write_diary(customer_ptr, DIARY_DESCRIPTION, 0, awake_message);
182 }
183
184
185 /*!
186  * @brief 宿屋への宿泊実行処理
187  * @param customer_ptr プレーヤーへの参照ポインタ
188  * @return 泊まれたらTRUE
189  */
190 static bool stay_inn(player_type *customer_ptr)
191 {
192         if (!is_healthy_stay(customer_ptr)) return FALSE;
193
194         int prev_day, prev_hour, prev_min;
195         extract_day_hour_min(customer_ptr, &prev_day, &prev_hour, &prev_min);
196         write_diary_stay_inn(customer_ptr, prev_hour);
197
198         pass_game_turn_by_stay();
199         prevent_turn_overflow(customer_ptr);
200
201         if ((prev_hour >= 18) && (prev_hour <= 23))
202                 exe_write_diary(customer_ptr, DIARY_DIALY, 0, NULL);
203
204         customer_ptr->chp = customer_ptr->mhp;
205         if (have_a_nightmare(customer_ptr)) return TRUE;
206
207         back_to_health(customer_ptr);
208         charge_magic_eating_energy(customer_ptr);
209
210         display_stay_result(customer_ptr, prev_hour);
211         return TRUE;
212 }
213
214
215 /*!
216  * todo 悪夢を見る前後に全回復しているが、何か意図がある?
217  * @brief 宿屋を利用する
218  * @param customer_ptr プレーヤーへの参照ポインタ
219  * @param cmd 宿屋の利用施設ID
220  * @return 施設の利用が実際に行われたらTRUE
221  * @details inn commands
222  * Note that resting for the night was a perfect way to avoid player
223  * ghosts in the town *if* you could only make it to the inn in time (-:
224  * Now that the ghosts are temporarily disabled in 2.8.X, this function
225  * will not be that useful.  I will keep it in the hopes the player
226  * ghost code does become a reality again. Does help to avoid filthy urchins.
227  * Resting at night is also a quick way to restock stores -KMW-
228  */
229 bool inn_comm(player_type *customer_ptr, int cmd)
230 {
231         switch (cmd)
232         {
233         case BACT_FOOD:
234                 return buy_food(customer_ptr);
235         case BACT_REST:
236                 return stay_inn(customer_ptr);
237         case BACT_RUMORS:
238                 display_rumor(customer_ptr, TRUE);
239                 return TRUE;
240         default:
241                 // todo リファクタリング前のコードもTRUEだった、FALSEにすべきでは.
242                 return TRUE;
243         }
244 }