1 #include "specific-object/torch.h"
2 #include "core/player-update-types.h"
3 #include "dungeon/dungeon-flag-types.h"
4 #include "dungeon/dungeon.h"
5 #include "floor/cave.h"
6 #include "inventory/inventory-slot-types.h"
7 #include "mind/mind-ninja.h"
8 #include "object-enchant/object-ego.h"
9 #include "object-enchant/tr-types.h"
10 #include "object/object-flags.h"
11 #include "player/special-defense-types.h"
12 #include "system/floor-type-definition.h"
13 #include "sv-definition/sv-lite-types.h"
14 #include "util/bit-flags-calculator.h"
17 * @brief 投擲時たいまつに投げやすい/焼棄/アンデッドスレイの特別効果を返す。
18 * Torches have special abilities when they are flaming.
19 * @param o_ptr 投擲するオブジェクトの構造体参照ポインタ
20 * @param flgs 特別に追加するフラグを返す参照ポインタ
23 void torch_flags(object_type *o_ptr, BIT_FLAGS *flgs)
25 if ((o_ptr->tval != TV_LITE) || (o_ptr->sval != SV_LITE_TORCH) || (o_ptr->xtra4 <= 0))
28 add_flag(flgs, TR_BRAND_FIRE);
29 add_flag(flgs, TR_KILL_UNDEAD);
30 add_flag(flgs, TR_THROW);
34 * @brief 投擲時たいまつにダイスを与える。
35 * Torches have special abilities when they are flaming.
36 * @param o_ptr 投擲するオブジェクトの構造体参照ポインタ
37 * @param dd 特別なダイス数を返す参照ポインタ
38 * @param ds 特別なダイス面数を返す参照ポインタ
41 void torch_dice(object_type *o_ptr, DICE_NUMBER *dd, DICE_SID *ds)
43 if ((o_ptr->tval != TV_LITE) || (o_ptr->sval != SV_LITE_TORCH) || (o_ptr->xtra4 <= 0))
51 * @brief 投擲時命中したたいまつの寿命を縮める。
52 * Torches have special abilities when they are flaming.
53 * @param o_ptr 投擲するオブジェクトの構造体参照ポインタ
56 void torch_lost_fuel(object_type *o_ptr)
58 if ((o_ptr->tval != TV_LITE) || (o_ptr->sval != SV_LITE_TORCH))
61 o_ptr->xtra4 -= (FUEL_TORCH / 25);
67 * @brief プレイヤーの光源半径を計算する / Extract and set the current "lite radius"
70 * SWD: Experimental modification: multiple light sources have additive effect.
72 void update_lite_radius(player_type *creature_ptr)
74 creature_ptr->cur_lite = 0;
75 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
77 o_ptr = &creature_ptr->inventory_list[i];
78 BIT_FLAGS flgs[TR_FLAG_SIZE];
79 object_flags(creature_ptr, o_ptr, flgs);
84 if (o_ptr->name2 == EGO_LITE_SHINE)
85 creature_ptr->cur_lite++;
87 if (!has_flag(flgs, TR_DARK_SOURCE)) {
88 if (o_ptr->tval == TV_LITE) {
89 if ((o_ptr->sval == SV_LITE_TORCH) && !(o_ptr->xtra4 > 0))
92 if ((o_ptr->sval == SV_LITE_LANTERN) && !(o_ptr->xtra4 > 0))
99 if (has_flag(flgs, TR_LITE_1) && !has_flag(flgs, TR_DARK_SOURCE))
102 if (has_flag(flgs, TR_LITE_2) && !has_flag(flgs, TR_DARK_SOURCE))
105 if (has_flag(flgs, TR_LITE_3) && !has_flag(flgs, TR_DARK_SOURCE))
108 if (has_flag(flgs, TR_LITE_M1))
111 if (has_flag(flgs, TR_LITE_M2))
114 if (has_flag(flgs, TR_LITE_M3))
117 creature_ptr->cur_lite += rad;
120 if (d_info[creature_ptr->dungeon_idx].flags1 & DF1_DARKNESS && creature_ptr->cur_lite > 1)
121 creature_ptr->cur_lite = 1;
123 if (creature_ptr->cur_lite <= 0 && creature_ptr->lite)
124 creature_ptr->cur_lite++;
126 if (creature_ptr->cur_lite > 14)
127 creature_ptr->cur_lite = 14;
129 if (creature_ptr->cur_lite < 0)
130 creature_ptr->cur_lite = 0;
132 if (creature_ptr->old_lite == creature_ptr->cur_lite)
135 creature_ptr->update |= PU_LITE | PU_MON_LITE | PU_MONSTERS;
136 creature_ptr->old_lite = creature_ptr->cur_lite;
138 if ((creature_ptr->cur_lite > 0) && (creature_ptr->special_defense & NINJA_S_STEALTH))
139 set_superstealth(creature_ptr, FALSE);
143 * Update the set of grids "illuminated" by the player's lite.
145 * This routine needs to use the results of "update_view()"
147 * Note that "blindness" does NOT affect "torch lite". Be careful!
149 * We optimize most lites (all non-artifact lites) by using "obvious"
150 * facts about the results of "small" lite radius, and we attempt to
151 * list the "nearby" grids before the more "distant" ones in the
152 * array of torch-lit grids.
154 * We assume that "radius zero" lite is in fact no lite at all.
156 * Torch Lantern Artifacts
166 void update_lite(player_type *subject_ptr)
168 POSITION p = subject_ptr->cur_lite;
170 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
171 for (int i = 0; i < floor_ptr->lite_n; i++) {
172 POSITION y = floor_ptr->lite_y[i];
173 POSITION x = floor_ptr->lite_x[i];
174 floor_ptr->grid_array[y][x].info &= ~(CAVE_LITE);
175 floor_ptr->grid_array[y][x].info |= CAVE_TEMP;
176 tmp_pos.y[tmp_pos.n] = y;
177 tmp_pos.x[tmp_pos.n] = x;
181 floor_ptr->lite_n = 0;
183 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x);
184 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x);
185 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x);
186 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x + 1);
187 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x - 1);
188 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x + 1);
189 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x - 1);
190 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x + 1);
191 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x - 1);
195 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x)) {
196 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x);
197 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x + 1);
198 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x - 1);
201 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x)) {
202 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x);
203 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x + 1);
204 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x - 1);
207 if (cave_los_bold(floor_ptr, subject_ptr->y, subject_ptr->x + 1)) {
208 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x + 2);
209 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x + 2);
210 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x + 2);
213 if (cave_los_bold(floor_ptr, subject_ptr->y, subject_ptr->x - 1)) {
214 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x - 2);
215 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x - 2);
216 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x - 2);
225 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x + 1))
226 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x + 2);
228 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x - 1))
229 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x - 2);
231 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x + 1))
232 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x + 2);
234 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x - 1))
235 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x - 2);
237 POSITION min_y = subject_ptr->y - p;
241 POSITION max_y = subject_ptr->y + p;
242 if (max_y > floor_ptr->height - 1)
243 max_y = floor_ptr->height - 1;
245 POSITION min_x = subject_ptr->x - p;
249 POSITION max_x = subject_ptr->x + p;
250 if (max_x > floor_ptr->width - 1)
251 max_x = floor_ptr->width - 1;
253 for (POSITION y = min_y; y <= max_y; y++) {
254 for (POSITION x = min_x; x <= max_x; x++) {
255 int dy = (subject_ptr->y > y) ? (subject_ptr->y - y) : (y - subject_ptr->y);
256 int dx = (subject_ptr->x > x) ? (subject_ptr->x - x) : (x - subject_ptr->x);
257 if ((dy <= 2) && (dx <= 2))
260 d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
264 if (floor_ptr->grid_array[y][x].info & CAVE_VIEW)
265 cave_lite_hack(floor_ptr, y, x);
270 for (int i = 0; i < floor_ptr->lite_n; i++) {
271 POSITION y = floor_ptr->lite_y[i];
272 POSITION x = floor_ptr->lite_x[i];
273 g_ptr = &floor_ptr->grid_array[y][x];
274 if (g_ptr->info & CAVE_TEMP)
277 cave_note_and_redraw_later(floor_ptr, g_ptr, y, x);
280 for (int i = 0; i < tmp_pos.n; i++) {
281 POSITION y = tmp_pos.y[i];
282 POSITION x = tmp_pos.x[i];
283 g_ptr = &floor_ptr->grid_array[y][x];
284 g_ptr->info &= ~(CAVE_TEMP);
285 if (g_ptr->info & CAVE_LITE)
288 cave_redraw_later(floor_ptr, g_ptr, y, x);
292 subject_ptr->update |= PU_DELAY_VIS;