OSDN Git Service

[Implement] ウサウサストライカー召喚処理を追加
[hengbandforosx/hengbandosx.git] / src / monster-floor / monster-remover.cpp
1 #include "monster-floor/monster-remover.h"
2 #include "core/stuff-handler.h"
3 #include "floor/cave.h"
4 #include "floor/floor-object.h"
5 #include "grid/grid.h"
6 #include "monster-race/monster-race.h"
7 #include "monster-race/race-brightness-mask.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-entity.h"
18 #include "system/monster-race-info.h"
19 #include "system/player-type-definition.h"
20 #include "system/redrawing-flags-updater.h"
21 #include "target/target-checker.h"
22
23 /*!
24  * @brief モンスター配列からモンスターを消去する / Delete a monster by index.
25  * @param i 消去するモンスターのID
26  * @details
27  * モンスターを削除するとそのモンスターが拾っていたアイテムも同時に削除される。 /
28  * When a monster is deleted, all of its objects are deleted.
29  */
30 void delete_monster_idx(PlayerType *player_ptr, MONSTER_IDX i)
31 {
32     auto *floor_ptr = player_ptr->current_floor_ptr;
33     auto *m_ptr = &floor_ptr->m_list[i];
34     auto *r_ptr = &m_ptr->get_monrace();
35
36     POSITION y = m_ptr->fy;
37     POSITION x = m_ptr->fx;
38
39     m_ptr->get_real_monrace().cur_num--;
40     if (r_ptr->misc_flags.has(MonsterMiscType::MULTIPLY)) {
41         floor_ptr->num_repro--;
42     }
43
44     if (m_ptr->is_asleep()) {
45         (void)set_monster_csleep(player_ptr, i, 0);
46     }
47     if (m_ptr->is_accelerated()) {
48         (void)set_monster_fast(player_ptr, i, 0);
49     }
50     if (m_ptr->is_decelerated()) {
51         (void)set_monster_slow(player_ptr, i, 0);
52     }
53     if (m_ptr->is_stunned()) {
54         (void)set_monster_stunned(player_ptr, i, 0);
55     }
56     if (m_ptr->is_confused()) {
57         (void)set_monster_confused(player_ptr, i, 0);
58     }
59     if (m_ptr->is_fearful()) {
60         (void)set_monster_monfear(player_ptr, i, 0);
61     }
62     if (m_ptr->is_invulnerable()) {
63         (void)set_monster_invulner(player_ptr, i, 0, false);
64     }
65
66     if (i == target_who) {
67         target_who = 0;
68     }
69
70     if (i == player_ptr->health_who) {
71         health_track(player_ptr, 0);
72     }
73
74     if (player_ptr->pet_t_m_idx == i) {
75         player_ptr->pet_t_m_idx = 0;
76     }
77     if (player_ptr->riding_t_m_idx == i) {
78         player_ptr->riding_t_m_idx = 0;
79     }
80     if (player_ptr->riding == i) {
81         player_ptr->riding = 0;
82     }
83
84     floor_ptr->grid_array[y][x].m_idx = 0;
85     for (auto it = m_ptr->hold_o_idx_list.begin(); it != m_ptr->hold_o_idx_list.end();) {
86         const OBJECT_IDX this_o_idx = *it++;
87         delete_object_idx(player_ptr, this_o_idx);
88     }
89
90     // 召喚元のモンスターが消滅した時は、召喚されたモンスターのparent_m_idxが
91     // 召喚されたモンスター自身のm_idxを指すようにする
92     for (MONSTER_IDX child_m_idx = 1; child_m_idx < floor_ptr->m_max; child_m_idx++) {
93         MonsterEntity *child_m_ptr = &floor_ptr->m_list[child_m_idx];
94         if (MonsterRace(child_m_ptr->r_idx).is_valid() && child_m_ptr->parent_m_idx == i) {
95             child_m_ptr->parent_m_idx = child_m_idx;
96         }
97     }
98
99     *m_ptr = {};
100     floor_ptr->m_cnt--;
101     lite_spot(player_ptr, y, x);
102     if (r_ptr->brightness_flags.has_any_of(ld_mask)) {
103         RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::MONSTER_LITE);
104     }
105 }
106
107 /*!
108  * @brief プレイヤーのフロア離脱に伴う全モンスター配列の消去
109  * @param player_ptr プレイヤーへの参照ポインタ
110  * @details 視覚効果なしでdelete_monster() をフロア全体に対して呼び出す.
111  */
112 void wipe_monsters_list(PlayerType *player_ptr)
113 {
114     MonraceList::get_instance().defeat_separated_uniques();
115     auto *floor_ptr = player_ptr->current_floor_ptr;
116     for (int i = floor_ptr->m_max - 1; i >= 1; i--) {
117         auto *m_ptr = &floor_ptr->m_list[i];
118         if (!m_ptr->is_valid()) {
119             continue;
120         }
121
122         floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].m_idx = 0;
123         *m_ptr = {};
124     }
125
126     /*
127      * Wiping racial counters of all monsters and incrementing of racial
128      * counters of monsters in party_mon[] are required to prevent multiple
129      * generation of unique monster who is the minion of player.
130      */
131     for (auto &[r_idx, r_ref] : monraces_info) {
132         r_ref.cur_num = 0;
133     }
134
135     floor_ptr->m_max = 1;
136     floor_ptr->m_cnt = 0;
137     for (int i = 0; i < MAX_MTIMED; i++) {
138         floor_ptr->mproc_max[i] = 0;
139     }
140
141     floor_ptr->num_repro = 0;
142     target_who = 0;
143     player_ptr->pet_t_m_idx = 0;
144     player_ptr->riding_t_m_idx = 0;
145     health_track(player_ptr, 0);
146 }
147
148 /*!
149  * @brief 指定位置に存在するモンスターを削除する / Delete the monster, if any, at a given location
150  * @param player_ptr プレイヤーへの参照ポインタ
151  * @param x 削除位置x座標
152  * @param y 削除位置y座標
153  */
154 void delete_monster(PlayerType *player_ptr, POSITION y, POSITION x)
155 {
156     Grid *g_ptr;
157     auto *floor_ptr = player_ptr->current_floor_ptr;
158     if (!in_bounds(floor_ptr, y, x)) {
159         return;
160     }
161
162     g_ptr = &floor_ptr->grid_array[y][x];
163     if (g_ptr->m_idx) {
164         delete_monster_idx(player_ptr, g_ptr->m_idx);
165     }
166 }