OSDN Git Service

1a461f55212703ce73b48d2d03f778e8a51c8d4a
[hengbandforosx/hengbandosx.git] / src / world / world-turn-processor.cpp
1 #include "world/world-turn-processor.h"
2 #include "cmd-building/cmd-building.h"
3 #include "cmd-io/cmd-save.h"
4 #include "core/disturbance.h"
5 #include "core/magic-effects-timeout-reducer.h"
6 #include "dungeon/dungeon.h"
7 #include "floor/floor-events.h"
8 #include "floor/floor-mode-changer.h"
9 #include "floor/wild.h"
10 #include "game-option/birth-options.h"
11 #include "game-option/cheat-options.h"
12 #include "game-option/special-options.h"
13 #include "game-option/text-display-options.h"
14 #include "grid/feature.h"
15 #include "grid/grid.h"
16 #include "hpmp/hp-mp-processor.h"
17 #include "hpmp/hp-mp-regenerator.h"
18 #include "inventory/inventory-curse.h"
19 #include "inventory/recharge-processor.h"
20 #include "io/write-diary.h"
21 #include "market/arena.h"
22 #include "market/bounty.h"
23 #include "monster-floor/monster-generator.h"
24 #include "monster-floor/monster-summon.h"
25 #include "monster/monster-describer.h"
26 #include "monster/monster-status.h"
27 #include "mutation/mutation-processor.h"
28 #include "object/lite-processor.h"
29 #include "perception/simple-perception.h"
30 #include "player/digestion-processor.h"
31 #include "player/player-status.h"
32 #include "store/store-owners.h"
33 #include "store/store-util.h"
34 #include "store/store.h"
35 #include "system/floor-type-definition.h"
36 #include "system/monster-type-definition.h"
37 #include "system/player-type-definition.h"
38 #include "term/screen-processor.h"
39 #include "term/term-color-types.h"
40 #include "util/bit-flags-calculator.h"
41 #include "view/display-messages.h"
42 #include "window/main-window-row-column.h"
43 #include "world/world-movement-processor.h"
44 #include "world/world.h"
45
46 /*!
47  * @brief 10ゲームターンが進行する毎にゲーム世界全体の処理を行う。
48  * / Handle certain things once every 10 game turns
49  * @param player_ptr プレーヤーへの参照ポインタ
50  * @return なし
51  */
52 void process_world(player_type *player_ptr)
53 {
54     const s32b A_DAY = TURNS_PER_TICK * TOWN_DAWN;
55     s32b prev_turn_in_today = ((current_world_ptr->game_turn - TURNS_PER_TICK) % A_DAY + A_DAY / 4) % A_DAY;
56     int prev_min = (1440 * prev_turn_in_today / A_DAY) % 60;
57
58     int day, hour, min;
59     extract_day_hour_min(player_ptr, &day, &hour, &min);
60     update_dungeon_feeling(player_ptr);
61
62     /* 帰還無しモード時のレベルテレポバグ対策 / Fix for level teleport bugs on ironman_downward.*/
63     floor_type *floor_ptr = player_ptr->current_floor_ptr;
64     if (ironman_downward && (player_ptr->dungeon_idx != DUNGEON_ANGBAND && player_ptr->dungeon_idx != 0)) {
65         floor_ptr->dun_level = 0;
66         player_ptr->dungeon_idx = 0;
67         prepare_change_floor_mode(player_ptr, CFM_FIRST_FLOOR | CFM_RAND_PLACE);
68         floor_ptr->inside_arena = FALSE;
69         player_ptr->wild_mode = FALSE;
70         player_ptr->leaving = TRUE;
71     }
72
73     if (player_ptr->phase_out && !player_ptr->leaving) {
74         int win_m_idx = 0;
75         int number_mon = 0;
76         for (int i2 = 0; i2 < floor_ptr->width; ++i2) {
77             for (int j2 = 0; j2 < floor_ptr->height; j2++) {
78                 grid_type *g_ptr = &floor_ptr->grid_array[j2][i2];
79                 if ((g_ptr->m_idx > 0) && (g_ptr->m_idx != player_ptr->riding)) {
80                     number_mon++;
81                     win_m_idx = g_ptr->m_idx;
82                 }
83             }
84         }
85
86         if (number_mon == 0) {
87             msg_print(_("相打ちに終わりました。", "Nothing survived."));
88             msg_print(NULL);
89             player_ptr->energy_need = 0;
90             update_gambling_monsters(player_ptr);
91         } else if ((number_mon - 1) == 0) {
92             GAME_TEXT m_name[MAX_NLEN];
93             monster_type *wm_ptr;
94             wm_ptr = &floor_ptr->m_list[win_m_idx];
95             monster_desc(player_ptr, m_name, wm_ptr, 0);
96             msg_format(_("%sが勝利した!", "%s won!"), m_name);
97             msg_print(NULL);
98
99             if (win_m_idx == (sel_monster + 1)) {
100                 msg_print(_("おめでとうございます。", "Congratulations."));
101                 msg_format(_("%d$を受け取った。", "You received %d gold."), battle_odds);
102                 player_ptr->au += battle_odds;
103             } else {
104                 msg_print(_("残念でした。", "You lost gold."));
105             }
106
107             msg_print(NULL);
108             player_ptr->energy_need = 0;
109             update_gambling_monsters(player_ptr);
110         } else if (current_world_ptr->game_turn - floor_ptr->generated_turn == 150 * TURNS_PER_TICK) {
111             msg_print(_("申し訳ありませんが、この勝負は引き分けとさせていただきます。", "Sorry, but this battle ended in a draw."));
112             player_ptr->au += kakekin;
113             msg_print(NULL);
114             player_ptr->energy_need = 0;
115             update_gambling_monsters(player_ptr);
116         }
117     }
118
119     if (current_world_ptr->game_turn % TURNS_PER_TICK)
120         return;
121
122     if (autosave_t && autosave_freq && !player_ptr->phase_out) {
123         if (!(current_world_ptr->game_turn % ((s32b)autosave_freq * TURNS_PER_TICK)))
124             do_cmd_save_game(player_ptr, TRUE);
125     }
126
127     if (floor_ptr->monster_noise && !ignore_unview) {
128         msg_print(_("何かが聞こえた。", "You hear noise."));
129     }
130
131     if (!floor_ptr->dun_level && !floor_ptr->inside_quest && !player_ptr->phase_out && !floor_ptr->inside_arena) {
132         if (!(current_world_ptr->game_turn % ((TURNS_PER_TICK * TOWN_DAWN) / 2))) {
133             bool dawn = (!(current_world_ptr->game_turn % (TURNS_PER_TICK * TOWN_DAWN)));
134             if (dawn)
135                 day_break(player_ptr);
136             else
137                 night_falls(player_ptr);
138         }
139     } else if ((vanilla_town || (lite_town && !floor_ptr->inside_quest && !player_ptr->phase_out && !floor_ptr->inside_arena)) && floor_ptr->dun_level) {
140         if (!(current_world_ptr->game_turn % (TURNS_PER_TICK * STORE_TICKS))) {
141             if (one_in_(STORE_SHUFFLE)) {
142                 int n;
143                 do {
144                     n = randint0(MAX_STORES);
145                 } while ((n == STORE_HOME) || (n == STORE_MUSEUM));
146
147                 for (FEAT_IDX i = 1; i < max_f_idx; i++) {
148                     feature_type *f_ptr = &f_info[i];
149                     if (f_ptr->name.empty())
150                         continue;
151                     if (!has_flag(f_ptr->flags, FF_STORE))
152                         continue;
153
154                     if (f_ptr->subtype == n) {
155                         if (cheat_xtra)
156                             msg_format(_("%sの店主をシャッフルします。", "Shuffle a Shopkeeper of %s."), f_ptr->name.c_str());
157
158                         store_shuffle(player_ptr, n);
159                         break;
160                     }
161                 }
162             }
163         }
164     }
165
166     if (one_in_(d_info[player_ptr->dungeon_idx].max_m_alloc_chance) && !floor_ptr->inside_arena && !floor_ptr->inside_quest && !player_ptr->phase_out) {
167         (void)alloc_monster(player_ptr, MAX_SIGHT + 5, 0, summon_specific);
168     }
169
170     if (!(current_world_ptr->game_turn % (TURNS_PER_TICK * 10)) && !player_ptr->phase_out)
171         regenerate_monsters(player_ptr);
172     if (!(current_world_ptr->game_turn % (TURNS_PER_TICK * 3)))
173         regenerate_captured_monsters(player_ptr);
174
175     if (!player_ptr->leaving) {
176         for (int i = 0; i < MAX_MTIMED; i++) {
177             if (floor_ptr->mproc_max[i] > 0)
178                 process_monsters_mtimed(player_ptr, i);
179         }
180     }
181
182     if (!hour && !min) {
183         if (min != prev_min) {
184             exe_write_diary(player_ptr, DIARY_DIALY, 0, NULL);
185             determine_daily_bounty(player_ptr, FALSE);
186         }
187     }
188
189     /*
190      * Nightmare mode activates the TY_CURSE at midnight
191      * Require exact minute -- Don't activate multiple times in a minute
192      */
193     if (ironman_nightmare && (min != prev_min)) {
194         if ((hour == 23) && !(min % 15)) {
195             disturb(player_ptr, FALSE, TRUE);
196             switch (min / 15) {
197             case 0:
198                 msg_print(_("遠くで不気味な鐘の音が鳴った。", "You hear a distant bell toll ominously."));
199                 break;
200
201             case 1:
202                 msg_print(_("遠くで鐘が二回鳴った。", "A distant bell sounds twice."));
203                 break;
204
205             case 2:
206                 msg_print(_("遠くで鐘が三回鳴った。", "A distant bell sounds three times."));
207                 break;
208
209             case 3:
210                 msg_print(_("遠くで鐘が四回鳴った。", "A distant bell tolls four times."));
211                 break;
212             }
213         }
214
215         if (!hour && !min) {
216             disturb(player_ptr, TRUE, TRUE);
217             msg_print(_("遠くで鐘が何回も鳴り、死んだような静けさの中へ消えていった。", "A distant bell tolls many times, fading into an deathly silence."));
218             if (player_ptr->wild_mode) {
219                 player_ptr->oldpy = randint1(MAX_HGT - 2);
220                 player_ptr->oldpx = randint1(MAX_WID - 2);
221                 change_wild_mode(player_ptr, TRUE);
222                 take_turn(player_ptr, 100);
223             }
224
225             player_ptr->invoking_midnight_curse = TRUE;
226         }
227     }
228
229     starve_player(player_ptr);
230     process_player_hp_mp(player_ptr);
231     reduce_magic_effects_timeout(player_ptr);
232     reduce_lite_life(player_ptr);
233     process_world_aux_mutation(player_ptr);
234     execute_cursed_items_effect(player_ptr);
235     recharge_magic_items(player_ptr);
236     sense_inventory1(player_ptr);
237     sense_inventory2(player_ptr);
238     execute_recall(player_ptr);
239     execute_floor_reset(player_ptr);
240 }
241
242 /*!
243  * @brief ゲーム時刻を表示する /
244  * Print time
245  * @return なし
246  */
247 void print_time(player_type *player_ptr)
248 {
249     int day, hour, min;
250     c_put_str(TERM_WHITE, "             ", ROW_DAY, COL_DAY);
251     extract_day_hour_min(player_ptr, &day, &hour, &min);
252     if (day < 1000)
253         c_put_str(TERM_WHITE, format(_("%2d日目", "Day%3d"), day), ROW_DAY, COL_DAY);
254     else
255         c_put_str(TERM_WHITE, _("***日目", "Day***"), ROW_DAY, COL_DAY);
256
257     c_put_str(TERM_WHITE, format("%2d:%02d", hour, min), ROW_DAY, COL_DAY + 7);
258 }