OSDN Git Service

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