OSDN Git Service

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