OSDN Git Service

[Refactor] Grid::has_monster()の定義
[hengbandforosx/hengbandosx.git] / src / room / vault-builder.cpp
1 #include "room/vault-builder.h"
2 #include "floor/cave.h"
3 #include "floor/floor-generator-util.h"
4 #include "floor/floor-util.h"
5 #include "game-option/cheat-options.h"
6 #include "grid/feature-flag-types.h"
7 #include "grid/object-placer.h"
8 #include "grid/trap.h"
9 #include "monster-floor/monster-generator.h"
10 #include "monster-floor/place-monster-types.h"
11 #include "system/floor-type-definition.h"
12 #include "system/grid-type-definition.h"
13 #include "system/player-type-definition.h"
14 #include "view/display-messages.h"
15
16 /*
17  * Grid based version of "creature_bold()"
18  */
19 static bool player_grid(PlayerType *player_ptr, Grid *g_ptr)
20 {
21     return g_ptr == &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
22 }
23
24 /*
25  * Grid based version of "cave_empty_bold()"
26  */
27 static bool is_cave_empty_grid(PlayerType *player_ptr, Grid *g_ptr)
28 {
29     bool is_empty_grid = g_ptr->cave_has_flag(TerrainCharacteristics::PLACE);
30     is_empty_grid &= !g_ptr->has_monster();
31     is_empty_grid &= !player_grid(player_ptr, g_ptr);
32     return is_empty_grid;
33 }
34
35 /*!
36  * @brief 特殊な部屋地形向けにモンスターを配置する / Place some sleeping monsters near the given location
37  * @param player_ptr プレイヤーへの参照ポインタ
38  * @param y1 モンスターを配置したいマスの中心Y座標
39  * @param x1 モンスターを配置したいマスの中心X座標
40  * @param num 配置したいモンスターの数
41  * @details
42  * Only really called by some of the "vault" routines.
43  */
44 void vault_monsters(PlayerType *player_ptr, POSITION y1, POSITION x1, int num)
45 {
46     auto *floor_ptr = player_ptr->current_floor_ptr;
47     for (int k = 0; k < num; k++) {
48         for (int i = 0; i < 9; i++) {
49             int d = 1;
50             POSITION y, x;
51             scatter(player_ptr, &y, &x, y1, x1, d, 0);
52             Grid *g_ptr;
53             g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
54             if (!is_cave_empty_grid(player_ptr, g_ptr)) {
55                 continue;
56             }
57
58             floor_ptr->monster_level = floor_ptr->base_level + 2;
59             (void)place_random_monster(player_ptr, y, x, PM_ALLOW_SLEEP | PM_ALLOW_GROUP);
60             floor_ptr->monster_level = floor_ptr->base_level;
61         }
62     }
63 }
64
65 /*!
66  * @brief 特殊な部屋向けに各種アイテムを配置する / Create up to "num" objects near the given coordinates
67  * @param player_ptr プレイヤーへの参照ポインタ
68  * @param y 配置したい中心マスのY座標
69  * @param x 配置したい中心マスのX座標
70  * @param num 配置したい数
71  * @details
72  * Only really called by some of the "vault" routines.
73  */
74 void vault_objects(PlayerType *player_ptr, POSITION y, POSITION x, int num)
75 {
76     auto *floor_ptr = player_ptr->current_floor_ptr;
77     for (; num > 0; --num) {
78         int j = y, k = x;
79         int dummy = 0;
80         for (int i = 0; i < 11; ++i) {
81             while (dummy < SAFE_MAX_ATTEMPTS) {
82                 j = rand_spread(y, 2);
83                 k = rand_spread(x, 3);
84                 dummy++;
85                 if (!in_bounds(floor_ptr, j, k)) {
86                     continue;
87                 }
88                 break;
89             }
90
91             if (dummy >= SAFE_MAX_ATTEMPTS && cheat_room) {
92                 msg_print(_("警告!地下室のアイテムを配置できません!", "Warning! Could not place vault object!"));
93             }
94
95             Grid *g_ptr;
96             g_ptr = &floor_ptr->grid_array[j][k];
97             if (!g_ptr->is_floor() || !g_ptr->o_idx_list.empty()) {
98                 continue;
99             }
100
101             if (randint0(100) < 75) {
102                 place_object(player_ptr, j, k, 0L);
103             } else {
104                 place_gold(player_ptr, j, k);
105             }
106
107             break;
108         }
109     }
110 }
111
112 /*!
113  * @brief 特殊な部屋向けに各種アイテムを配置する(vault_trapのサブセット) / Place a trap with a given displacement of point
114  * @param y トラップを配置したいマスの中心Y座標
115  * @param x トラップを配置したいマスの中心X座標
116  * @param yd Y方向の配置分散マス数
117  * @param xd X方向の配置分散マス数
118  * @details
119  * Only really called by some of the "vault" routines.
120  */
121 static void vault_trap_aux(FloorType *floor_ptr, POSITION y, POSITION x, POSITION yd, POSITION xd)
122 {
123     Grid *g_ptr;
124     int y1 = y, x1 = x;
125     int dummy = 0;
126     for (int count = 0; count <= 5; count++) {
127         while (dummy < SAFE_MAX_ATTEMPTS) {
128             y1 = rand_spread(y, yd);
129             x1 = rand_spread(x, xd);
130             dummy++;
131             if (!in_bounds(floor_ptr, y1, x1)) {
132                 continue;
133             }
134             break;
135         }
136
137         if (dummy >= SAFE_MAX_ATTEMPTS && cheat_room) {
138             msg_print(_("警告!地下室のトラップを配置できません!", "Warning! Could not place vault trap!"));
139         }
140
141         g_ptr = &floor_ptr->grid_array[y1][x1];
142         if (!g_ptr->is_floor() || !g_ptr->o_idx_list.empty() || g_ptr->has_monster()) {
143             continue;
144         }
145
146         place_trap(floor_ptr, y1, x1);
147         break;
148     }
149 }
150
151 /*!
152  * @brief 特殊な部屋向けに各種アイテムを配置する(メインルーチン) / Place some traps with a given displacement of given location
153  * @param player_ptr プレイヤーへの参照ポインタ
154  * @param y トラップを配置したいマスの中心Y座標
155  * @param x トラップを配置したいマスの中心X座標
156  * @param yd Y方向の配置分散マス数
157  * @param xd X方向の配置分散マス数
158  * @param num 配置したいトラップの数
159  * @details
160  * Only really called by some of the "vault" routines.
161  * @todo rooms-normal からしか呼ばれていない、要調整
162  */
163 void vault_traps(FloorType *floor_ptr, POSITION y, POSITION x, POSITION yd, POSITION xd, int num)
164 {
165     for (int i = 0; i < num; i++) {
166         vault_trap_aux(floor_ptr, y, x, yd, xd);
167     }
168 }