OSDN Git Service

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