OSDN Git Service

df69a93708c88ba5bf58fb073aea48d38ce61641
[hengband/hengband.git] / src / core / player-processor.c
1 #include "core/player-processor.h"
2 #include "mind/mind-sniper.h"
3 #include "core/special-internal-keys.h"
4 #include "core/stuff-handler.h"
5 #include "floor/wild.h"
6 #include "inventory/pack-overflow.h"
7 #include "io/input-key-processor.h"
8 #include "mind/mind-force-trainer.h"
9 #include "monster/creature.h"
10 #include "monster-race/monster-race-hook.h"
11 #include "monster/monster-flag-types.h"
12 #include "monster/monster-status.h"
13 #include "mutation/mutation.h"
14 #include "player/player-effects.h"
15 #include "player/player-move.h"
16 #include "player/player-skill.h"
17 #include "spell/music-checker.h"
18 #include "spell-kind/spells-random.h"
19 #include "spell-realm/spells-hex.h"
20 #include "view/display-main-window.h"
21
22 bool load = TRUE;
23 bool can_save = FALSE;
24 bool repair_monsters; // todo より適切なファイルへ移設する可能性あり.
25
26 static void process_fishing(player_type *creature_ptr)
27 {
28     Term_xtra(TERM_XTRA_DELAY, 10);
29     if (one_in_(1000)) {
30         MONRACE_IDX r_idx;
31         bool success = FALSE;
32         get_mon_num_prep(creature_ptr, monster_is_fishing_target, NULL);
33         r_idx = get_mon_num(creature_ptr,
34             creature_ptr->current_floor_ptr->dun_level ? creature_ptr->current_floor_ptr->dun_level
35                                                        : wilderness[creature_ptr->wilderness_y][creature_ptr->wilderness_x].level,
36             0);
37         msg_print(NULL);
38         if (r_idx && one_in_(2)) {
39             POSITION y, x;
40             y = creature_ptr->y + ddy[creature_ptr->fishing_dir];
41             x = creature_ptr->x + ddx[creature_ptr->fishing_dir];
42             if (place_monster_aux(creature_ptr, 0, y, x, r_idx, PM_NO_KAGE)) {
43                 GAME_TEXT m_name[MAX_NLEN];
44                 monster_desc(creature_ptr, m_name, &creature_ptr->current_floor_ptr->m_list[creature_ptr->current_floor_ptr->grid_array[y][x].m_idx], 0);
45                 msg_format(_("%sが釣れた!", "You have a good catch!"), m_name);
46                 success = TRUE;
47             }
48         }
49
50         if (!success) {
51             msg_print(_("餌だけ食われてしまった!くっそ~!", "Damn!  The fish stole your bait!"));
52         }
53
54         disturb(creature_ptr, FALSE, TRUE);
55     }
56 }
57
58 /*!
59  * @brief プレイヤーの行動処理 / Process the player
60  * @return なし
61  * @note
62  * Notice the annoying code to handle "pack overflow", which\n
63  * must come first just in case somebody manages to corrupt\n
64  * the savefiles by clever use of menu commands or something.\n
65  */
66 void process_player(player_type *creature_ptr)
67 {
68     if (creature_ptr->hack_mutation) {
69         msg_print(_("何か変わった気がする!", "You feel different!"));
70
71         (void)gain_mutation(creature_ptr, 0);
72         creature_ptr->hack_mutation = FALSE;
73     }
74
75     if (creature_ptr->invoking_midnight_curse) {
76         int count = 0;
77         activate_ty_curse(creature_ptr, FALSE, &count);
78         creature_ptr->invoking_midnight_curse = FALSE;
79     }
80
81     if (creature_ptr->phase_out) {
82         for (MONSTER_IDX m_idx = 1; m_idx < creature_ptr->current_floor_ptr->m_max; m_idx++) {
83             monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
84             if (!monster_is_valid(m_ptr))
85                 continue;
86
87             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
88             update_monster(creature_ptr, m_idx, FALSE);
89         }
90
91         print_time(creature_ptr);
92     } else if (!(load && creature_ptr->energy_need <= 0)) {
93         creature_ptr->energy_need -= SPEED_TO_ENERGY(creature_ptr->pspeed);
94     }
95
96     if (creature_ptr->energy_need > 0)
97         return;
98     if (!command_rep)
99         print_time(creature_ptr);
100
101     if (creature_ptr->resting < 0) {
102         if (creature_ptr->resting == COMMAND_ARG_REST_FULL_HEALING) {
103             if ((creature_ptr->chp == creature_ptr->mhp) && (creature_ptr->csp >= creature_ptr->msp)) {
104                 set_action(creature_ptr, ACTION_NONE);
105             }
106         } else if (creature_ptr->resting == COMMAND_ARG_REST_UNTIL_DONE) {
107             if ((creature_ptr->chp == creature_ptr->mhp) && (creature_ptr->csp >= creature_ptr->msp) && !creature_ptr->blind && !creature_ptr->confused
108                 && !creature_ptr->poisoned && !creature_ptr->afraid && !creature_ptr->stun && !creature_ptr->cut && !creature_ptr->slow
109                 && !creature_ptr->paralyzed && !creature_ptr->image && !creature_ptr->word_recall && !creature_ptr->alter_reality) {
110                 set_action(creature_ptr, ACTION_NONE);
111             }
112         }
113     }
114
115     if (creature_ptr->action == ACTION_FISH)
116         process_fishing(creature_ptr);
117
118     if (check_abort) {
119         if (creature_ptr->running || travel.run || command_rep || (creature_ptr->action == ACTION_REST) || (creature_ptr->action == ACTION_FISH)) {
120             inkey_scan = TRUE;
121             if (inkey()) {
122                 flush();
123                 disturb(creature_ptr, FALSE, TRUE);
124                 msg_print(_("中断しました。", "Canceled."));
125             }
126         }
127     }
128
129     if (creature_ptr->riding && !creature_ptr->confused && !creature_ptr->blind) {
130         monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
131         monster_race *r_ptr = &r_info[m_ptr->r_idx];
132         if (MON_CSLEEP(m_ptr)) {
133             GAME_TEXT m_name[MAX_NLEN];
134             (void)set_monster_csleep(creature_ptr, creature_ptr->riding, 0);
135             monster_desc(creature_ptr, m_name, m_ptr, 0);
136             msg_format(_("%^sを起こした。", "You have woken %s up."), m_name);
137         }
138
139         if (MON_STUNNED(m_ptr)) {
140             if (set_monster_stunned(
141                     creature_ptr, creature_ptr->riding, (randint0(r_ptr->level) < creature_ptr->skill_exp[GINOU_RIDING]) ? 0 : (MON_STUNNED(m_ptr) - 1))) {
142                 GAME_TEXT m_name[MAX_NLEN];
143                 monster_desc(creature_ptr, m_name, m_ptr, 0);
144                 msg_format(_("%^sを朦朧状態から立ち直らせた。", "%^s is no longer stunned."), m_name);
145             }
146         }
147
148         if (MON_CONFUSED(m_ptr)) {
149             if (set_monster_confused(
150                     creature_ptr, creature_ptr->riding, (randint0(r_ptr->level) < creature_ptr->skill_exp[GINOU_RIDING]) ? 0 : (MON_CONFUSED(m_ptr) - 1))) {
151                 GAME_TEXT m_name[MAX_NLEN];
152                 monster_desc(creature_ptr, m_name, m_ptr, 0);
153                 msg_format(_("%^sを混乱状態から立ち直らせた。", "%^s is no longer confused."), m_name);
154             }
155         }
156
157         if (MON_MONFEAR(m_ptr)) {
158             if (set_monster_monfear(
159                     creature_ptr, creature_ptr->riding, (randint0(r_ptr->level) < creature_ptr->skill_exp[GINOU_RIDING]) ? 0 : (MON_MONFEAR(m_ptr) - 1))) {
160                 GAME_TEXT m_name[MAX_NLEN];
161                 monster_desc(creature_ptr, m_name, m_ptr, 0);
162                 msg_format(_("%^sを恐怖から立ち直らせた。", "%^s is no longer afraid."), m_name);
163             }
164         }
165
166         handle_stuff(creature_ptr);
167     }
168
169     load = FALSE;
170     if (creature_ptr->lightspeed) {
171         (void)set_lightspeed(creature_ptr, creature_ptr->lightspeed - 1, TRUE);
172     }
173
174     if ((creature_ptr->pclass == CLASS_FORCETRAINER) && get_current_ki(creature_ptr)) {
175         if (get_current_ki(creature_ptr) < 40)
176             set_current_ki(creature_ptr, TRUE, 0);
177         else
178             set_current_ki(creature_ptr, FALSE, -40);
179         creature_ptr->update |= (PU_BONUS);
180     }
181
182     if (creature_ptr->action == ACTION_LEARN) {
183         s32b cost = 0L;
184         u32b cost_frac = (creature_ptr->msp + 30L) * 256L;
185         s64b_LSHIFT(cost, cost_frac, 16);
186         if (s64b_cmp(creature_ptr->csp, creature_ptr->csp_frac, cost, cost_frac) < 0) {
187             creature_ptr->csp = 0;
188             creature_ptr->csp_frac = 0;
189             set_action(creature_ptr, ACTION_NONE);
190         } else {
191             s64b_sub(&(creature_ptr->csp), &(creature_ptr->csp_frac), cost, cost_frac);
192         }
193
194         creature_ptr->redraw |= PR_MANA;
195     }
196
197     if (creature_ptr->special_defense & KATA_MASK) {
198         if (creature_ptr->special_defense & KATA_MUSOU) {
199             if (creature_ptr->csp < 3) {
200                 set_action(creature_ptr, ACTION_NONE);
201             } else {
202                 creature_ptr->csp -= 2;
203                 creature_ptr->redraw |= (PR_MANA);
204             }
205         }
206     }
207
208     /*** Handle actual user input ***/
209     while (creature_ptr->energy_need <= 0) {
210         creature_ptr->window |= PW_PLAYER;
211         creature_ptr->sutemi = FALSE;
212         creature_ptr->counter = FALSE;
213         creature_ptr->now_damaged = FALSE;
214
215         handle_stuff(creature_ptr);
216         move_cursor_relative(creature_ptr->y, creature_ptr->x);
217         if (fresh_before)
218             Term_fresh();
219
220         pack_overflow(creature_ptr);
221         if (!command_new)
222             command_see = FALSE;
223
224         free_turn(creature_ptr);
225         if (creature_ptr->phase_out) {
226             move_cursor_relative(creature_ptr->y, creature_ptr->x);
227             command_cmd = SPECIAL_KEY_BUILDING;
228             process_command(creature_ptr);
229         } else if (creature_ptr->paralyzed || (creature_ptr->stun >= 100)) {
230             take_turn(creature_ptr, 100);
231         } else if (creature_ptr->action == ACTION_REST) {
232             if (creature_ptr->resting > 0) {
233                 creature_ptr->resting--;
234                 if (!creature_ptr->resting)
235                     set_action(creature_ptr, ACTION_NONE);
236                 creature_ptr->redraw |= (PR_STATE);
237             }
238
239             take_turn(creature_ptr, 100);
240         } else if (creature_ptr->action == ACTION_FISH) {
241             take_turn(creature_ptr, 100);
242         } else if (creature_ptr->running) {
243             run_step(creature_ptr, 0);
244         } else if (travel.run) {
245             travel_step(creature_ptr);
246         } else if (command_rep) {
247             command_rep--;
248             creature_ptr->redraw |= (PR_STATE);
249             handle_stuff(creature_ptr);
250             msg_flag = FALSE;
251             prt("", 0, 0);
252             process_command(creature_ptr);
253         } else {
254             move_cursor_relative(creature_ptr->y, creature_ptr->x);
255             can_save = TRUE;
256             request_command(creature_ptr, FALSE);
257             can_save = FALSE;
258             process_command(creature_ptr);
259         }
260
261         pack_overflow(creature_ptr);
262         if (creature_ptr->energy_use) {
263             if (creature_ptr->timewalk || creature_ptr->energy_use > 400) {
264                 creature_ptr->energy_need += creature_ptr->energy_use * TURNS_PER_TICK / 10;
265             } else {
266                 creature_ptr->energy_need += (s16b)((s32b)creature_ptr->energy_use * ENERGY_NEED() / 100L);
267             }
268
269             if (creature_ptr->image)
270                 creature_ptr->redraw |= (PR_MAP);
271
272             for (MONSTER_IDX m_idx = 1; m_idx < creature_ptr->current_floor_ptr->m_max; m_idx++) {
273                 monster_type *m_ptr;
274                 monster_race *r_ptr;
275                 m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
276                 if (!monster_is_valid(m_ptr))
277                     continue;
278                 if (!m_ptr->ml)
279                     continue;
280
281                 r_ptr = &r_info[m_ptr->ap_r_idx];
282                 if (!(r_ptr->flags1 & (RF1_ATTR_MULTI | RF1_SHAPECHANGER)))
283                     continue;
284
285                 lite_spot(creature_ptr, m_ptr->fy, m_ptr->fx);
286             }
287
288             if (repair_monsters) {
289                 repair_monsters = FALSE;
290                 for (MONSTER_IDX m_idx = 1; m_idx < creature_ptr->current_floor_ptr->m_max; m_idx++) {
291                     monster_type *m_ptr;
292                     m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
293                     if (!monster_is_valid(m_ptr))
294                         continue;
295
296                     if (m_ptr->mflag & MFLAG_NICE) {
297                         m_ptr->mflag &= ~(MFLAG_NICE);
298                     }
299
300                     if (m_ptr->mflag2 & MFLAG2_MARK) {
301                         if (m_ptr->mflag2 & MFLAG2_SHOW) {
302                             m_ptr->mflag2 &= ~(MFLAG2_SHOW);
303                             repair_monsters = TRUE;
304                         } else {
305                             m_ptr->mflag2 &= ~(MFLAG2_MARK);
306                             m_ptr->ml = FALSE;
307                             update_monster(creature_ptr, m_idx, FALSE);
308                             if (creature_ptr->health_who == m_idx)
309                                 creature_ptr->redraw |= (PR_HEALTH);
310                             if (creature_ptr->riding == m_idx)
311                                 creature_ptr->redraw |= (PR_UHEALTH);
312
313                             lite_spot(creature_ptr, m_ptr->fy, m_ptr->fx);
314                         }
315                     }
316                 }
317             }
318
319             if (creature_ptr->pclass == CLASS_IMITATOR) {
320                 if (creature_ptr->mane_num > (creature_ptr->lev > 44 ? 3 : creature_ptr->lev > 29 ? 2 : 1)) {
321                     creature_ptr->mane_num--;
322                     for (int j = 0; j < creature_ptr->mane_num; j++) {
323                         creature_ptr->mane_spell[j] = creature_ptr->mane_spell[j + 1];
324                         creature_ptr->mane_dam[j] = creature_ptr->mane_dam[j + 1];
325                     }
326                 }
327
328                 creature_ptr->new_mane = FALSE;
329                 creature_ptr->redraw |= (PR_IMITATION);
330             }
331
332             if (creature_ptr->action == ACTION_LEARN) {
333                 creature_ptr->new_mane = FALSE;
334                 creature_ptr->redraw |= (PR_STATE);
335             }
336
337             if (creature_ptr->timewalk && (creature_ptr->energy_need > -1000)) {
338
339                 creature_ptr->redraw |= (PR_MAP);
340                 creature_ptr->update |= (PU_MONSTERS);
341                 creature_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
342
343                 msg_print(_("「時は動きだす…」", "You feel time flowing around you once more."));
344                 msg_print(NULL);
345                 creature_ptr->timewalk = FALSE;
346                 creature_ptr->energy_need = ENERGY_NEED();
347
348                 handle_stuff(creature_ptr);
349             }
350         }
351
352         if (!creature_ptr->playing || creature_ptr->is_dead) {
353             creature_ptr->timewalk = FALSE;
354             break;
355         }
356
357         if (creature_ptr->energy_use && creature_ptr->reset_concent)
358             reset_concentration(creature_ptr, TRUE);
359
360         if (creature_ptr->leaving)
361             break;
362     }
363
364     update_smell(creature_ptr->current_floor_ptr, creature_ptr);
365 }
366
367 /*!
368  * @brief プレイヤーの行動エネルギーが充填される(=プレイヤーのターンが回る)毎に行われる処理  / process the effects per 100 energy at player speed.
369  * @return なし
370  */
371 void process_upkeep_with_speed(player_type *creature_ptr)
372 {
373     if (!load && creature_ptr->enchant_energy_need > 0 && !creature_ptr->leaving) {
374         creature_ptr->enchant_energy_need -= SPEED_TO_ENERGY(creature_ptr->pspeed);
375     }
376
377     if (creature_ptr->enchant_energy_need > 0)
378         return;
379
380     while (creature_ptr->enchant_energy_need <= 0) {
381         if (!load)
382             check_music(creature_ptr);
383         if (!load)
384             check_hex(creature_ptr);
385         if (!load)
386             revenge_spell(creature_ptr);
387
388         creature_ptr->enchant_energy_need += ENERGY_NEED();
389     }
390 }