Пример #1
0
/*
 * Determine if a trap makes a reasonable target
 */
static bool target_able_trap(int y, int x)
{
	/* Must be on line of fire */
	if (!player_can_fire_bold(y, x)) return (FALSE);

	/* Only player traps allowed. Ignore monster traps and glyphs */
	if (!cave_player_trap_bold(y, x)) return (FALSE);

	/* Ignore hidden traps */
	if (x_list[cave_x_idx[y][x]].x_flags & (EF1_HIDDEN)) return (FALSE);

	/* Known player traps are okay */
	return (TRUE);
}
Пример #2
0
/*
 * Apply a "project()" directly to all monsters in view of a certain spot.
 *
 * Note that affected monsters are NOT auto-tracked by this usage.
 *
 * We are able to check LOS from either the character (in which case we
 * use line of fire for speed and accuracy), or from any given grid.
 *
 * To avoid misbehavior when monster deaths have side-effects,
 * this is done in two passes. -- JDL
 */
bool project_los(int y0, int x0, int dam, int typ)
{
    int i, d, x, y;

    u32b flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;

    bool obvious = FALSE;

    int who;

    /* Determine whether we are using LOF or LOS */
    bool line_of_fire = FALSE;

    if ((y0 == p_ptr->py) && (x0 == p_ptr->px))
    {
        line_of_fire = TRUE;
        who = SOURCE_PLAYER;
    }
    else if (cave_monster_trap_bold(y0, x0)) who = SOURCE_TRAP;
    else if (cave_player_trap_bold(y0, x0))  who = SOURCE_EFFECT;
    else who = SOURCE_OTHER;

    /* Mark monsters in LOS */
    for (i = 1; i < mon_max; i++)
    {
        monster_type *m_ptr = &mon_list[i];

        /* Paranoia -- Skip dead monsters */
        if (!m_ptr->r_idx) continue;

        /* Location */
        y = m_ptr->fy;
        x = m_ptr->fx;

        /* Apply character-centered test */
        if (line_of_fire)
        {
            /* Require line of fire */
            if (!player_can_fire_bold(y, x)) continue;
        }

        /* Apply generic grid test */
        else
        {
            /* Get distance between source and monster */
            d = distance(y0, x0, y, x);

            /* LOS extends only to max sight range */
            if (d > MAX_RANGE) continue;

            /* Check LOS if not at grid or adjacent */
            if (d > 1)
            {
                /* Ignore if not in LOS */
                if (!los(y0, x0, y, x)) continue;
            }
        }

        /* Mark the monster */
        m_ptr->mflag |= (MFLAG_TEMP);
    }

    /* Affect all (nearby) monsters */
    for (i = 1; i < mon_max; i++)
    {
        monster_type *m_ptr = &mon_list[i];

        /* Skip unmarked monsters */
        if (!(m_ptr->mflag & (MFLAG_TEMP))) continue;

        /* Remove mark */
        m_ptr->mflag &= ~(MFLAG_TEMP);

        /* Jump directly to the monster */
        if (project_m(who, m_ptr->fy, m_ptr->fx, dam, typ, flg))
        {
            obvious = TRUE;
        }
    }

    /* Result */
    return (obvious);
}