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 calc_lite_radius(player_type *creature_ptr)
74 creature_ptr->cur_lite = 0;
75 for (inventory_slot_type i = INVEN_RARM; i < INVEN_TOTAL; i++) {
77 o_ptr = &creature_ptr->inventory_list[i];
81 if (o_ptr->name2 == EGO_LITE_SHINE)
82 creature_ptr->cur_lite++;
84 if (o_ptr->name2 != EGO_LITE_DARKNESS) {
85 if (o_ptr->tval == TV_LITE) {
86 if ((o_ptr->sval == SV_LITE_TORCH) && !(o_ptr->xtra4 > 0))
89 if ((o_ptr->sval == SV_LITE_LANTERN) && !(o_ptr->xtra4 > 0))
94 BIT_FLAGS flgs[TR_FLAG_SIZE];
95 object_flags(creature_ptr, o_ptr, flgs);
98 if (have_flag(flgs, TR_LITE_1) && o_ptr->name2 != EGO_LITE_DARKNESS)
101 if (have_flag(flgs, TR_LITE_2) && o_ptr->name2 != EGO_LITE_DARKNESS)
104 if (have_flag(flgs, TR_LITE_3) && o_ptr->name2 != EGO_LITE_DARKNESS)
107 if (have_flag(flgs, TR_LITE_M1))
110 if (have_flag(flgs, TR_LITE_M2))
113 if (have_flag(flgs, TR_LITE_M3))
116 creature_ptr->cur_lite += rad;
119 if (d_info[creature_ptr->dungeon_idx].flags1 & DF1_DARKNESS && creature_ptr->cur_lite > 1)
120 creature_ptr->cur_lite = 1;
122 if (creature_ptr->cur_lite <= 0 && creature_ptr->lite)
123 creature_ptr->cur_lite++;
125 if (creature_ptr->cur_lite > 14)
126 creature_ptr->cur_lite = 14;
128 if (creature_ptr->cur_lite < 0)
129 creature_ptr->cur_lite = 0;
131 if (creature_ptr->old_lite == creature_ptr->cur_lite)
134 creature_ptr->update |= PU_LITE | PU_MON_LITE | PU_MONSTERS;
135 creature_ptr->old_lite = creature_ptr->cur_lite;
137 if ((creature_ptr->cur_lite > 0) && (creature_ptr->special_defense & NINJA_S_STEALTH))
138 set_superstealth(creature_ptr, FALSE);
142 * Update the set of grids "illuminated" by the player's lite.
144 * This routine needs to use the results of "update_view()"
146 * Note that "blindness" does NOT affect "torch lite". Be careful!
148 * We optimize most lites (all non-artifact lites) by using "obvious"
149 * facts about the results of "small" lite radius, and we attempt to
150 * list the "nearby" grids before the more "distant" ones in the
151 * array of torch-lit grids.
153 * We assume that "radius zero" lite is in fact no lite at all.
155 * Torch Lantern Artifacts
165 void update_lite(player_type *subject_ptr)
167 POSITION p = subject_ptr->cur_lite;
169 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
170 for (int i = 0; i < floor_ptr->lite_n; i++) {
171 POSITION y = floor_ptr->lite_y[i];
172 POSITION x = floor_ptr->lite_x[i];
173 floor_ptr->grid_array[y][x].info &= ~(CAVE_LITE);
174 floor_ptr->grid_array[y][x].info |= CAVE_TEMP;
175 tmp_pos.y[tmp_pos.n] = y;
176 tmp_pos.x[tmp_pos.n] = x;
180 floor_ptr->lite_n = 0;
182 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x);
183 cave_lite_hack(floor_ptr, subject_ptr->y + 1, 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, subject_ptr->x + 1);
186 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x - 1);
187 cave_lite_hack(floor_ptr, subject_ptr->y + 1, 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);
194 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x)) {
195 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x);
196 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x + 1);
197 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x - 1);
200 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x)) {
201 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x);
202 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x + 1);
203 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x - 1);
206 if (cave_los_bold(floor_ptr, subject_ptr->y, subject_ptr->x + 1)) {
207 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x + 2);
208 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x + 2);
209 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x + 2);
212 if (cave_los_bold(floor_ptr, subject_ptr->y, subject_ptr->x - 1)) {
213 cave_lite_hack(floor_ptr, subject_ptr->y, subject_ptr->x - 2);
214 cave_lite_hack(floor_ptr, subject_ptr->y + 1, subject_ptr->x - 2);
215 cave_lite_hack(floor_ptr, subject_ptr->y - 1, subject_ptr->x - 2);
224 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x + 1))
225 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x + 2);
227 if (cave_los_bold(floor_ptr, subject_ptr->y + 1, subject_ptr->x - 1))
228 cave_lite_hack(floor_ptr, subject_ptr->y + 2, subject_ptr->x - 2);
230 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x + 1))
231 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x + 2);
233 if (cave_los_bold(floor_ptr, subject_ptr->y - 1, subject_ptr->x - 1))
234 cave_lite_hack(floor_ptr, subject_ptr->y - 2, subject_ptr->x - 2);
236 POSITION min_y = subject_ptr->y - p;
240 POSITION max_y = subject_ptr->y + p;
241 if (max_y > floor_ptr->height - 1)
242 max_y = floor_ptr->height - 1;
244 POSITION min_x = subject_ptr->x - p;
248 POSITION max_x = subject_ptr->x + p;
249 if (max_x > floor_ptr->width - 1)
250 max_x = floor_ptr->width - 1;
252 for (POSITION y = min_y; y <= max_y; y++) {
253 for (POSITION x = min_x; x <= max_x; x++) {
254 int dy = (subject_ptr->y > y) ? (subject_ptr->y - y) : (y - subject_ptr->y);
255 int dx = (subject_ptr->x > x) ? (subject_ptr->x - x) : (x - subject_ptr->x);
256 if ((dy <= 2) && (dx <= 2))
259 d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
263 if (floor_ptr->grid_array[y][x].info & CAVE_VIEW)
264 cave_lite_hack(floor_ptr, y, x);
269 for (int i = 0; i < floor_ptr->lite_n; i++) {
270 POSITION y = floor_ptr->lite_y[i];
271 POSITION x = floor_ptr->lite_x[i];
272 g_ptr = &floor_ptr->grid_array[y][x];
273 if (g_ptr->info & CAVE_TEMP)
276 cave_note_and_redraw_later(floor_ptr, g_ptr, y, x);
279 for (int i = 0; i < tmp_pos.n; i++) {
280 POSITION y = tmp_pos.y[i];
281 POSITION x = tmp_pos.x[i];
282 g_ptr = &floor_ptr->grid_array[y][x];
283 g_ptr->info &= ~(CAVE_TEMP);
284 if (g_ptr->info & CAVE_LITE)
287 cave_redraw_later(floor_ptr, g_ptr, y, x);
291 subject_ptr->update |= PU_DELAY_VIS;