OSDN Git Service

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