*/
#include "angband.h"
+#include "util.h"
+
+#include "floor.h"
+#include "dungeon.h"
+#include "grid.h"
#include "object-curse.h"
-#include "projection.h"
#include "quest.h"
#include "realm-hex.h"
#include "player-move.h"
#include "player-status.h"
+#include "monster.h"
+#include "monster-spell.h"
+#include "spells.h"
+#include "world.h"
+#include "realm-song.h"
+#include "view-mainwindow.h"
+#include "player-race.h"
+#include "player-class.h"
/*!
*/
static void remove_bad_spells(MONSTER_IDX m_idx, u32b *f4p, u32b *f5p, u32b *f6p)
{
- monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
+ monster_type *m_ptr = &p_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
u32b f4 = (*f4p);
if (smart & (SM_RES_NETH))
{
- if (prace_is_(RACE_SPECTRE))
+ if (PRACE_IS_(p_ptr, RACE_SPECTRE))
{
f4 &= ~(RF4_BR_NETH);
f5 &= ~(RF5_BA_NETH);
if (smart & (SM_RES_DARK))
{
- if (prace_is_(RACE_VAMPIRE))
+ if (PRACE_IS_(p_ptr, RACE_VAMPIRE))
{
f4 &= ~(RF4_BR_DARK);
f5 &= ~(RF5_BA_DARK);
for (x = x1 - 2; x <= x1 + 2; x++)
{
/* Ignore illegal locations */
- if (!in_bounds(y, x)) continue;
+ if (!in_bounds(p_ptr->current_floor_ptr, y, x)) continue;
/* Only check a circular area */
if (distance(y1, x1, y, x)>2) continue;
if (pattern_tile(y, x)) continue;
/* Require empty floor grid in line of projection */
- if (cave_empty_bold(y, x) && projectable(y1, x1, y, x) && projectable(y, x, y1, x1)) return (TRUE);
+ if (cave_empty_bold(p_ptr->current_floor_ptr, y, x) && projectable(p_ptr->current_floor_ptr, y1, x1, y, x) && projectable(p_ptr->current_floor_ptr, y, x, y1, x1)) return (TRUE);
}
}
for (yy = y - 5; yy <= y + 5; yy++)
{
if (distance(y, x, yy, xx) > 5) continue;
- if (!los(y, x, yy, xx)) continue;
- if (!projectable(y, x, yy, xx)) continue;
+ if (!los(p_ptr->current_floor_ptr, y, x, yy, xx)) continue;
+ if (!projectable(p_ptr->current_floor_ptr, y, x, yy, xx)) continue;
- g_ptr = ¤t_floor_ptr->grid_array[yy][xx];
+ g_ptr = &p_ptr->current_floor_ptr->grid_array[yy][xx];
/* Scan the pile of objects */
for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
{
- object_type *o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
+ object_type *o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx];
next_o_idx = o_ptr->next_o_idx;
/* Known to be worthless? */
y = GRID_Y(grid_g[i]);
x = GRID_X(grid_g[i]);
- if ((current_floor_ptr->grid_array[y][x].m_idx > 0) && !((y == y2) && (x == x2)))
+ if ((p_ptr->current_floor_ptr->grid_array[y][x].m_idx > 0) && !((y == y2) && (x == x2)))
{
- monster_type *m_ptr = ¤t_floor_ptr->m_list[current_floor_ptr->grid_array[y][x].m_idx];
+ monster_type *m_ptr = &p_ptr->current_floor_ptr->m_list[p_ptr->current_floor_ptr->grid_array[y][x].m_idx];
if (is_friend == is_pet(m_ptr))
{
return (FALSE);
}
}
/* Pets may not shoot through the character - TNB */
- if (player_bold(y, x))
+ if (player_bold(p_ptr, y, x))
{
if (is_friend) return (FALSE);
}
if (typ != GF_ARROW) flg |= PROJECT_REFLECTABLE;
/* Target the player with a bolt attack */
- (void)project(m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+ (void)project(p_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
}
/*!
}
/* Target the player with a bolt attack */
- (void)project(m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+ (void)project(p_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
}
*/
void breath(POSITION y, POSITION x, MONSTER_IDX m_idx, EFFECT_ID typ, int dam_hp, POSITION rad, bool breath, int monspell, int target_type)
{
- monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
+ monster_type *m_ptr = &p_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
bool learnable = spell_learnable(m_idx);
BIT_FLAGS flg = 0x00;
}
/* Target the player with a ball attack */
- (void)project(m_idx, rad, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+ (void)project(p_ptr, m_idx, rad, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
}
*/
static bool spell_special(byte spell)
{
- if (p_ptr->inside_battle) return FALSE;
+ if (p_ptr->phase_out) return FALSE;
if (spell == 160 + 7) return (TRUE);
return (FALSE);
}
*/
bool dispel_check(MONSTER_IDX m_idx)
{
- monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
+ monster_type *m_ptr = &p_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
/* Invulnabilty (including the song) */
/* Elemental resistances */
if (r_ptr->flags4 & RF4_BR_ACID)
{
- if (!p_ptr->immune_acid && (p_ptr->oppose_acid || music_singing(MUSIC_RESIST))) return (TRUE);
+ if (!p_ptr->immune_acid && (p_ptr->oppose_acid || music_singing(p_ptr, MUSIC_RESIST))) return (TRUE);
if (p_ptr->special_defense & DEFENSE_ACID) return (TRUE);
}
{
if (!((p_ptr->prace == RACE_DEMON) && p_ptr->lev > 44))
{
- if (!p_ptr->immune_fire && (p_ptr->oppose_fire || music_singing(MUSIC_RESIST))) return (TRUE);
+ if (!p_ptr->immune_fire && (p_ptr->oppose_fire || music_singing(p_ptr, MUSIC_RESIST))) return (TRUE);
if (p_ptr->special_defense & DEFENSE_FIRE) return (TRUE);
}
}
if (r_ptr->flags4 & RF4_BR_ELEC)
{
- if (!p_ptr->immune_elec && (p_ptr->oppose_elec || music_singing(MUSIC_RESIST))) return (TRUE);
+ if (!p_ptr->immune_elec && (p_ptr->oppose_elec || music_singing(p_ptr, MUSIC_RESIST))) return (TRUE);
if (p_ptr->special_defense & DEFENSE_ELEC) return (TRUE);
}
if (r_ptr->flags4 & RF4_BR_COLD)
{
- if (!p_ptr->immune_cold && (p_ptr->oppose_cold || music_singing(MUSIC_RESIST))) return (TRUE);
+ if (!p_ptr->immune_cold && (p_ptr->oppose_cold || music_singing(p_ptr, MUSIC_RESIST))) return (TRUE);
if (p_ptr->special_defense & DEFENSE_COLD) return (TRUE);
}
{
if (!((p_ptr->pclass == CLASS_NINJA) && p_ptr->lev > 44))
{
- if (p_ptr->oppose_pois || music_singing(MUSIC_RESIST)) return (TRUE);
+ if (p_ptr->oppose_pois || music_singing(p_ptr, MUSIC_RESIST)) return (TRUE);
if (p_ptr->special_defense & DEFENSE_POIS) return (TRUE);
}
}
if ((p_ptr->special_attack & ATTACK_COLD) && !(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) return (TRUE);
if ((p_ptr->special_attack & ATTACK_POIS) && !(r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)) return (TRUE);
- /* Speed */
if (p_ptr->pspeed < 145)
{
if (IS_FAST()) return (TRUE);
/* Light speed */
if (p_ptr->lightspeed && (m_ptr->mspeed < 136)) return (TRUE);
- if (p_ptr->riding && (current_floor_ptr->m_list[p_ptr->riding].mspeed < 135))
+ if (p_ptr->riding && (p_ptr->current_floor_ptr->m_list[p_ptr->riding].mspeed < 135))
{
- if (MON_FAST(¤t_floor_ptr->m_list[p_ptr->riding])) return (TRUE);
+ if (MON_FAST(&p_ptr->current_floor_ptr->m_list[p_ptr->riding])) return (TRUE);
}
/* No need to cast dispel spell */
*/
static int choose_attack_spell(MONSTER_IDX m_idx, byte spells[], byte num)
{
- monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
+ monster_type *m_ptr = &p_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
byte escape[96], escape_num = 0;
* @return 有効な座標があった場合TRUEを返す
*/
static bool adjacent_grid_check(monster_type *m_ptr, POSITION *yp, POSITION *xp,
- int f_flag, bool (*path_check)(POSITION, POSITION, POSITION, POSITION))
+ int f_flag, bool (*path_check)(floor_type *, POSITION, POSITION, POSITION, POSITION))
{
int i;
int tonari;
grid_type *g_ptr;
/* Access the next grid */
- g_ptr = ¤t_floor_ptr->grid_array[next_y][next_x];
+ g_ptr = &p_ptr->current_floor_ptr->grid_array[next_y][next_x];
/* Skip this feature */
if (!cave_have_flag_grid(g_ptr, f_flag)) continue;
- if (path_check(m_ptr->fy, m_ptr->fx, next_y, next_x))
+ if (path_check(p_ptr->current_floor_ptr, m_ptr->fy, m_ptr->fx, next_y, next_x))
{
*yp = next_y;
*xp = next_x;
* Note the special "MFLAG_NICE" flag, which prevents a monster from using\n
* any spell attacks until the player has had a single chance to move.\n
*/
-bool make_attack_spell(MONSTER_IDX m_idx)
+bool make_attack_spell(MONSTER_IDX m_idx, player_type *target_ptr)
{
int k;
SPELL_IDX thrown_spell = 0;
PERCENTAGE failrate;
byte spell[96], num = 0;
BIT_FLAGS f4, f5, f6;
- monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
GAME_TEXT m_name[MAX_NLEN];
#ifndef JP
bool do_spell = DO_SPELL_NONE;
int dam = 0;
- POSITION x = p_ptr->x;
- POSITION y = p_ptr->y;
+ POSITION x = target_ptr->x;
+ POSITION y = target_ptr->y;
/* Target location for lite breath */
POSITION x_br_lite = 0;
POSITION y_br_lite = 0;
/* Extract the "see-able-ness" */
- bool seen = (!p_ptr->blind && m_ptr->ml);
- bool maneable = player_has_los_bold(m_ptr->fy, m_ptr->fx);
+ bool seen = (!target_ptr->blind && m_ptr->ml);
+ bool maneable = player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx);
/* Check "projectable" */
bool direct;
- bool in_no_magic_dungeon = (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && current_floor_ptr->dun_level
- && (!p_ptr->inside_quest || is_fixed_quest_idx(p_ptr->inside_quest));
+ bool in_no_magic_dungeon = (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && target_ptr->current_floor_ptr->dun_level
+ && (!target_ptr->current_floor_ptr->inside_quest || is_fixed_quest_idx(target_ptr->current_floor_ptr->inside_quest));
bool can_use_lite_area = FALSE;
y_br_lite = y;
x_br_lite = x;
- if (los(m_ptr->fy, m_ptr->fx, y_br_lite, x_br_lite))
+ if (los(target_ptr->current_floor_ptr, m_ptr->fy, m_ptr->fx, y_br_lite, x_br_lite))
{
- feature_type *f_ptr = &f_info[current_floor_ptr->grid_array[y_br_lite][x_br_lite].feat];
+ feature_type *f_ptr = &f_info[target_ptr->current_floor_ptr->grid_array[y_br_lite][x_br_lite].feat];
if (!have_flag(f_ptr->flags, FF_LOS))
{
}
/* Check path */
- if (projectable(m_ptr->fy, m_ptr->fx, y, x))
+ if (projectable(target_ptr->current_floor_ptr, m_ptr->fy, m_ptr->fx, y, x))
{
- feature_type *f_ptr = &f_info[current_floor_ptr->grid_array[y][x].feat];
+ feature_type *f_ptr = &f_info[target_ptr->current_floor_ptr->grid_array[y][x].feat];
if (!have_flag(f_ptr->flags, FF_PROJECT))
{
if ((f4 & RF4_BR_DISI) && (m_ptr->cdis < MAX_RANGE/2) &&
in_disintegration_range(m_ptr->fy, m_ptr->fx, y, x) &&
- (one_in_(10) || (projectable(y, x, m_ptr->fy, m_ptr->fx) && one_in_(2))))
+ (one_in_(10) || (projectable(target_ptr->current_floor_ptr, y, x, m_ptr->fy, m_ptr->fx) && one_in_(2))))
{
do_spell = DO_SPELL_BR_DISI;
success = TRUE;
}
else if ((f4 & RF4_BR_LITE) && (m_ptr->cdis < MAX_RANGE/2) &&
- los(m_ptr->fy, m_ptr->fx, y, x) && one_in_(5))
+ los(target_ptr->current_floor_ptr, m_ptr->fy, m_ptr->fx, y, x) && one_in_(5))
{
do_spell = DO_SPELL_BR_LITE;
success = TRUE;
{
POSITION by = y, bx = x;
get_project_point(m_ptr->fy, m_ptr->fx, &by, &bx, 0L);
- if ((distance(by, bx, y, x) <= 3) && los(by, bx, y, x) && one_in_(5))
+ if ((distance(by, bx, y, x) <= 3) && los(target_ptr->current_floor_ptr, by, bx, y, x) && one_in_(5))
{
do_spell = DO_SPELL_BA_LITE;
success = TRUE;
if (f6 & RF6_DARKNESS)
{
- if ((p_ptr->pclass == CLASS_NINJA) &&
+ if ((target_ptr->pclass == CLASS_NINJA) &&
!(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) &&
!(r_ptr->flags7 & RF7_DARK_MASK))
can_use_lite_area = TRUE;
if (!(r_ptr->flags2 & RF2_STUPID))
{
- if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) f6 &= ~(RF6_DARKNESS);
- else if ((p_ptr->pclass == CLASS_NINJA) && !can_use_lite_area) f6 &= ~(RF6_DARKNESS);
+ if (d_info[target_ptr->dungeon_idx].flags1 & DF1_DARKNESS) f6 &= ~(RF6_DARKNESS);
+ else if ((target_ptr->pclass == CLASS_NINJA) && !can_use_lite_area) f6 &= ~(RF6_DARKNESS);
}
}
/* Remove the "ineffective" spells */
remove_bad_spells(m_idx, &f4, &f5, &f6);
- if (p_ptr->inside_arena || p_ptr->inside_battle)
+ if (target_ptr->current_floor_ptr->inside_arena || target_ptr->phase_out)
{
f4 &= ~(RF4_SUMMON_MASK);
f5 &= ~(RF5_SUMMON_MASK);
if (!(r_ptr->flags2 & RF2_STUPID))
{
- if (!p_ptr->csp) f5 &= ~(RF5_DRAIN_MANA);
+ if (!target_ptr->csp) f5 &= ~(RF5_DRAIN_MANA);
/* Check for a clean bolt shot */
if (((f4 & RF4_BOLT_MASK) ||
(f5 & RF5_BOLT_MASK) ||
(f6 & RF6_BOLT_MASK)) &&
- !clean_shot(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x, FALSE))
+ !clean_shot(m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x, FALSE))
{
/* Remove spells that will only hurt friends */
f4 &= ~(RF4_BOLT_MASK);
if (!num) return (FALSE);
/* Stop if player is dead or gone */
- if (!p_ptr->playing || p_ptr->is_dead) return (FALSE);
+ if (!target_ptr->playing || target_ptr->is_dead) return (FALSE);
/* Stop if player is leaving */
- if (p_ptr->leaving) return (FALSE);
+ if (target_ptr->leaving) return (FALSE);
/* Get the monster name (or "it") */
monster_desc(m_name, m_ptr, 0x00);
break;
default:
- return FALSE; /* Paranoia */
+ return FALSE;
}
/* Abort if no spell was chosen */
if (!spell_is_inate(thrown_spell)
&& (in_no_magic_dungeon || (MON_STUNNED(m_ptr) && one_in_(2)) || (randint0(100) < failrate)))
{
- disturb(TRUE, TRUE);
+ disturb(target_ptr, TRUE, TRUE);
msg_format(_("%^sは呪文を唱えようとしたが失敗した。", "%^s tries to cast a spell, but fails."), m_name);
return (TRUE);
}
/* Projectable? */
- direct = player_bold(y, x);
+ direct = player_bold(target_ptr, y, x);
can_remember = is_original_ap_and_seen(m_ptr);
}
/* Cast the spell. */
- dam = monspell_to_player(thrown_spell, y, x, m_idx);
+ dam = monspell_to_player(thrown_spell, target_ptr, y, x, m_idx);
if (dam < 0) return FALSE;
- if ((p_ptr->action == ACTION_LEARN) && thrown_spell > 175)
+ if ((target_ptr->action == ACTION_LEARN) && thrown_spell > 175)
{
learn_spell(thrown_spell - 96);
}
- if (seen && maneable && !current_world_ptr->timewalk_m_idx && (p_ptr->pclass == CLASS_IMITATOR))
+ if (seen && maneable && !current_world_ptr->timewalk_m_idx && (target_ptr->pclass == CLASS_IMITATOR))
{
if (thrown_spell != 167) /* Not RF6_SPECIAL */
{
- if (p_ptr->mane_num == MAX_MANE)
+ if (target_ptr->mane_num == MAX_MANE)
{
int i;
- p_ptr->mane_num--;
- for (i = 0;i < p_ptr->mane_num;i++)
+ target_ptr->mane_num--;
+ for (i = 0;i < target_ptr->mane_num;i++)
{
- p_ptr->mane_spell[i] = p_ptr->mane_spell[i+1];
- p_ptr->mane_dam[i] = p_ptr->mane_dam[i+1];
+ target_ptr->mane_spell[i] = target_ptr->mane_spell[i+1];
+ target_ptr->mane_dam[i] = target_ptr->mane_dam[i+1];
}
}
- p_ptr->mane_spell[p_ptr->mane_num] = thrown_spell - 96;
- p_ptr->mane_dam[p_ptr->mane_num] = dam;
- p_ptr->mane_num++;
- new_mane = TRUE;
+ target_ptr->mane_spell[target_ptr->mane_num] = thrown_spell - 96;
+ target_ptr->mane_dam[target_ptr->mane_num] = dam;
+ target_ptr->mane_num++;
+ target_ptr->new_mane = TRUE;
- p_ptr->redraw |= (PR_IMITATION);
+ target_ptr->redraw |= (PR_IMITATION);
}
}
/* Always take note of monsters that kill you */
- if (p_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !p_ptr->inside_arena)
+ if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !target_ptr->current_floor_ptr->inside_arena)
{
r_ptr->r_deaths++; /* Ignore appearance difference */
}