OSDN Git Service

Merge remote-tracking branch 'remotes/origin/For2.2.2-Fix-Hourier' into For2.2.2...
[hengband/hengband.git] / src / monster-floor / monster-move.c
1 /*!
2  * @brief モンスターの移動に関する処理
3  * @date 2020/03/08
4  * @author Hourier
5  */
6
7 #include "monster-floor/monster-move.h"
8 #include "core/disturbance.h"
9 #include "core/player-update-types.h"
10 #include "core/speed-table.h"
11 #include "core/window-redrawer.h"
12 #include "effect/effect-characteristics.h"
13 #include "floor/cave.h"
14 #include "floor/floor.h"
15 #include "game-option/disturbance-options.h"
16 #include "grid/feature.h"
17 #include "io/files-util.h"
18 #include "monster-attack/monster-attack-processor.h"
19 #include "monster-floor/monster-object.h"
20 #include "monster-race/monster-race.h"
21 #include "monster-race/race-flags1.h"
22 #include "monster-race/race-flags2.h"
23 #include "monster-race/race-flags7.h"
24 #include "monster-race/race-flags8.h"
25 #include "monster-race/race-indice-types.h"
26 #include "monster/monster-describer.h"
27 #include "monster/monster-flag-types.h"
28 #include "monster/monster-info.h"
29 #include "monster/monster-status.h"
30 #include "monster/monster-update.h"
31 #include "pet/pet-util.h"
32 #include "spell/process-effect.h"
33 #include "spell/spell-types.h"
34 #include "system/floor-type-definition.h"
35 #include "util/bit-flags-calculator.h"
36 #include "view/display-messages.h"
37
38 static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
39 {
40         return !have_flag(f_ptr->flags, FF_GLASS) ||
41                 (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) ||
42                 (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200));
43 }
44
45
46 /*!
47   * @brief モンスターによる壁の透過・破壊を行う
48   * @param target_ptr プレーヤーへの参照ポインタ
49   * @param m_ptr モンスターへの参照ポインタ
50   * @param ny モンスターのY座標
51   * @param nx モンスターのX座標
52   * @param can_cross モンスターが地形を踏破できるならばTRUE
53   * @return 透過も破壊もしなかった場合はFALSE、それ以外はTRUE
54   */
55 static bool process_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx, bool can_cross)
56 {
57         monster_race *r_ptr = &r_info[m_ptr->r_idx];
58         grid_type *g_ptr;
59         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
60         feature_type *f_ptr;
61         f_ptr = &f_info[g_ptr->feat];
62         if (player_bold(target_ptr, ny, nx))
63         {
64                 turn_flags_ptr->do_move = TRUE;
65                 return TRUE;
66         }
67
68         if (g_ptr->m_idx > 0)
69         {
70                 turn_flags_ptr->do_move = TRUE;
71                 return TRUE;
72         }
73
74         if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) &&
75                 (can_cross ? !have_flag(f_ptr->flags, FF_LOS) : !turn_flags_ptr->is_riding_mon) &&
76                 have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT) &&
77                 check_hp_for_feat_destruction(f_ptr, m_ptr))
78         {
79                 turn_flags_ptr->do_move = TRUE;
80                 if (!can_cross) turn_flags_ptr->must_alter_to_move = TRUE;
81
82                 turn_flags_ptr->did_kill_wall = TRUE;
83                 return TRUE;
84         }
85
86         if (!can_cross) return FALSE;
87
88         turn_flags_ptr->do_move = TRUE;
89         if (((r_ptr->flags2 & RF2_PASS_WALL) != 0) && (!turn_flags_ptr->is_riding_mon || target_ptr->pass_wall) &&
90                 have_flag(f_ptr->flags, FF_CAN_PASS))
91         {
92                 turn_flags_ptr->did_pass_wall = TRUE;
93         }
94
95         return TRUE;
96 }
97
98
99 /*!
100  * @brief モンスターが普通のドアを開ける処理
101  * @param target_ptr プレーヤーへの参照ポインタ
102  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
103  * @param m_ptr モンスターへの参照ポインタ
104  * @param ny モンスターのY座標
105  * @param nx モンスターのX座標
106  * @return ここではドアを開けず、ガラスのドアを開ける可能性があるならTRUE
107  */
108 static bool bash_normal_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
109 {
110         monster_race *r_ptr = &r_info[m_ptr->r_idx];
111         grid_type *g_ptr;
112         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
113         feature_type *f_ptr;
114         f_ptr = &f_info[g_ptr->feat];
115         turn_flags_ptr->do_move = FALSE;
116         if (((r_ptr->flags2 & RF2_OPEN_DOOR) == 0) || !have_flag(f_ptr->flags, FF_OPEN) ||
117                 (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
118                 return TRUE;
119
120         if (f_ptr->power == 0)
121         {
122                 turn_flags_ptr->did_open_door = TRUE;
123                 turn_flags_ptr->do_turn = TRUE;
124                 return FALSE;
125         }
126
127         if (randint0(m_ptr->hp / 10) > f_ptr->power)
128         {
129                 cave_alter_feat(target_ptr, ny, nx, FF_DISARM);
130                 turn_flags_ptr->do_turn = TRUE;
131                 return FALSE;
132         }
133
134         return TRUE;
135 }
136
137
138 /*!
139  * @brief モンスターがガラスのドアを開ける処理
140  * @param target_ptr プレーヤーへの参照ポインタ
141  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
142  * @param m_ptr モンスターへの参照ポインタ
143  * @param g_ptr グリッドへの参照ポインタ
144  * @param f_ptr 地形への参照ポインタ
145  * @return なし
146  */
147 static void bash_glass_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, feature_type *f_ptr, bool may_bash)
148 {
149         monster_race *r_ptr = &r_info[m_ptr->r_idx];
150         if (!may_bash || ((r_ptr->flags2 & RF2_BASH_DOOR) == 0) || !have_flag(f_ptr->flags, FF_BASH) ||
151                 (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
152                 return;
153
154         if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power))
155                 return;
156
157         if (have_flag(f_ptr->flags, FF_GLASS))
158                 msg_print(_("ガラスが砕ける音がした!", "You hear glass breaking!"));
159         else
160                 msg_print(_("ドアを叩き開ける音がした!", "You hear a door burst open!"));
161
162         if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
163
164         turn_flags_ptr->did_bash_door = TRUE;
165         turn_flags_ptr->do_move = TRUE;
166         turn_flags_ptr->must_alter_to_move = TRUE;
167 }
168
169
170 /*!
171  * @brief モンスターによるドアの開放・破壊を行う
172  * @param target_ptr プレーヤーへの参照ポインタ
173  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
174  * @param m_ptr モンスターへの参照ポインタ
175  * @param ny モンスターのY座標
176  * @param nx モンスターのX座標
177  * @return モンスターが死亡した場合のみFALSE
178  */
179 static bool process_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
180 {
181         monster_race *r_ptr = &r_info[m_ptr->r_idx];
182         grid_type *g_ptr;
183         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
184         if (!is_closed_door(target_ptr, g_ptr->feat)) return TRUE;
185
186         feature_type *f_ptr;
187         f_ptr = &f_info[g_ptr->feat];
188         bool may_bash = bash_normal_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx);
189         bash_glass_door(target_ptr, turn_flags_ptr, m_ptr, f_ptr, may_bash);
190
191         if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door) return TRUE;
192
193         if (turn_flags_ptr->did_bash_door &&
194                 ((randint0(100) < 50) || (feat_state(target_ptr, g_ptr->feat, FF_OPEN) == g_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS)))
195         {
196                 cave_alter_feat(target_ptr, ny, nx, FF_BASH);
197                 if (!monster_is_valid(m_ptr))
198                 {
199                         target_ptr->update |= (PU_FLOW);
200                         target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
201                         if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
202
203                         return FALSE;
204                 }
205         }
206         else
207         {
208                 cave_alter_feat(target_ptr, ny, nx, FF_OPEN);
209         }
210
211         f_ptr = &f_info[g_ptr->feat];
212         turn_flags_ptr->do_view = TRUE;
213         return TRUE;
214 }
215
216
217 /*!
218  * @brief 守りのルーンによるモンスターの移動制限を処理する
219  * @param target_ptr プレーヤーへの参照ポインタ
220  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
221  * @param m_ptr モンスターへの参照ポインタ
222  * @param ny モンスターのY座標
223  * @param nx モンスターのX座標
224  * @return ルーンのある/なし
225  */
226 static bool process_protection_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
227 {
228         grid_type *g_ptr;
229         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
230         monster_race *r_ptr = &r_info[m_ptr->r_idx];
231         if (!turn_flags_ptr->do_move || !is_glyph_grid(g_ptr) ||
232                 (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
233                 return FALSE;
234
235         turn_flags_ptr->do_move = FALSE;
236         if (is_pet(m_ptr) || (randint1(BREAK_GLYPH) >= r_ptr->level))
237                 return TRUE;
238
239         if (g_ptr->info & CAVE_MARK)
240         {
241                 msg_print(_("守りのルーンが壊れた!", "The rune of protection is broken!"));
242         }
243
244         g_ptr->info &= ~(CAVE_MARK);
245         g_ptr->info &= ~(CAVE_OBJECT);
246         g_ptr->mimic = 0;
247         turn_flags_ptr->do_move = TRUE;
248         note_spot(target_ptr, ny, nx);
249         return TRUE;
250 }
251
252
253 /*!
254  * @brief 爆発のルーンを処理する
255  * @param target_ptr プレーヤーへの参照ポインタ
256  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
257  * @param m_ptr モンスターへの参照ポインタ
258  * @param ny モンスターのY座標
259  * @param nx モンスターのX座標
260  * @return モンスターが死亡した場合のみFALSE
261  */
262 static bool process_explosive_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
263 {
264         grid_type *g_ptr;
265         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
266         monster_race *r_ptr = &r_info[m_ptr->r_idx];
267         if (!turn_flags_ptr->do_move || !is_explosive_rune_grid(g_ptr) ||
268                 (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
269                 return TRUE;
270
271         turn_flags_ptr->do_move = FALSE;
272         if (is_pet(m_ptr)) return TRUE;
273
274         if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
275         {
276                 if (g_ptr->info & CAVE_MARK)
277                 {
278                         msg_print(_("ルーンが爆発した!", "The rune explodes!"));
279                         BIT_FLAGS project_flags = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI;
280                         project(target_ptr, 0, 2, ny, nx, 2 * (target_ptr->lev + damroll(7, 7)), GF_MANA, project_flags, -1);
281                 }
282         }
283         else
284         {
285                 msg_print(_("爆発のルーンは解除された。", "An explosive rune was disarmed."));
286         }
287
288         g_ptr->info &= ~(CAVE_MARK);
289         g_ptr->info &= ~(CAVE_OBJECT);
290         g_ptr->mimic = 0;
291
292         note_spot(target_ptr, ny, nx);
293         lite_spot(target_ptr, ny, nx);
294
295         if (!monster_is_valid(m_ptr)) return FALSE;
296
297         turn_flags_ptr->do_move = TRUE;
298         return TRUE;
299 }
300
301
302 /*!
303  * @brief モンスターが壁を掘った後続処理を実行する
304  * @param target_ptr プレーヤーへの参照ポインタ
305  * @turn_flags_ptr ターン経過処理フラグへの参照ポインタ
306  * @param m_ptr モンスターへの参照ポインタ
307  * @param ny モンスターのY座標
308  * @param nx モンスターのX座標
309  * @return モンスターが死亡した場合のみFALSE
310  */
311 static bool process_post_dig_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
312 {
313         monster_race *r_ptr = &r_info[m_ptr->r_idx];
314         grid_type *g_ptr;
315         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
316         feature_type *f_ptr;
317         f_ptr = &f_info[g_ptr->feat];
318         if (!turn_flags_ptr->did_kill_wall || !turn_flags_ptr->do_move) return TRUE;
319
320         if (one_in_(GRINDNOISE))
321         {
322                 if (have_flag(f_ptr->flags, FF_GLASS))
323                         msg_print(_("何かの砕ける音が聞こえる。", "There is a crashing sound."));
324                 else
325                         msg_print(_("ギシギシいう音が聞こえる。", "There is a grinding sound."));
326         }
327
328         cave_alter_feat(target_ptr, ny, nx, FF_HURT_DISI);
329
330         if (!monster_is_valid(m_ptr))
331         {
332                 target_ptr->update |= (PU_FLOW);
333                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
334                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_WALL);
335
336                 return FALSE;
337         }
338
339         f_ptr = &f_info[g_ptr->feat];
340         turn_flags_ptr->do_view = TRUE;
341         turn_flags_ptr->do_turn = TRUE;
342         return TRUE;
343 }
344
345
346 /*!
347  * todo 少し長いが、これといってブロックとしてまとまった部分もないので暫定でこのままとする
348  * @brief モンスターの移動に関するメインルーチン
349  * @param target_ptr プレーヤーへの参照ポインタ
350  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
351  * @param m_idx モンスターID
352  * @param mm モンスターの移動方向
353  * @param oy 移動前の、モンスターのY座標
354  * @param ox 移動前の、モンスターのX座標
355  * @param count 移動回数 (のはず todo)
356  * @return 移動が阻害される何か (ドア等)があったらFALSE
357  */
358 bool process_monster_movement(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count)
359 {
360         for (int i = 0; mm[i]; i++)
361         {
362                 int d = mm[i];
363                 if (d == 5) d = ddd[randint0(8)];
364
365                 POSITION ny = oy + ddy[d];
366                 POSITION nx = ox + ddx[d];
367                 if (!in_bounds2(target_ptr->current_floor_ptr, ny, nx)) continue;
368
369                 grid_type *g_ptr;
370                 g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
371                 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
372                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
373                 bool can_cross = monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
374
375                 if (!process_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross))
376                 {
377                         if (!process_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
378                                 return FALSE;
379                 }
380
381                 if (!process_protection_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
382                 {
383                         if (!process_explosive_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
384                                 return FALSE;
385                 }
386
387                 exe_monster_attack_to_player(target_ptr, turn_flags_ptr, m_idx, ny, nx);
388                 if (process_monster_attack_to_monster(target_ptr, turn_flags_ptr, m_idx, g_ptr, can_cross)) return FALSE;
389
390                 if (turn_flags_ptr->is_riding_mon)
391                 {
392                         if (!target_ptr->riding_ryoute && !monster_fear_remaining(&target_ptr->current_floor_ptr->m_list[target_ptr->riding])) turn_flags_ptr->do_move = FALSE;
393                 }
394
395                 if (!process_post_dig_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx)) return FALSE;
396
397                 if (turn_flags_ptr->must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
398                 {
399                         if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0))
400                                 turn_flags_ptr->do_move = FALSE;
401                 }
402
403                 if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
404                         turn_flags_ptr->do_move = FALSE;
405
406                 if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
407                 {
408                         if (is_original_ap_and_seen(target_ptr, m_ptr))
409                                 r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
410
411                         turn_flags_ptr->do_move = FALSE;
412                 }
413
414                 if (!turn_flags_ptr->do_move)
415                 {
416                         if (turn_flags_ptr->do_turn) break;
417
418                         continue;
419                 }
420
421                 turn_flags_ptr->do_turn = TRUE;
422                 feature_type *f_ptr;
423                 f_ptr = &f_info[g_ptr->feat];
424                 if (have_flag(f_ptr->flags, FF_TREE))
425                 {
426                         if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
427                         {
428                                 m_ptr->energy_need += ENERGY_NEED();
429                         }
430                 }
431
432                 if (!update_riding_monster(target_ptr, turn_flags_ptr, m_idx, oy, ox, ny, nx)) break;
433
434                 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
435                 if (m_ptr->ml &&
436                         (disturb_move ||
437                         (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(target_ptr, target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx)) ||
438                                 (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= target_ptr->lev)))
439                 {
440                         if (is_hostile(m_ptr))
441                                 disturb(target_ptr, FALSE, TRUE);
442                 }
443
444                 bool is_takable_or_killable = g_ptr->o_idx > 0;
445                 is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
446
447                 bool is_pickup_items = (target_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
448                 is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
449
450                 is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
451                 if (!is_takable_or_killable)
452                 {
453                         if (turn_flags_ptr->do_turn) break;
454
455                         continue;
456                 }
457
458                 update_object_by_monster_movement(target_ptr, turn_flags_ptr, m_idx, ny, nx);
459                 if (turn_flags_ptr->do_turn) break;
460
461                 (*count)++;
462         }
463
464         return TRUE;
465 }
466
467
468 /*!
469  * @brief モンスターを喋らせたり足音を立てたりする
470  * @param target_ptr プレーヤーへの参照ポインタ
471  * @param m_idx モンスターID
472  * @param oy モンスターが元々いたY座標
473  * @param ox モンスターが元々いたX座標
474  * @param aware モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
475  * @return なし
476  */
477 void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware)
478 {
479         if (target_ptr->phase_out) return;
480
481         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
482         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
483         if (m_ptr->ap_r_idx == MON_CYBER &&
484                 one_in_(CYBERNOISE) &&
485                 !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
486         {
487                 if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
488                 msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
489         }
490
491         if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware ||
492                 !one_in_(SPEAK_CHANCE) ||
493                 !player_has_los_bold(target_ptr, oy, ox) ||
494                 !projectable(target_ptr, oy, ox, target_ptr->y, target_ptr->x))
495                 return;
496
497         GAME_TEXT m_name[MAX_NLEN];
498         char monmessage[1024];
499         concptr filename;
500
501         if (m_ptr->ml)
502                 monster_desc(target_ptr, m_name, m_ptr, 0);
503         else
504                 strcpy(m_name, _("それ", "It"));
505
506         if (monster_fear_remaining(m_ptr))
507                 filename = _("monfear_j.txt", "monfear.txt");
508         else if (is_pet(m_ptr))
509                 filename = _("monpet_j.txt", "monpet.txt");
510         else if (is_friendly(m_ptr))
511                 filename = _("monfrien_j.txt", "monfrien.txt");
512         else
513                 filename = _("monspeak_j.txt", "monspeak.txt");
514
515         if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
516         {
517                 msg_format(_("%^s%s", "%^s %s"), m_name, monmessage);
518         }
519 }
520
521 /*!
522  * @brief モンスターの目標地点をセットする / Set the target of counter attack
523  * @param m_ptr モンスターの参照ポインタ
524  * @param y 目標y座標
525  * @param x 目標x座標
526  * @return なし
527  */
528 void set_target(monster_type *m_ptr, POSITION y, POSITION x)
529 {
530     m_ptr->target_y = y;
531     m_ptr->target_x = x;
532 }
533
534 /*!
535  * @brief モンスターの目標地点をリセットする / Reset the target of counter attack
536  * @param m_ptr モンスターの参照ポインタ
537  * @return なし
538  */
539 void reset_target(monster_type *m_ptr) { set_target(m_ptr, 0, 0); }