OSDN Git Service

[Refactor] #2628 Renamed object-type-definition.cpp/h to item-entity.cpp/h
[hengbandforosx/hengbandosx.git] / src / monster-floor / monster-remover.cpp
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/grid-type-definition.h"
16 #include "system/item-entity.h"
17 #include "system/monster-race-definition.h"
18 #include "system/monster-type-definition.h"
19 #include "system/player-type-definition.h"
20 #include "target/target-checker.h"
21
22 /*!
23  * @brief モンスター配列からモンスターを消去する / Delete a monster by index.
24  * @param i 消去するモンスターのID
25  * @details
26  * モンスターを削除するとそのモンスターが拾っていたアイテムも同時に削除される。 /
27  * When a monster is deleted, all of its objects are deleted.
28  */
29 void delete_monster_idx(PlayerType *player_ptr, MONSTER_IDX i)
30 {
31     auto *floor_ptr = player_ptr->current_floor_ptr;
32     auto *m_ptr = &floor_ptr->m_list[i];
33     auto *r_ptr = &monraces_info[m_ptr->r_idx];
34
35     POSITION y = m_ptr->fy;
36     POSITION x = m_ptr->fx;
37
38     m_ptr->get_real_r_ref().cur_num--;
39     if (r_ptr->flags2 & (RF2_MULTIPLY)) {
40         floor_ptr->num_repro--;
41     }
42
43     if (m_ptr->is_asleep()) {
44         (void)set_monster_csleep(player_ptr, i, 0);
45     }
46     if (m_ptr->is_accelerated()) {
47         (void)set_monster_fast(player_ptr, i, 0);
48     }
49     if (m_ptr->is_decelerated()) {
50         (void)set_monster_slow(player_ptr, i, 0);
51     }
52     if (m_ptr->is_stunned()) {
53         (void)set_monster_stunned(player_ptr, i, 0);
54     }
55     if (m_ptr->is_confused()) {
56         (void)set_monster_confused(player_ptr, i, 0);
57     }
58     if (m_ptr->is_fearful()) {
59         (void)set_monster_monfear(player_ptr, i, 0);
60     }
61     if (m_ptr->is_invulnerable()) {
62         (void)set_monster_invulner(player_ptr, i, 0, false);
63     }
64
65     if (i == target_who) {
66         target_who = 0;
67     }
68
69     if (i == player_ptr->health_who) {
70         health_track(player_ptr, 0);
71     }
72
73     if (player_ptr->pet_t_m_idx == i) {
74         player_ptr->pet_t_m_idx = 0;
75     }
76     if (player_ptr->riding_t_m_idx == i) {
77         player_ptr->riding_t_m_idx = 0;
78     }
79     if (player_ptr->riding == i) {
80         player_ptr->riding = 0;
81     }
82
83     floor_ptr->grid_array[y][x].m_idx = 0;
84     for (auto it = m_ptr->hold_o_idx_list.begin(); it != m_ptr->hold_o_idx_list.end();) {
85         const OBJECT_IDX this_o_idx = *it++;
86         delete_object_idx(player_ptr, this_o_idx);
87     }
88
89     // 召喚元のモンスターが消滅した時は、召喚されたモンスターのparent_m_idxが
90     // 召喚されたモンスター自身のm_idxを指すようにする
91     for (MONSTER_IDX child_m_idx = 1; child_m_idx < floor_ptr->m_max; child_m_idx++) {
92         MonsterEntity *child_m_ptr = &floor_ptr->m_list[child_m_idx];
93         if (MonsterRace(child_m_ptr->r_idx).is_valid() && child_m_ptr->parent_m_idx == i) {
94             child_m_ptr->parent_m_idx = child_m_idx;
95         }
96     }
97
98     *m_ptr = {};
99     floor_ptr->m_cnt--;
100     lite_spot(player_ptr, y, x);
101     if (r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK)) {
102         player_ptr->update |= (PU_MON_LITE);
103     }
104 }
105
106 /*!
107  * @brief プレイヤーのフロア離脱に伴う全モンスター配列の消去 / Delete/Remove all the monsters when the player leaves the level
108  * @param player_ptr プレイヤーへの参照ポインタ
109  * @details
110  * This is an efficient method of simulating multiple calls to the
111  * "delete_monster()" function, with no visual effects.
112  */
113 void wipe_monsters_list(PlayerType *player_ptr)
114 {
115     if (!monraces_info[MonsterRaceId::BANORLUPART].max_num) {
116         if (monraces_info[MonsterRaceId::BANOR].max_num) {
117             monraces_info[MonsterRaceId::BANOR].max_num = 0;
118             monraces_info[MonsterRaceId::BANOR].r_pkills++;
119             monraces_info[MonsterRaceId::BANOR].r_akills++;
120             if (monraces_info[MonsterRaceId::BANOR].r_tkills < MAX_SHORT) {
121                 monraces_info[MonsterRaceId::BANOR].r_tkills++;
122             }
123         }
124
125         if (monraces_info[MonsterRaceId::LUPART].max_num) {
126             monraces_info[MonsterRaceId::LUPART].max_num = 0;
127             monraces_info[MonsterRaceId::LUPART].r_pkills++;
128             monraces_info[MonsterRaceId::LUPART].r_akills++;
129             if (monraces_info[MonsterRaceId::LUPART].r_tkills < MAX_SHORT) {
130                 monraces_info[MonsterRaceId::LUPART].r_tkills++;
131             }
132         }
133     }
134
135     auto *floor_ptr = player_ptr->current_floor_ptr;
136     for (int i = floor_ptr->m_max - 1; i >= 1; i--) {
137         auto *m_ptr = &floor_ptr->m_list[i];
138         if (!m_ptr->is_valid()) {
139             continue;
140         }
141
142         floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].m_idx = 0;
143         *m_ptr = {};
144     }
145
146     /*
147      * Wiping racial counters of all monsters and incrementing of racial
148      * counters of monsters in party_mon[] are required to prevent multiple
149      * generation of unique monster who is the minion of player.
150      */
151     for (auto &[r_idx, r_ref] : monraces_info) {
152         r_ref.cur_num = 0;
153     }
154
155     floor_ptr->m_max = 1;
156     floor_ptr->m_cnt = 0;
157     for (int i = 0; i < MAX_MTIMED; i++) {
158         floor_ptr->mproc_max[i] = 0;
159     }
160
161     floor_ptr->num_repro = 0;
162     target_who = 0;
163     player_ptr->pet_t_m_idx = 0;
164     player_ptr->riding_t_m_idx = 0;
165     health_track(player_ptr, 0);
166 }
167
168 /*!
169  * @brief 指定位置に存在するモンスターを削除する / Delete the monster, if any, at a given location
170  * @param player_ptr プレイヤーへの参照ポインタ
171  * @param x 削除位置x座標
172  * @param y 削除位置y座標
173  */
174 void delete_monster(PlayerType *player_ptr, POSITION y, POSITION x)
175 {
176     grid_type *g_ptr;
177     auto *floor_ptr = player_ptr->current_floor_ptr;
178     if (!in_bounds(floor_ptr, y, x)) {
179         return;
180     }
181
182     g_ptr = &floor_ptr->grid_array[y][x];
183     if (g_ptr->m_idx) {
184         delete_monster_idx(player_ptr, g_ptr->m_idx);
185     }
186 }