OSDN Git Service

Merge pull request #3634 from Hourier/Prepare-Replace-ChooseRandomTrap-FloorType
[hengbandforosx/hengbandosx.git] / src / spell-kind / spells-neighbor.cpp
1 #include "spell-kind/spells-neighbor.h"
2 #include "effect/attribute-types.h"
3 #include "effect/effect-characteristics.h"
4 #include "effect/effect-processor.h"
5 #include "floor/cave.h"
6 #include "floor/floor-util.h"
7 #include "grid/feature-flag-types.h"
8 #include "grid/grid.h"
9 #include "spell-kind/earthquake.h"
10 #include "system/player-type-definition.h"
11 #include "system/redrawing-flags-updater.h"
12 #include "util/bit-flags-calculator.h"
13
14 /*!
15  * @brief ドア生成処理(プレイヤー中心に周囲1マス) / Hooks -- affect adjacent grids (radius 1 ball attack)
16  * @param player_ptr プレイヤーへの参照ポインタ
17  * @return 作用が実際にあった場合TRUEを返す
18  */
19 bool door_creation(PlayerType *player_ptr, POSITION y, POSITION x)
20 {
21     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
22     return project(player_ptr, 0, 1, y, x, 0, AttributeType::MAKE_DOOR, flg).notice;
23 }
24
25 /*!
26  * @brief トラップ生成処理(起点から周囲1マス)
27  * @param player_ptr プレイヤーへの参照ポインタ
28  * @param y 起点Y座標
29  * @param x 起点X座標
30  * @return 作用が実際にあった場合TRUEを返す
31  */
32 bool trap_creation(PlayerType *player_ptr, POSITION y, POSITION x)
33 {
34     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
35     return project(player_ptr, 0, 1, y, x, 0, AttributeType::MAKE_TRAP, flg).notice;
36 }
37
38 /*!
39  * @brief 森林生成処理(プレイヤー中心に周囲1マス)
40  * @param player_ptr プレイヤーへの参照ポインタ
41  * @return 作用が実際にあった場合TRUEを返す
42  */
43 bool tree_creation(PlayerType *player_ptr, POSITION y, POSITION x)
44 {
45     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
46     return project(player_ptr, 0, 1, y, x, 0, AttributeType::MAKE_TREE, flg).notice;
47 }
48
49 /*!
50  * @brief 魔法のルーン生成処理(プレイヤー中心に周囲1マス)
51  * @param player_ptr プレイヤーへの参照ポインタ
52  * @return 作用が実際にあった場合TRUEを返す
53  */
54 bool create_rune_protection_area(PlayerType *player_ptr, POSITION y, POSITION x)
55 {
56     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM;
57     return project(player_ptr, 0, 1, y, x, 0, AttributeType::MAKE_RUNE_PROTECTION, flg).notice;
58 }
59
60 /*!
61  * @brief 壁生成処理(プレイヤー中心に周囲1マス)
62  * @param player_ptr プレイヤーへの参照ポインタ
63  * @return 作用が実際にあった場合TRUEを返す
64  */
65 bool wall_stone(PlayerType *player_ptr)
66 {
67     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
68     bool dummy = project(player_ptr, 0, 1, player_ptr->y, player_ptr->x, 0, AttributeType::STONE_WALL, flg).notice;
69     auto &rfu = RedrawingFlagsUpdater::get_instance();
70     rfu.set_flag(StatusRecalculatingFlag::FLOW);
71     rfu.set_flag(MainWindowRedrawingFlag::MAP);
72     return dummy;
73 }
74
75 /*!
76  * @brief ドア破壊処理(プレイヤー中心に周囲1マス)
77  * @param player_ptr プレイヤーへの参照ポインタ
78  * @return 作用が実際にあった場合TRUEを返す
79  */
80 bool destroy_doors_touch(PlayerType *player_ptr)
81 {
82     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
83     return project(player_ptr, 0, 1, player_ptr->y, player_ptr->x, 0, AttributeType::KILL_DOOR, flg).notice;
84 }
85
86 /*!
87  * @brief トラップ解除処理(プレイヤー中心に周囲1マス)
88  * @param player_ptr プレイヤーへの参照ポインタ
89  * @return 作用が実際にあった場合TRUEを返す
90  */
91 bool disarm_traps_touch(PlayerType *player_ptr)
92 {
93     BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
94     return project(player_ptr, 0, 1, player_ptr->y, player_ptr->x, 0, AttributeType::KILL_TRAP, flg).notice;
95 }
96
97 /*!
98  * @brief スリープモンスター処理(プレイヤー中心に周囲1マス)
99  * @param player_ptr プレイヤーへの参照ポインタ
100  * @return 作用が実際にあった場合TRUEを返す
101  */
102 bool sleep_monsters_touch(PlayerType *player_ptr)
103 {
104     BIT_FLAGS flg = PROJECT_KILL | PROJECT_HIDE;
105     return project(player_ptr, 0, 1, player_ptr->y, player_ptr->x, player_ptr->lev, AttributeType::OLD_SLEEP, flg).notice;
106 }
107
108 /*!
109  * @brief 死者復活処理(起点より周囲5マス)
110  * @param player_ptr プレイヤーへの参照ポインタ
111  * @param who 術者モンスターID(0ならばプレイヤー)
112  * @param y 起点Y座標
113  * @param x 起点X座標
114  * @return 作用が実際にあった場合TRUEを返す
115  */
116 bool animate_dead(PlayerType *player_ptr, MONSTER_IDX who, POSITION y, POSITION x)
117 {
118     BIT_FLAGS flg = PROJECT_ITEM | PROJECT_HIDE;
119     return project(player_ptr, who, 5, y, x, 0, AttributeType::ANIM_DEAD, flg).notice;
120 }
121
122 /*!
123  * @brief 周辺破壊効果(プレイヤー中心)
124  * @param player_ptr プレイヤーへの参照ポインタ
125  */
126 void wall_breaker(PlayerType *player_ptr)
127 {
128     POSITION y = 0, x = 0;
129     int attempts = 1000;
130     if (randint1(80 + player_ptr->lev) < 70) {
131         while (attempts--) {
132             scatter(player_ptr, &y, &x, player_ptr->y, player_ptr->x, 4, PROJECT_NONE);
133
134             if (!cave_has_flag_bold(player_ptr->current_floor_ptr, y, x, TerrainCharacteristics::PROJECT)) {
135                 continue;
136             }
137
138             if (!player_bold(player_ptr, y, x)) {
139                 break;
140             }
141         }
142
143         constexpr auto flags = PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
144         project(player_ptr, 0, 0, y, x, 20 + randint1(30), AttributeType::KILL_WALL, flags);
145         return;
146     }
147
148     if (randint1(100) > 30) {
149         earthquake(player_ptr, player_ptr->y, player_ptr->x, 1, 0);
150         return;
151     }
152
153     int num = damroll(5, 3);
154     for (int i = 0; i < num; i++) {
155         while (true) {
156             scatter(player_ptr, &y, &x, player_ptr->y, player_ptr->x, 10, PROJECT_NONE);
157
158             if (!player_bold(player_ptr, y, x)) {
159                 break;
160             }
161         }
162
163         constexpr auto flags = PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
164         project(player_ptr, 0, 0, y, x, 20 + randint1(30), AttributeType::KILL_WALL, flags);
165     }
166 }