OSDN Git Service

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