OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Fix-Compile-on-Linux' into develop
[hengband/hengband.git] / src / monster-floor / monster-remover.c
1 #include "monster-floor/monster-remover.h"
2 #include "core/player-update-types.h"
3 #include "core/stuff-handler.h"
4 #include "floor/cave.h"
5 #include "floor/floor-object.h"
6 #include "grid/grid.h"
7 #include "monster-race/monster-race.h"
8 #include "monster-race/race-flags2.h"
9 #include "monster-race/race-flags7.h"
10 #include "monster-race/race-indice-types.h"
11 #include "monster/monster-info.h"
12 #include "monster/monster-status-setter.h"
13 #include "monster/monster-status.h"
14 #include "system/floor-type-definition.h"
15 #include "system/monster-type-definition.h"
16 #include "system/object-type-definition.h"
17 #include "target/target-checker.h"
18
19 /*!
20  * @brief モンスター配列からモンスターを消去する / Delete a monster by index.
21  * @param i 消去するモンスターのID
22  * @return なし
23  * @details
24  * モンスターを削除するとそのモンスターが拾っていたアイテムも同時に削除される。 /
25  * When a monster is deleted, all of its objects are deleted.
26  */
27 void delete_monster_idx(player_type *player_ptr, MONSTER_IDX i)
28 {
29     floor_type *floor_ptr = player_ptr->current_floor_ptr;
30     monster_type *m_ptr = &floor_ptr->m_list[i];
31     monster_race *r_ptr = &r_info[m_ptr->r_idx];
32
33     POSITION y = m_ptr->fy;
34     POSITION x = m_ptr->fx;
35
36     real_r_ptr(m_ptr)->cur_num--;
37     if (r_ptr->flags2 & (RF2_MULTIPLY))
38         floor_ptr->num_repro--;
39
40     if (monster_csleep_remaining(m_ptr))
41         (void)set_monster_csleep(player_ptr, i, 0);
42     if (monster_fast_remaining(m_ptr))
43         (void)set_monster_fast(player_ptr, i, 0);
44     if (monster_slow_remaining(m_ptr))
45         (void)set_monster_slow(player_ptr, i, 0);
46     if (monster_stunned_remaining(m_ptr))
47         (void)set_monster_stunned(player_ptr, i, 0);
48     if (monster_confused_remaining(m_ptr))
49         (void)set_monster_confused(player_ptr, i, 0);
50     if (monster_fear_remaining(m_ptr))
51         (void)set_monster_monfear(player_ptr, i, 0);
52     if (monster_invulner_remaining(m_ptr))
53         (void)set_monster_invulner(player_ptr, i, 0, FALSE);
54
55     if (i == target_who)
56         target_who = 0;
57
58     if (i == player_ptr->health_who)
59         health_track(player_ptr, 0);
60
61     if (player_ptr->pet_t_m_idx == i)
62         player_ptr->pet_t_m_idx = 0;
63     if (player_ptr->riding_t_m_idx == i)
64         player_ptr->riding_t_m_idx = 0;
65     if (player_ptr->riding == i)
66         player_ptr->riding = 0;
67
68     floor_ptr->grid_array[y][x].m_idx = 0;
69     OBJECT_IDX next_o_idx = 0;
70     for (OBJECT_IDX this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
71         object_type *o_ptr;
72         o_ptr = &floor_ptr->o_list[this_o_idx];
73         next_o_idx = o_ptr->next_o_idx;
74         delete_object_idx(player_ptr, this_o_idx);
75     }
76
77     (void)WIPE(m_ptr, monster_type);
78     floor_ptr->m_cnt--;
79     lite_spot(player_ptr, y, x);
80     if (r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK)) {
81         player_ptr->update |= (PU_MON_LITE);
82     }
83 }
84
85 /*!
86  * @brief プレイヤーのフロア離脱に伴う全モンスター配列の消去 / Delete/Remove all the monsters when the player leaves the level
87  * @param player_ptr プレーヤーへの参照ポインタ
88  * @return なし
89  * @details
90  * This is an efficient method of simulating multiple calls to the
91  * "delete_monster()" function, with no visual effects.
92  */
93 void wipe_monsters_list(player_type *player_ptr)
94 {
95     if (!r_info[MON_BANORLUPART].max_num) {
96         if (r_info[MON_BANOR].max_num) {
97             r_info[MON_BANOR].max_num = 0;
98             r_info[MON_BANOR].r_pkills++;
99             r_info[MON_BANOR].r_akills++;
100             if (r_info[MON_BANOR].r_tkills < MAX_SHORT)
101                 r_info[MON_BANOR].r_tkills++;
102         }
103
104         if (r_info[MON_LUPART].max_num) {
105             r_info[MON_LUPART].max_num = 0;
106             r_info[MON_LUPART].r_pkills++;
107             r_info[MON_LUPART].r_akills++;
108             if (r_info[MON_LUPART].r_tkills < MAX_SHORT)
109                 r_info[MON_LUPART].r_tkills++;
110         }
111     }
112
113     floor_type *floor_ptr = player_ptr->current_floor_ptr;
114     for (int i = floor_ptr->m_max - 1; i >= 1; i--) {
115         monster_type *m_ptr = &floor_ptr->m_list[i];
116         if (!monster_is_valid(m_ptr))
117             continue;
118
119         floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].m_idx = 0;
120         (void)WIPE(m_ptr, monster_type);
121     }
122
123     /*
124      * Wiping racial counters of all monsters and incrementing of racial
125      * counters of monsters in party_mon[] are required to prevent multiple
126      * generation of unique monster who is the minion of player.
127      */
128     for (int i = 1; i < max_r_idx; i++)
129         r_info[i].cur_num = 0;
130
131     floor_ptr->m_max = 1;
132     floor_ptr->m_cnt = 0;
133     for (int i = 0; i < MAX_MTIMED; i++)
134         floor_ptr->mproc_max[i] = 0;
135
136     floor_ptr->num_repro = 0;
137     target_who = 0;
138     player_ptr->pet_t_m_idx = 0;
139     player_ptr->riding_t_m_idx = 0;
140     health_track(player_ptr, 0);
141 }
142
143 /*!
144  * @brief 指定位置に存在するモンスターを削除する / Delete the monster, if any, at a given location
145  * @param player_ptr プレーヤーへの参照ポインタ
146  * @param x 削除位置x座標
147  * @param y 削除位置y座標
148  * @return なし
149  */
150 void delete_monster(player_type *player_ptr, POSITION y, POSITION x)
151 {
152     grid_type *g_ptr;
153     floor_type *floor_ptr = player_ptr->current_floor_ptr;
154     if (!in_bounds(floor_ptr, y, x))
155         return;
156
157     g_ptr = &floor_ptr->grid_array[y][x];
158     if (g_ptr->m_idx)
159         delete_monster_idx(player_ptr, g_ptr->m_idx);
160 }