static void _excavation_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Excavation");
        break;
    case SPELL_DESC:
        var_set_string(res, "You break walls on your quest for treasure!  This takes a bit more time, though.");
        break;
    case SPELL_ENERGY:
        {
            int n = 200;

            if (equip_find_object(TV_DIGGING, SV_ANY))
                n -= 120 * p_ptr->lev / 50;
            else
                n -= 80 * p_ptr->lev / 50;

            var_set_int(res, n);
        }
        break;
    case SPELL_CAST:
        {
            int dir = 5;
            bool b = FALSE;

            if ( get_rep_dir2(&dir)
              && dir != 5 )
            {
                int x, y;
                y = py + ddy[dir];
                x = px + ddx[dir];

                if (!in_bounds(y, x))
                {
                    msg_print("You may excavate no further.");
                }
                else if ( cave_have_flag_bold(y, x, FF_WALL)
                       || cave_have_flag_bold(y, x, FF_TREE)
                       || cave_have_flag_bold(y, x, FF_CAN_DIG) )
                {
                    msg_print("You dig your way to treasure!");
                    cave_alter_feat(y, x, FF_TUNNEL);
                    move_player_effect(y, x, 0);
                    b = TRUE;
                }
                else
                {
                    msg_print("There is nothing to excavate.");
                }
            }
            var_set_bool(res, b);
        }
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
static void _charge_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Charge");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attacks monster with your weapons normally, then move through counter side of the monster.");
        break;
    case SPELL_CAST:
    {
        int dir, x, y;
        var_set_bool(res, FALSE);
        if (p_ptr->riding)
        {
            msg_print("You cannot do it when riding.");
            return;
        }

        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

        y = py + ddy[dir];
        x = px + ddx[dir];

        if (!cave[y][x].m_idx)
        {
            msg_print("There is no monster there.");
            return;
        }

        py_attack(y, x, 0);

        if (player_can_enter(cave[y][x].feat, 0) && !is_trap(cave[y][x].feat))
        {
            y += ddy[dir];
            x += ddx[dir];
            if (player_can_enter(cave[y][x].feat, 0) && !is_trap(cave[y][x].feat) && !cave[y][x].m_idx)
            {
                msg_print(NULL);
                move_player_effect(y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
            }
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Example #3
0
_rush_result _rush_attack(int rng, _rush_type type)
{
    _rush_result result = _rush_cancelled;
    int tx, ty;
    int tm_idx = 0;
    u16b path_g[32];
    int path_n, i;
    bool moved = FALSE;
    int flg = 0;
    int dis = 0;

    if (type == _rush_normal)
        flg = PROJECT_STOP | PROJECT_KILL;
    else if (type == _rush_acrobatic)
        flg = PROJECT_THRU | PROJECT_KILL;
    else
        flg = PROJECT_DISI | PROJECT_THRU;

    if (!p_ptr->duelist_target_idx)
    {
        msg_print("You need to select a foe first (Mark Target).");
        return result;
    }

    tm_idx = p_ptr->duelist_target_idx;
    tx = m_list[tm_idx].fx;
    ty = m_list[tm_idx].fy;

    dis = distance(ty, tx, py, px);

    /* Foe must be visible.  For all charges except the phase charge, the
       foe must also be in your line of sight */
    if (!m_list[p_ptr->duelist_target_idx].ml ||
        (type != _rush_phase && !los(ty, tx, py, px)))
    {
        msg_format("%^s is not in your line of sight.", duelist_current_challenge());
        return result;
    }

    if (dis > rng)
    {
        msg_format("Your foe is out of range (%d vs %d).", dis, rng);
        if (!get_check("Charge anyway? ")) return result;
    }

    project_length = rng;
    path_n = project_path(path_g, project_length, py, px, ty, tx, flg);
    project_length = 0;

    if (!path_n) return result;

    result = _rush_failed;

    /* Use ty and tx as to-move point */
    ty = py;
    tx = px;

    /* Scrolling the cave would invalidate our path! */
    if (!dun_level && !p_ptr->wild_mode && !p_ptr->inside_arena && !p_ptr->inside_battle)
        wilderness_scroll_lock = TRUE;

    /* Project along the path */
    for (i = 0; i < path_n; i++)
    {
        monster_type *m_ptr;
        cave_type *c_ptr;
        bool can_enter = FALSE;
        bool old_pass_wall = p_ptr->pass_wall;

        int ny = GRID_Y(path_g[i]);
        int nx = GRID_X(path_g[i]);
        c_ptr = &cave[ny][nx];

        switch (type)
        {
        case _rush_normal:
            can_enter = cave_empty_bold(ny, nx) && player_can_enter(c_ptr->feat, 0);
            break;

        case _rush_acrobatic:
            can_enter = !c_ptr->m_idx && player_can_enter(c_ptr->feat, 0);
            break;
        
        case _rush_phase:
            p_ptr->pass_wall = TRUE;
            can_enter = !c_ptr->m_idx && player_can_enter(c_ptr->feat, 0);
            p_ptr->pass_wall = old_pass_wall;
            break;
        }

        if (can_enter)
        {
            ty = ny;
            tx = nx;
            continue;
        }

        if (!c_ptr->m_idx)
        {
            msg_print("Failed!");
            break;
        }

        /* Move player before updating the monster */
        if (!player_bold(ty, tx)) move_player_effect(ty, tx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
        moved = TRUE;

        /* Update the monster */
        update_mon(c_ptr->m_idx, TRUE);

        /* Found a monster */
        m_ptr = &m_list[c_ptr->m_idx];

        /* But it is not the monster we seek! */
        if (tm_idx != c_ptr->m_idx)
        {
            /* Acrobatic Charge attempts to displace monsters on route */
            if (type == _rush_acrobatic)
            {
                /* Swap position of player and monster */
                set_monster_csleep(c_ptr->m_idx, 0);
                move_player_effect(ny, nx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
                ty = ny;
                tx = nx;
                continue;
            }
            /* Normal Charge just attacks first monster on route */
            else
                msg_format("There is %s in the way!", m_ptr->ml ? (tm_idx ? "another monster" : "a monster") : "someone");
        }

        /* Attack the monster */
        if (tm_idx == p_ptr->duelist_target_idx) result = _rush_succeeded;
        py_attack(ny, nx, 0);
        break;
    }

    if (!moved && !player_bold(ty, tx)) move_player_effect(ty, tx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
    if (!dun_level && !p_ptr->wild_mode && !p_ptr->inside_arena && !p_ptr->inside_battle)
    {
        wilderness_scroll_lock = FALSE;
        wilderness_move_player(px, py);
    }
    return result;
}