2 #include "effect/effect-feature.h"
5 #include "main/sound-definitions-table.h"
7 #include "player-effects.h"
11 * @brief 汎用的なビーム/ボルト/ボール系による地形効果処理 / We are called from "project()" to "damage" terrain features
12 * @param caster_ptr プレーヤーへの参照ポインタ
13 * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
14 * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
15 * @param y 目標Y座標 / Target y location (or location to travel "towards")
16 * @param x 目標X座標 / Target x location (or location to travel "towards")
17 * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
18 * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
19 * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
22 * We are called both for "beam" effects and "ball" effects.
24 * The "r" parameter is the "distance from ground zero".
26 * Note that we determine if the player can "see" anything that happens
27 * by taking into account: blindness, line-of-sight, and illumination.
29 * We return "TRUE" if the effect of the projection is "obvious".
31 * We also "see" grids which are "memorized", probably a hack
33 * Perhaps we should affect doors?
36 bool affect_feature(player_type *caster_ptr, MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
38 floor_type *floor_ptr = caster_ptr->current_floor_ptr;
39 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
40 feature_type *f_ptr = &f_info[g_ptr->feat];
43 bool known = player_has_los_bold(caster_ptr, y, x);
46 dam = (dam + r) / (r + 1);
48 if (have_flag(f_ptr->flags, FF_TREE))
56 message = _("枯れた", "was blasted."); break;
58 message = _("縮んだ", "shrank."); break;
60 message = _("溶けた", "melted."); break;
63 message = _("凍り、砕け散った", "was frozen and smashed."); break;
67 message = _("燃えた", "burns up!"); break;
79 message = _("粉砕された", "was crushed."); break;
81 message = NULL; break;
86 msg_format(_("木は%s。", "A tree %s"), message);
87 cave_set_feat(caster_ptr, y, x, one_in_(3) ? feat_brake : feat_grass);
90 if (g_ptr->info & (CAVE_MARK)) obvious = TRUE;
94 /* Analyze the type */
97 /* Ignore most effects */
133 if (is_hidden_door(caster_ptr, g_ptr))
135 disclose_grid(caster_ptr, y, x);
142 if (is_trap(caster_ptr, g_ptr->feat))
146 msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
150 cave_alter_feat(caster_ptr, y, x, FF_DISARM);
153 if (is_closed_door(caster_ptr, g_ptr->feat) && f_ptr->power && have_flag(f_ptr->flags, FF_OPEN))
155 FEAT_IDX old_feat = g_ptr->feat;
156 cave_alter_feat(caster_ptr, y, x, FF_DISARM);
157 if (known && (old_feat != g_ptr->feat))
159 msg_print(_("カチッと音がした!", "Click!"));
164 if (caster_ptr->blind || !player_has_los_bold(caster_ptr, y, x)) break;
166 g_ptr->info &= ~(CAVE_UNSAFE);
167 lite_spot(caster_ptr, y, x);
173 if (is_trap(caster_ptr, g_ptr->feat) || have_flag(f_ptr->flags, FF_DOOR))
177 msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
181 cave_alter_feat(caster_ptr, y, x, FF_TUNNEL);
184 if (caster_ptr->blind || !player_has_los_bold(caster_ptr, y, x)) break;
186 g_ptr->info &= ~(CAVE_UNSAFE);
187 lite_spot(caster_ptr, y, x);
193 if (!have_flag(f_ptr->flags, FF_SPIKE)) break;
195 s16b old_mimic = g_ptr->mimic;
196 feature_type *mimic_f_ptr = &f_info[get_feat_mimic(g_ptr)];
198 cave_alter_feat(caster_ptr, y, x, FF_SPIKE);
199 g_ptr->mimic = old_mimic;
201 note_spot(caster_ptr, y, x);
202 lite_spot(caster_ptr, y, x);
204 if (!known || !have_flag(mimic_f_ptr->flags, FF_OPEN)) break;
206 msg_format(_("%sに何かがつっかえて開かなくなった。", "The %s seems stuck."), f_name + mimic_f_ptr->name);
212 if (!have_flag(f_ptr->flags, FF_HURT_ROCK)) break;
214 if (known && (g_ptr->info & (CAVE_MARK)))
216 msg_format(_("%sが溶けて泥になった!", "The %s turns into mud!"), f_name + f_info[get_feat_mimic(g_ptr)].name);
220 cave_alter_feat(caster_ptr, y, x, FF_HURT_ROCK);
221 caster_ptr->update |= (PU_FLOW);
226 if (!cave_naked_bold(caster_ptr, floor_ptr, y, x)) break;
227 if (player_bold(caster_ptr, y, x)) break;
228 cave_set_feat(caster_ptr, y, x, feat_door[DOOR_DOOR].closed);
229 if (g_ptr->info & (CAVE_MARK)) obvious = TRUE;
234 place_trap(caster_ptr, y, x);
239 if (!cave_naked_bold(caster_ptr, floor_ptr, y, x)) break;
240 if (player_bold(caster_ptr, y, x)) break;
241 cave_set_feat(caster_ptr, y, x, feat_tree);
242 if (g_ptr->info & (CAVE_MARK)) obvious = TRUE;
247 if (!cave_naked_bold(caster_ptr, floor_ptr, y, x)) break;
248 g_ptr->info |= CAVE_OBJECT;
249 g_ptr->mimic = feat_glyph;
250 note_spot(caster_ptr, y, x);
251 lite_spot(caster_ptr, y, x);
256 if (!cave_naked_bold(caster_ptr, floor_ptr, y, x)) break;
257 if (player_bold(caster_ptr, y, x)) break;
258 cave_set_feat(caster_ptr, y, x, feat_granite);
263 if (have_flag(f_ptr->flags, FF_PERMANENT)) break;
266 if (!have_flag(f_ptr->flags, FF_FLOOR)) break;
267 cave_set_feat(caster_ptr, y, x, feat_shallow_lava);
271 cave_set_feat(caster_ptr, y, x, feat_deep_lava);
278 if (have_flag(f_ptr->flags, FF_PERMANENT)) break;
281 if (!have_flag(f_ptr->flags, FF_FLOOR)) break;
282 cave_set_feat(caster_ptr, y, x, feat_shallow_water);
286 cave_set_feat(caster_ptr, y, x, feat_deep_water);
294 if ((d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) != 0) break;
296 g_ptr->info |= (CAVE_GLOW);
297 note_spot(caster_ptr, y, x);
298 lite_spot(caster_ptr, y, x);
299 update_local_illumination(caster_ptr, y, x);
301 if (player_can_see_bold(caster_ptr, y, x)) obvious = TRUE;
302 if (g_ptr->m_idx) update_monster(caster_ptr, g_ptr->m_idx, FALSE);
304 if (caster_ptr->special_defense & NINJA_S_STEALTH)
306 if (player_bold(caster_ptr, y, x)) set_superstealth(caster_ptr, FALSE);
314 bool do_dark = !caster_ptr->phase_out && !is_mirror_grid(g_ptr);
317 if ((floor_ptr->dun_level > 0) || !is_daytime())
319 for (int j = 0; j < 9; j++)
321 int by = y + ddy_ddd[j];
322 int bx = x + ddx_ddd[j];
324 if (!in_bounds2(floor_ptr, by, bx)) continue;
326 grid_type *cc_ptr = &floor_ptr->grid_array[by][bx];
327 if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
337 g_ptr->info &= ~(CAVE_GLOW);
339 /* Hack -- Forget "boring" grids */
340 if (!have_flag(f_ptr->flags, FF_REMEMBER))
343 g_ptr->info &= ~(CAVE_MARK);
344 note_spot(caster_ptr, y, x);
347 lite_spot(caster_ptr, y, x);
349 update_local_illumination(caster_ptr, y, x);
351 if (player_can_see_bold(caster_ptr, y, x)) obvious = TRUE;
352 if (g_ptr->m_idx) update_monster(caster_ptr, g_ptr->m_idx, FALSE);
359 if (is_mirror_grid(g_ptr))
361 msg_print(_("鏡が割れた!", "The mirror was shattered!"));
363 remove_mirror(caster_ptr, y, x);
364 project(caster_ptr, 0, 2, y, x, caster_ptr->lev / 2 + 5, GF_SHARDS, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
367 if (!have_flag(f_ptr->flags, FF_GLASS) || have_flag(f_ptr->flags, FF_PERMANENT) || (dam < 50))
370 if (known && (g_ptr->info & CAVE_MARK))
372 msg_format(_("%sが割れた!", "The %s crumbled!"), f_name + f_info[get_feat_mimic(g_ptr)].name);
376 cave_alter_feat(caster_ptr, y, x, FF_HURT_ROCK);
377 caster_ptr->update |= (PU_FLOW);
382 if (is_mirror_grid(g_ptr) && caster_ptr->lev < 40)
384 msg_print(_("鏡が割れた!", "The mirror was shattered!"));
386 remove_mirror(caster_ptr, y, x);
387 project(caster_ptr, 0, 2, y, x, caster_ptr->lev / 2 + 5, GF_SHARDS, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
390 if (!have_flag(f_ptr->flags, FF_GLASS) || have_flag(f_ptr->flags, FF_PERMANENT) || (dam < 200))
393 if (known && (g_ptr->info & CAVE_MARK))
395 msg_format(_("%sが割れた!", "The %s crumbled!"), f_name + f_info[get_feat_mimic(g_ptr)].name);
399 cave_alter_feat(caster_ptr, y, x, FF_HURT_ROCK);
400 caster_ptr->update |= (PU_FLOW);
403 case GF_DISINTEGRATE:
405 if (is_mirror_grid(g_ptr) || is_glyph_grid(g_ptr) || is_explosive_rune_grid(g_ptr))
406 remove_mirror(caster_ptr, y, x);
408 if (!have_flag(f_ptr->flags, FF_HURT_DISI) || have_flag(f_ptr->flags, FF_PERMANENT))
411 cave_alter_feat(caster_ptr, y, x, FF_HURT_DISI);
412 caster_ptr->update |= (PU_FLOW);
417 lite_spot(caster_ptr, y, x);