1 #include "effect/effect-item.h"
2 #include "autopick/autopick.h"
3 #include "floor/floor-object.h"
4 #include "floor/floor.h"
5 #include "monster-floor/monster-summon.h"
6 #include "monster-floor/place-monster-types.h"
7 #include "monster/monster-info.h"
8 #include "object-enchant/tr-types.h"
9 #include "object-hook/hook-checker.h"
10 #include "object-hook/hook-enchant.h"
11 #include "object-hook/hook-expendable.h"
12 #include "object/object-broken.h"
13 #include "object/object-flags.h"
14 #include "object/object-flavor.h"
15 #include "object/object-mark-types.h"
16 #include "perception/object-perception.h"
17 #include "spell-kind/spells-perception.h"
18 #include "spell/spell-types.h"
19 #include "sv-definition/sv-other-types.h"
20 #include "sv-definition/sv-scroll-types.h"
21 #include "util/bit-flags-calculator.h"
22 #include "view/display-messages.h"
25 * @brief 汎用的なビーム/ボルト/ボール系によるアイテムオブジェクトへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.
26 * @param caster_ptr プレーヤーへの参照ポインタ
27 * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
28 * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
29 * @param y 目標Y座標 / Target y location (or location to travel "towards")
30 * @param x 目標X座標 / Target x location (or location to travel "towards")
31 * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
32 * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
33 * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
35 bool affect_item(player_type *caster_ptr, MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
37 grid_type *g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
39 bool is_item_affected = FALSE;
40 bool known = player_has_los_bold(caster_ptr, y, x);
42 dam = (dam + r) / (r + 1);
43 OBJECT_IDX next_o_idx = 0;
44 for (OBJECT_IDX this_o_idx = g_ptr->o_idx; this_o_idx != 0; this_o_idx = next_o_idx)
46 object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[this_o_idx];
49 concptr note_kill = NULL;
53 bool plural = (o_ptr->number > 1);
55 next_o_idx = o_ptr->next_o_idx;
56 BIT_FLAGS flags[TR_FLAG_SIZE];
57 object_flags(caster_ptr, o_ptr, flags);
58 bool is_artifact = object_is_artifact(o_ptr);
63 if (hates_acid(o_ptr))
66 note_kill = _("融けてしまった!", (plural ? " melt!" : " melts!"));
67 if (have_flag(flags, TR_IGNORE_ACID)) ignore = TRUE;
74 if (hates_elec(o_ptr))
77 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
78 if (have_flag(flags, TR_IGNORE_ELEC)) ignore = TRUE;
85 if (hates_fire(o_ptr))
88 note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
89 if (have_flag(flags, TR_IGNORE_FIRE)) ignore = TRUE;
96 if (hates_cold(o_ptr))
98 note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
100 if (have_flag(flags, TR_IGNORE_COLD)) ignore = TRUE;
107 if (hates_fire(o_ptr))
110 note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
111 if (have_flag(flags, TR_IGNORE_FIRE)) ignore = TRUE;
114 if (hates_elec(o_ptr))
118 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
119 if (have_flag(flags, TR_IGNORE_ELEC)) ignore = TRUE;
126 if (hates_fire(o_ptr))
129 note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
130 if (have_flag(flags, TR_IGNORE_FIRE)) ignore = TRUE;
133 if (hates_cold(o_ptr))
137 note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
138 if (have_flag(flags, TR_IGNORE_COLD)) ignore = TRUE;
148 if (hates_cold(o_ptr))
150 note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
161 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
164 case GF_DISINTEGRATE:
167 note_kill = _("蒸発してしまった!", (plural ? " evaporate!" : " evaporates!"));
173 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
174 if (have_flag(flags, TR_RES_CHAOS)) ignore = TRUE;
175 else if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_CHAOS)) ignore = TRUE;
181 if (object_is_cursed(o_ptr))
184 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
191 identify_item(caster_ptr, o_ptr);
192 autopick_alter_item(caster_ptr, (-this_o_idx), FALSE);
198 if (o_ptr->tval != TV_CHEST) break;
199 if (o_ptr->pval <= 0) break;
201 o_ptr->pval = (0 - o_ptr->pval);
203 if (known && (o_ptr->marked & OM_FOUND))
205 msg_print(_("カチッと音がした!", "Click!"));
206 is_item_affected = TRUE;
213 if (o_ptr->tval != TV_CORPSE) break;
216 if (!who || is_pet(&caster_ptr->current_floor_ptr->m_list[who]))
217 mode |= PM_FORCE_PET;
219 for (int i = 0; i < o_ptr->number; i++)
221 if (((o_ptr->sval == SV_CORPSE) && (randint1(100) > 80)) ||
222 ((o_ptr->sval == SV_SKELETON) && (randint1(100) > 60)))
226 note_kill = _("灰になった。", (plural ? " become dust." : " becomes dust."));
231 else if (summon_named_creature(caster_ptr, who, y, x, o_ptr->pval, mode))
233 note_kill = _("生き返った。", " revived.");
237 note_kill = _("灰になった。", (plural ? " become dust." : " becomes dust."));
242 is_item_affected = TRUE;
247 if (!do_kill) continue;
249 GAME_TEXT o_name[MAX_NLEN];
250 if (known && (o_ptr->marked & OM_FOUND))
252 is_item_affected = TRUE;
253 object_desc(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
256 if ((is_artifact || ignore))
258 if (known && (o_ptr->marked & OM_FOUND))
259 msg_format(_("%sは影響を受けない!", (plural ? "The %s are unaffected!" : "The %s is unaffected!")), o_name);
264 if (known && (o_ptr->marked & OM_FOUND) && note_kill)
265 msg_format(_("%sは%s", "The %s%s"), o_name, note_kill);
267 KIND_OBJECT_IDX k_idx = o_ptr->k_idx;
268 bool is_potion = object_is_potion(o_ptr);
269 delete_object_idx(caster_ptr, this_o_idx);
271 (void)potion_smash_effect(caster_ptr, who, y, x, k_idx);
273 lite_spot(caster_ptr, y, x);
276 return is_item_affected;