1 #include "spell/spells-sight.h"
2 #include "core/stuff-handler.h"
3 #include "effect/effect-characteristics.h"
4 #include "floor/floor.h"
5 #include "monster/monster-status.h"
6 #include "player/avatar.h"
7 #include "spell/process-effect.h"
8 #include "spell/spells-type.h"
9 #include "view/display-main-window.h"
12 * @brief 視界内モンスターに魔法効果を与える / Apply a "project()" directly to all viewable monsters
15 * @return 効力があった場合TRUEを返す
18 * Note that affected monsters are NOT auto-tracked by this usage.
20 * To avoid misbehavior when monster deaths have side-effects,
21 * this is done in two passes. -- JDL
24 bool project_all_los(player_type *caster_ptr, EFFECT_ID typ, HIT_POINT dam)
26 for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
27 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
28 if (!monster_is_valid(m_ptr))
31 POSITION y = m_ptr->fy;
32 POSITION x = m_ptr->fx;
33 if (!player_has_los_bold(caster_ptr, y, x) || !projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x))
36 m_ptr->mflag |= (MFLAG_LOS);
39 BIT_FLAGS flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
41 for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
42 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
43 if (!(m_ptr->mflag & (MFLAG_LOS)))
46 m_ptr->mflag &= ~(MFLAG_LOS);
47 POSITION y = m_ptr->fy;
48 POSITION x = m_ptr->fx;
50 if (project(caster_ptr, 0, 0, y, x, dam, typ, flg, -1))
58 * @brief 視界内モンスターを加速する処理 / Speed monsters
59 * @param caster_ptr プレーヤーへの参照ポインタ
60 * @return 効力があった場合TRUEを返す
62 bool speed_monsters(player_type *caster_ptr) { return (project_all_los(caster_ptr, GF_OLD_SPEED, caster_ptr->lev)); }
65 * @brief 視界内モンスターを加速する処理 / Slow monsters
66 * @param caster_ptr プレーヤーへの参照ポインタ
67 * @return 効力があった場合TRUEを返す
69 bool slow_monsters(player_type *caster_ptr, int power) { return (project_all_los(caster_ptr, GF_OLD_SLOW, power)); }
72 * @brief 視界内モンスターを眠らせる処理 / Sleep monsters
73 * @param caster_ptr プレーヤーへの参照ポインタ
74 * @return 効力があった場合TRUEを返す
76 bool sleep_monsters(player_type *caster_ptr, int power) { return (project_all_los(caster_ptr, GF_OLD_SLEEP, power)); }
79 * @brief 視界内の邪悪なモンスターをテレポート・アウェイさせる処理 / Banish evil monsters
80 * @param caster_ptr プレーヤーへの参照ポインタ
81 * @return 効力があった場合TRUEを返す
83 bool banish_evil(player_type *caster_ptr, int dist) { return (project_all_los(caster_ptr, GF_AWAY_EVIL, dist)); }
86 * @brief 視界内のアンデッド・モンスターを恐怖させる処理 / Turn undead
87 * @return 効力があった場合TRUEを返す
89 bool turn_undead(player_type *caster_ptr)
91 bool tester = (project_all_los(caster_ptr, GF_TURN_UNDEAD, caster_ptr->lev));
93 chg_virtue(caster_ptr, V_UNLIFE, -1);
98 * @brief 視界内のアンデッド・モンスターにダメージを与える処理 / Dispel undead monsters
99 * @param caster_ptr プレーヤーへの参照ポインタ
100 * @return 効力があった場合TRUEを返す
102 bool dispel_undead(player_type *caster_ptr, HIT_POINT dam)
104 bool tester = (project_all_los(caster_ptr, GF_DISP_UNDEAD, dam));
106 chg_virtue(caster_ptr, V_UNLIFE, -2);
111 * @brief 視界内の邪悪なモンスターにダメージを与える処理 / Dispel evil monsters
112 * @param caster_ptr プレーヤーへの参照ポインタ
113 * @return 効力があった場合TRUEを返す
115 bool dispel_evil(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_DISP_EVIL, dam)); }
118 * @brief 視界内の善良なモンスターにダメージを与える処理 / Dispel good monsters
119 * @param caster_ptr プレーヤーへの参照ポインタ
120 * @return 効力があった場合TRUEを返す
122 bool dispel_good(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_DISP_GOOD, dam)); }
125 * @brief 視界内のあらゆるモンスターにダメージを与える処理 / Dispel all monsters
126 * @param caster_ptr プレーヤーへの参照ポインタ
127 * @return 効力があった場合TRUEを返す
129 bool dispel_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_DISP_ALL, dam)); }
132 * @brief 視界内の生命のあるモンスターにダメージを与える処理 / Dispel 'living' monsters
133 * @param caster_ptr プレーヤーへの参照ポインタ
134 * @return 効力があった場合TRUEを返す
136 bool dispel_living(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_DISP_LIVING, dam)); }
139 * @brief 視界内の悪魔系モンスターにダメージを与える処理 / Dispel 'living' monsters
140 * @param caster_ptr プレーヤーへの参照ポインタ
141 * @return 効力があった場合TRUEを返す
143 bool dispel_demons(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_DISP_DEMON, dam)); }
146 * @brief 視界内のモンスターに「聖戦」効果を与える処理
147 * @param caster_ptr プレーヤーへの参照ポインタ
148 * @return 効力があった場合TRUEを返す
150 bool crusade(player_type *caster_ptr) { return (project_all_los(caster_ptr, GF_CRUSADE, caster_ptr->lev * 4)); }
153 * @brief 視界内モンスターを怒らせる処理 / Wake up all monsters, and speed up "los" monsters.
154 * @param caster_ptr プレーヤーへの参照ポインタ
155 * @param who 怒らせる原因を起こしたモンスター(0ならばプレイヤー)
158 void aggravate_monsters(player_type *caster_ptr, MONSTER_IDX who)
162 for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
163 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
164 if (!monster_is_valid(m_ptr))
169 if (m_ptr->cdis < MAX_SIGHT * 2) {
170 if (MON_CSLEEP(m_ptr)) {
171 (void)set_monster_csleep(caster_ptr, i, 0);
176 m_ptr->mflag2 |= MFLAG2_NOPET;
179 if (player_has_los_bold(caster_ptr, m_ptr->fy, m_ptr->fx)) {
180 if (!is_pet(m_ptr)) {
181 (void)set_monster_fast(caster_ptr, i, MON_FAST(m_ptr) + 100);
188 msg_print(_("付近で何かが突如興奮したような感じを受けた!", "You feel a sudden stirring nearby!"));
190 msg_print(_("何かが突如興奮したような騒々しい音が遠くに聞こえた!", "You hear a sudden stirring in the distance!"));
191 if (caster_ptr->riding)
192 caster_ptr->update |= PU_BONUS;
196 * @brief パニック・モンスター効果(プレイヤー視界範囲内) / Confuse monsters
197 * @param caster_ptr プレーヤーへの参照ポインタ
199 * @return 作用が実際にあった場合TRUEを返す
201 bool confuse_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_OLD_CONF, dam)); }
204 * @brief チャーム・モンスター効果(プレイヤー視界範囲内) / Charm monsters
205 * @param caster_ptr プレーヤーへの参照ポインタ
207 * @return 作用が実際にあった場合TRUEを返す
209 bool charm_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_CHARM, dam)); }
212 * @brief 動物魅了効果(プレイヤー視界範囲内) / Charm Animals
213 * @param caster_ptr プレーヤーへの参照ポインタ
215 * @return 作用が実際にあった場合TRUEを返す
217 bool charm_animals(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_CONTROL_ANIMAL, dam)); }
220 * @brief モンスター朦朧効果(プレイヤー視界範囲内) / Stun monsters
221 * @param caster_ptr プレーヤーへの参照ポインタ
223 * @return 作用が実際にあった場合TRUEを返す
225 bool stun_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_STUN, dam)); }
228 * @brief モンスター停止効果(プレイヤー視界範囲内) / Stasis monsters
229 * @param caster_ptr プレーヤーへの参照ポインタ
231 * @return 作用が実際にあった場合TRUEを返す
233 bool stasis_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_STASIS, dam)); }
236 * @brief モンスター精神攻撃効果(プレイヤー視界範囲内) / Mindblast monsters
237 * @param caster_ptr プレーヤーへの参照ポインタ
239 * @return 作用が実際にあった場合TRUEを返す
241 bool mindblast_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_PSI, dam)); }
244 * @brief モンスター追放効果(プレイヤー視界範囲内) / Banish all monsters
245 * @param caster_ptr プレーヤーへの参照ポインタ
247 * @return 作用が実際にあった場合TRUEを返す
249 bool banish_monsters(player_type *caster_ptr, int dist) { return (project_all_los(caster_ptr, GF_AWAY_ALL, dist)); }
252 * @brief 邪悪退散効果(プレイヤー視界範囲内) / Turn evil
253 * @param caster_ptr プレーヤーへの参照ポインタ
255 * @return 作用が実際にあった場合TRUEを返す
257 bool turn_evil(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_TURN_EVIL, dam)); }
260 * @brief 全モンスター退散効果(プレイヤー視界範囲内) / Turn everyone
261 * @param caster_ptr プレーヤーへの参照ポインタ
263 * @return 作用が実際にあった場合TRUEを返す
265 bool turn_monsters(player_type *caster_ptr, HIT_POINT dam) { return (project_all_los(caster_ptr, GF_TURN_ALL, dam)); }
268 * @brief 死の光線(プレイヤー視界範囲内) / Death-ray all monsters (note: OBSCENELY powerful)
269 * @param caster_ptr プレーヤーへの参照ポインタ
270 * @return 作用が実際にあった場合TRUEを返す
272 bool deathray_monsters(player_type *caster_ptr) { return (project_all_los(caster_ptr, GF_DEATH_RAY, caster_ptr->lev * 200)); }
275 * @brief 周辺モンスターを調査する / Probe nearby monsters
276 * @return 効力があった場合TRUEを返す
278 bool probing(player_type *caster_ptr)
280 bool cu = Term->scr->cu;
281 bool cv = Term->scr->cv;
289 for (int i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
290 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
291 monster_race *r_ptr = &r_info[m_ptr->r_idx];
292 if (!monster_is_valid(m_ptr))
294 if (!player_has_los_bold(caster_ptr, m_ptr->fy, m_ptr->fx))
299 GAME_TEXT m_name[MAX_NLEN];
301 msg_print(_("調査中...", "Probing..."));
304 if (!is_original_ap(m_ptr)) {
305 if (m_ptr->mflag2 & MFLAG2_KAGE)
306 m_ptr->mflag2 &= ~(MFLAG2_KAGE);
308 m_ptr->ap_r_idx = m_ptr->r_idx;
309 lite_spot(caster_ptr, m_ptr->fy, m_ptr->fx);
312 monster_desc(caster_ptr, m_name, m_ptr, MD_IGNORE_HALLU | MD_INDEF_HIDDEN);
313 speed = m_ptr->mspeed - 110;
318 if (ironman_nightmare)
321 if ((r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)) == (RF3_EVIL | RF3_GOOD))
322 align = _("善悪", "good&evil");
323 else if (r_ptr->flags3 & RF3_EVIL)
324 align = _("邪悪", "evil");
325 else if (r_ptr->flags3 & RF3_GOOD)
326 align = _("善良", "good");
327 else if ((m_ptr->sub_align & (SUB_ALIGN_EVIL | SUB_ALIGN_GOOD)) == (SUB_ALIGN_EVIL | SUB_ALIGN_GOOD))
328 align = _("中立(善悪)", "neutral(good&evil)");
329 else if (m_ptr->sub_align & SUB_ALIGN_EVIL)
330 align = _("中立(邪悪)", "neutral(evil)");
331 else if (m_ptr->sub_align & SUB_ALIGN_GOOD)
332 align = _("中立(善良)", "neutral(good)");
334 align = _("中立", "neutral");
336 sprintf(buf, _("%s ... 属性:%s HP:%d/%d AC:%d 速度:%s%d 経験:", "%s ... align:%s HP:%d/%d AC:%d speed:%s%d exp:"), m_name, align, (int)m_ptr->hp,
337 (int)m_ptr->maxhp, r_ptr->ac, (speed > 0) ? "+" : "", speed);
339 if (r_ptr->next_r_idx) {
340 strcat(buf, format("%d/%d ", m_ptr->exp, r_ptr->next_exp));
345 if (MON_CSLEEP(m_ptr))
346 strcat(buf, _("睡眠 ", "sleeping "));
347 if (MON_STUNNED(m_ptr))
348 strcat(buf, _("朦朧 ", "stunned "));
349 if (MON_MONFEAR(m_ptr))
350 strcat(buf, _("恐怖 ", "scared "));
351 if (MON_CONFUSED(m_ptr))
352 strcat(buf, _("混乱 ", "confused "));
353 if (MON_INVULNER(m_ptr))
354 strcat(buf, _("無敵 ", "invulnerable "));
355 buf[strlen(buf) - 1] = '\0';
359 caster_ptr->window |= (PW_MESSAGE);
360 handle_stuff(caster_ptr);
361 move_cursor_relative(m_ptr->fy, m_ptr->fx);
363 Term_erase(0, 0, 255);
364 if (lore_do_probe(caster_ptr, m_ptr->r_idx)) {
365 strcpy(buf, (r_name + r_ptr->name));
367 msg_format("%sについてさらに詳しくなった気がする。", buf);
370 msg_format("You now know more about %s.", buf);
383 chg_virtue(caster_ptr, V_KNOWLEDGE, 1);
384 msg_print(_("これで全部です。", "That's all."));