OSDN Git Service

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