void _smash_trap_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Smash Trap");
        break;
    case SPELL_DESC:
        var_set_string(res, "Sets off a trap, then destroy that trap.");
        break;
    case SPELL_CAST:
    {
        int dir;
        var_set_bool(res, FALSE);
        
        if (!get_rep_dir2(&dir)) return;
        move_player(dir, easy_disarm, TRUE);
        
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 2
0
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);
                    teleport_player_to(y, x, TELEPORT_NONMAGICAL); /*??*/
                    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;
    }
}
Ejemplo n.º 4
0
bool do_blow(int type)
{
    int x = 0, y = 0;
    int dir;
    int m_idx = 0;

    /* For ergonomics sake, use currently targeted monster. This allows
       a macro of \e*tmaa or similar to pick an adjacent foe, while
       \emaa*t won't work, since get_rep_dir2() won't allow a target. */
    if (use_old_target && target_okay())
    {
        y = target_row;
        x = target_col;
        m_idx = cave[y][x].m_idx;
        if (m_idx)
        {
            if (m_list[m_idx].cdis > 1)
                m_idx = 0;
            else
                dir = 5;
        }
    }

    if (!m_idx)
    {
        if (!get_rep_dir2(&dir)) return FALSE;
        if (dir == 5) return FALSE;

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

        if (!m_idx)
        {
            msg_print("There is no monster there.");
            return FALSE;
        }

    }

    if (m_idx)
        py_attack(y, x, type);

    return TRUE;
}
Ejemplo n.º 5
0
static void _smash_wall_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Smash");
        break;
    case SPELL_DESC:
        var_set_string(res, "Destroys adjacent targeted wall, door, tree, or trap.");
        break;
    case SPELL_CAST:
    {
        int y, x, dir;
        
        var_set_bool(res, FALSE);
        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

        y = py + ddy[dir];
        x = px + ddx[dir];
        
        if (!in_bounds(y, x)) return;

        if (cave_have_flag_bold(y, x, FF_HURT_ROCK))
        {
            cave_alter_feat(y, x, FF_HURT_ROCK);
            p_ptr->update |= PU_FLOW;
        }
        else if (cave_have_flag_bold(y, x, FF_TREE))
        {
            cave_set_feat(y, x, one_in_(3) ? feat_brake : feat_grass);
        }
        else
        {
            int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
            project(0, 0, y, x, 0, GF_KILL_DOOR, flg, -1);
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 6
0
void awesome_blow_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Awesome Blow");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack a monster with a single melee blow. If blow hits, does normal melee damage and propels the monster backwards.");
        break;
    case SPELL_CAST:
    {
        int y, x, dir;
        var_set_bool(res, FALSE);

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

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

        if (cave[y][x].m_idx)
        {
            py_attack(y, x, MELEE_AWESOME_BLOW);
        }
        else
        {
            msg_print("There is no monster.");
            return;
        }

        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 7
0
static void _stone_smash_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Stone Smash");
        break;
    case SPELL_DESC:
        var_set_string(res, "Destroys adjacent targeted wall.");
        break;
    case SPELL_CAST:
    {
        int y, x, dir;
        
        var_set_bool(res, FALSE);
        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

        y = py + ddy[dir];
        x = px + ddx[dir];
        
        if (!in_bounds(y, x)) return;

        if (cave_have_flag_bold(y, x, FF_HURT_ROCK))
        {
            cave_alter_feat(y, x, FF_HURT_ROCK);
            p_ptr->update |= PU_FLOW;
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 8
0
/****************************************************************
 * Spells
 ****************************************************************/
static void _kiss_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Kiss");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attempt to charm an adjacent monster.");
        break;
    case SPELL_COST_EXTRA:
        var_set_int(res, p_ptr->lev * 2);
        break;
    case SPELL_CAST:
    {
        int y, x, dir = 0, m_idx;
        var_set_bool(res, FALSE);
        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

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

        m_idx = cave[y][x].m_idx;
        if (m_idx)
        {
            monster_type *m_ptr = &m_list[m_idx];
            monster_race *r_ptr = &r_info[m_ptr->r_idx];
            char desc[MAX_NLEN];
            monster_desc(desc, m_ptr, 0);
            if ((r_ptr->flags1 & RF1_UNIQUE) || mon_save_p(m_ptr->r_idx, A_CHR))
            {
                set_monster_csleep(m_idx, 0);
                if (is_hostile(m_ptr))
                {
                    switch (randint1(10))
                    {
                    case 1:
                        msg_format("%^s says 'Impudent Strumpet!'", desc);
                        break;
                    case 2:
                        msg_format("%^s says 'Ewwww! Gross!!'", desc);
                        break;
                    case 3:
                        msg_format("%^s says 'You ain't my type!'", desc);
                        break;
                    default:
                        msg_format("%^s resists your charms.", desc);
                    }

                    if (allow_ticked_off(r_ptr))
                    {
                        m_ptr->anger_ct++;
                    }

                }
                else
                    msg_format("%^s ignores you.", desc);
            }
            else
            {
                if (is_pet(m_ptr))
                    msg_format("%^s slobbers on you affectionately.", desc);
                else if (is_friendly(m_ptr))
                {
                    set_pet(m_ptr);
                    msg_format("%^s is charmed!", desc);
                }
                else
                {
                    set_friendly(m_ptr);
                    msg_format("%^s suddenly becomes friendly.", desc);
                }
            }
            var_set_bool(res, TRUE);
        }
        else
        {
            msg_print("There is no monster.");
        }
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 9
0
void banish_evil_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Banish Evil");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attempts to remove a single evil opponent.");
        break;
    case SPELL_GAIN_MUT:
        msg_print("You feel a holy wrath fill you.");
        break;
    case SPELL_LOSE_MUT:
        msg_print("You no longer feel a holy wrath.");
        break;
    case SPELL_MUT_DESC:
        var_set_string(res, "You can send evil creatures directly to Hell.");
        break;
    case SPELL_CAST:
    {
        int dir = 0;
        int x, y;
        cave_type *c_ptr;
        monster_type *m_ptr;
        monster_race *r_ptr;

        if (!get_rep_dir2(&dir)) 
        {
            var_set_bool(res, FALSE);
            break;
        }

        var_set_bool(res, TRUE);

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

        if (!c_ptr->m_idx)
        {
            msg_print("You sense no evil there!");
            break;
        }

        m_ptr = &m_list[c_ptr->m_idx];
        r_ptr = &r_info[m_ptr->r_idx];

        if ((r_ptr->flags3 & RF3_EVIL) &&
            !(r_ptr->flags1 & RF1_QUESTOR) &&
            !(r_ptr->flags1 & RF1_UNIQUE) &&
            !p_ptr->inside_arena && !p_ptr->inside_quest &&
            (r_ptr->level < randint1(p_ptr->lev+50)) &&
            !(m_ptr->mflag2 & MFLAG2_NOGENO))
        {
            /* Delete the monster, rather than killing it. */
            delete_monster_idx(c_ptr->m_idx);
            msg_print("The evil creature vanishes in a puff of sulfurous smoke!");
        }
        else
        {
            msg_print("Your invocation is ineffectual!");
            if (one_in_(13)) m_ptr->mflag2 |= MFLAG2_NOGENO;
        }
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Ejemplo n.º 10
0
static void _double_crack_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Double Crack");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack a monster normally with your whip, and then randomly attack an adjacent monster.");
        break;
    case SPELL_CAST:
        if (_whip_check())
        {
            int dir = 5;
            bool b = FALSE;

            if ( get_rep_dir2(&dir)
              && dir != 5 )
            {
                int x, y;
                int num = 1;
                int attempts = 0;

                /* First we attack where the player selected */
                y = py + ddy[dir];
                x = px + ddx[dir];
                if (in_bounds(y, x) && cave[y][x].m_idx)
                    py_attack(y, x, 0);
                else
                    msg_print("Your whip cracks in empty air.");

                /* Now the whip cracks randomly!
                   Note that we favor fighting in hallways, or
                   with ones back up against the wall. */
                while (num > 0)
                {
                    if (attempts > 3 * num)
                    {
                        while (num > 0)
                        {
                            msg_print("Your whip cracks in empty air.");
                            num--;
                        }
                        break;
                    }

                    /* random direction, but we don't penalize for choosing the player (5) */
                    dir = randint0(9);
                    if (dir == 5) continue;
                    
                    attempts++;
                    y = py + ddy[dir];
                    x = px + ddx[dir];

                    if ( !in_bounds(y, x) 
                      || 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) )
                    {
                        continue;
                    }

                    
                    if (cave[y][x].m_idx)
                        py_attack(y, x, 0);
                    else
                        msg_print("Your whip cracks in empty air.");

                    num--;
                }

                b = TRUE;
            }
            var_set_bool(res, b);
        }
        else
        {
            msg_print("Whip techniques can only be used if you are fighting with whips.");
            var_set_bool(res, FALSE);
        }
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
static bool _necro_do_touch(int type, int dice, int sides, int base)
{
    int x, y;
    int dir = 0;
    int m_idx = 0;

    if (!_necro_check_touch()) return FALSE;

    /* For ergonomics sake, use currently targeted monster. This allows
       a macro of \e*tmaa or similar to pick an adjacent foe, while
       \emaa*t won't work, since get_rep_dir2() won't allow a target. */
    if (use_old_target && target_okay())
    {
        y = target_row;
        x = target_col;
        m_idx = cave[y][x].m_idx;
        if (m_idx)
        {
            if (m_list[m_idx].cdis > 1)
                m_idx = 0;
            else
                dir = 5; /* Hack so that fire_ball() works correctly */
        }
    }

    if (!m_idx)
    {
        if (!get_rep_dir2(&dir)) return FALSE;
        if (dir == 5) return FALSE;

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

        if (!m_idx)
        {
            msg_print("There is no monster there.");
            return FALSE;
        }

    }

    if (m_idx)
    {
        int dam;
        monster_type *m_ptr = &m_list[m_idx];

        if (!is_hostile(m_ptr) &&
            !(p_ptr->stun || p_ptr->confused || p_ptr->image ||
            IS_SHERO() || !m_ptr->ml))
        {
            if (!get_check("Really hit it? "))
                return FALSE;
        }

        dam = _necro_damroll(dice, sides, base);
        on_p_hit_m(m_idx);
        touch_zap_player(m_idx);
        if (fire_ball(type, dir, dam, 0))
        {
            if (type == GF_OLD_DRAIN)
                hp_player(dam);
        }
    }
    return TRUE;
}
/**********************************************************************
 * Spells: Note, we are still using the old "Book Spell System"
 **********************************************************************/
cptr do_necromancy_spell(int spell, int mode)
{
    bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
    bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
    bool info = (mode == SPELL_INFO) ? TRUE : FALSE;
    bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
    bool fail = (mode == SPELL_FAIL) ? TRUE : FALSE;

    int plev = p_ptr->lev;

    switch (spell)
    {
    /* Stench of Death */
    case 0:
        if (name) return "Cold Touch";
        if (desc) return "Damage an adjacent monster with a chilling touch.";
        if (info) return _necro_info_damage(2, 6, plev + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_COLD, 2, 6, plev + p_ptr->to_d_spell)) return NULL;
        break;

    case 1:
        if (name) return "Summon Rat";
        if (desc) return "Summons a rat to feast on the dead!";
        if (cast || fail) _necro_do_summon(SUMMON_RAT, 1, fail);
        break;

    case 2:
        if (name) return "Detect Life";
        if (desc) return "Detects all living monsters in your vicinity.";
        if (info) return info_radius(DETECT_RAD_DEFAULT);
        if (cast) detect_monsters_living(DETECT_RAD_DEFAULT, "You sense the presence of life around you.");
        break;

    case 3:
        if (name) return "Detect Unlife";
        if (desc) return "Detects all nonliving monsters in your vicinity.";
        if (info) return info_radius(DETECT_RAD_DEFAULT);
        if (cast) detect_monsters_nonliving(DETECT_RAD_DEFAULT);
        break;

    case 4:
        if (name) return "Poison Touch";
        if (desc) return "Damage an adjacent monster with a venomous touch.";
        if (info) return _necro_info_damage(4, 6, plev + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_POIS, 4, 6, plev + p_ptr->to_d_spell)) return NULL;
        break;

    case 5:
        if (name) return "Summon Bats";
        if (desc) return "Summons bats to feast on the living!";
        if (cast || fail) _necro_do_summon(SUMMON_BAT, 1 + randint1(2), fail);
        break;

    case 6:
        if (name) return "Eldritch Howl";
        if (desc) return "Emit a terrifying howl.";
        if (cast) project_hack(GF_ELDRITCH_HOWL, spell_power(plev * 3));
        break;

    case 7:
        if (name) return "Black Touch";
        if (desc) return "Damage an adjacent monster with a dark touch.";
        if (info) return _necro_info_damage(6, 6, plev * 3 / 2 + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_DARK, 6, 6, plev * 3 / 2 + p_ptr->to_d_spell)) return NULL;
        break;

    /* Sepulchral Ways */
    case 8:
        if (name) return "Summon Wolves";
        if (desc) return "Summons wolves to feast on the living!";
        if (cast || fail) _necro_do_summon(SUMMON_WOLF, 1 + randint1(2), fail);
        break;

    case 9:
        if (name) return "Black Cloak";
        if (desc) return "You become shrouded in darkness.";
        if (cast) 
        {
            set_tim_dark_stalker(spell_power(randint1(plev) + plev), FALSE);
        }
        break;

    case 10:
        if (name) return "Undead Sight";
        if (desc) return "Learn about your nearby surroundings by communing with the dead.";
        if (info) return info_radius(DETECT_RAD_MAP);
        if (cast)
        {
            map_area(DETECT_RAD_MAP);
            detect_traps(DETECT_RAD_DEFAULT, TRUE);
            detect_doors(DETECT_RAD_DEFAULT);
            detect_stairs(DETECT_RAD_DEFAULT);
        }
        break;

    case 11:
        if (name) return "Undead Lore";
        if (desc) return "Ask the dead to examine an object for you.";
        if (cast) ident_spell(NULL);
        break;

    case 12:
        if (name) return "Repelling Touch";
        if (desc) return "Conjure a foul wind to blow an adjacent monster away.";
    
        if (cast)
        {
            int y, x, dir;

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

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

            if (!cave[y][x].m_idx)
            {
                msg_print("There is no monster.");
                return NULL;
            }
            else
            {
                int i;
                int ty = y, tx = x;
                int oy = y, ox = x;
                int m_idx = cave[y][x].m_idx;
                monster_type *m_ptr = &m_list[m_idx];
                char m_name[80];
    
                monster_desc(m_name, m_ptr, 0);
                touch_zap_player(cave[y][x].m_idx);    
    
                for (i = 0; i < 10; i++)
                {
                    y += ddy[dir];
                    x += ddx[dir];
                    if (cave_empty_bold(y, x))
                    {
                        ty = y;
                        tx = x;
                    }
                    else break;
                }
                if ((ty != oy) || (tx != ox))
                {
                    msg_format("A foul wind blows %s away!", m_name);
                    cave[oy][ox].m_idx = 0;
                    cave[ty][tx].m_idx = m_idx;
                    m_ptr->fy = ty;
                    m_ptr->fx = tx;
    
                    update_mon(m_idx, TRUE);
                    lite_spot(oy, ox);
                    lite_spot(ty, tx);
    
                    if (r_info[m_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
                        p_ptr->update |= (PU_MON_LITE);
                }
            }
        }
        break;

    case 13:
        if (name) return "Vampiric Touch";
        if (desc) return "Steal life from an adjacent foe.";
        if (info) return _necro_info_damage(0, 0, plev * 4 + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_OLD_DRAIN, 0, 0, plev * 4 + p_ptr->to_d_spell)) return NULL;
        break;

    case 14:
        if (name) return "Dread of Night";
        if (desc) return "Summons Dread to do your bidding. Beware of failure!";
        if (cast || fail) _necro_do_summon(SUMMON_DREAD, 1 + randint0(3), fail);
        break;

    case 15:
        if (name) return "Entomb";
        if (desc) return "Entombs chosen foe.";
        if (cast)
        {
            int dir; 
            if (!get_fire_dir(&dir)) return NULL;
            fire_ball_hide(GF_ENTOMB, dir, plev, 0);
            p_ptr->update |= (PU_FLOW);
            p_ptr->redraw |= (PR_MAP);
        }
        break;

    /* Return of the Dead */
    case 16:
        if (name) return "Summon Zombies";
        if (desc) return "The dead are back and hungry for brains!";
        if (cast || fail) _necro_do_summon(SUMMON_ZOMBIE, 2 + randint1(3), fail);
        break;

    case 17:
        if (name) return "Summon Skeletons";
        if (desc) return "Summon skeletal assistance.";
        if (cast || fail) _necro_do_summon(SUMMON_SKELETON, 1 + randint0(3), fail);
        break;

    case 18:
        if (name) return "Summon Ghosts";
        if (desc) return "Recall the spirits of slain warriors for unholy servitude.";
        if (cast || fail) _necro_do_summon(SUMMON_GHOST, 1 + randint0(3), fail);
        break;

    case 19:
        if (name) return "Summon Vampires";
        if (desc) return "Its time to command the commanders!";
        if (cast || fail) _necro_do_summon(SUMMON_VAMPIRE, 1 + randint0(2), fail);
        break;

    case 20:
        if (name) return "Summon Wraiths";
        if (desc) return "Summon wights and wraiths to do your bidding.";
        if (cast || fail) _necro_do_summon(SUMMON_WIGHT, 1 + randint0(2), fail);
        break;

    case 21:
        if (name) return "Summon Liches";
        if (desc) return "Call forth former necromancers.";
        if (cast || fail) _necro_do_summon(SUMMON_LICH, 1 + randint0(2), fail);
        break;

    case 22:
        if (name) return "Unholy Word";
        if (desc) return "Utter an unspeakable word. The morale of your visible evil pets is temporarily boosted and they will serve you with renewed enthusiasm.";
        if (cast) project_hack(GF_UNHOLY_WORD, plev * 6);
        break;

    case 23:
        if (name) return "Lost Cause";
        if (desc) return "Make a last ditch Kamikaze effort for victory!";
        if (cast) discharge_minion();
        break;

    /* Necromatic Tome */
    case 24:
        if (name) return "Draining Touch";
        if (desc) return "Steal mana from an adjacent foe.";
        if (info) return _necro_info_damage(5, 5, plev/2 + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_DRAINING_TOUCH, 5, 5, plev/2 + p_ptr->to_d_spell)) return NULL;
        break;

    case 25:
        if (name) return "Unhallow Ground";
        if (desc) return "Makes the current square unholy.";
        if (cast) warding_glyph(); /* TODO: Add new cave feature! */
        break;

    case 26:
    {
        int base = spell_power(20);
        if (name) return "Shield of the Dead";
        if (desc) return "Grants temporary protection";
        if (info) return info_duration(base, base);
        if (cast)
        {
            set_tim_res_nether(randint1(base) + base, FALSE);
            set_oppose_pois(randint1(base) + base, FALSE);
            set_oppose_cold(randint1(base) + base, FALSE);
            set_shield(randint1(base) + base, FALSE);
        }
        break;
    }
    case 27:
        if (name) return "Rending Touch";
        if (desc) return "Damage an adjacent monster with a disintegrating touch.";
        if (info) return _necro_info_damage(20, 20, plev + p_ptr->to_d_spell);
        if (cast && !_necro_do_touch(GF_DISINTEGRATE, 20, 20, plev + p_ptr->to_d_spell)) return NULL;
        break;

    case 28:
        if (name) return "Repose of the Dead";
        if (desc) return "Sleep the sleep of the dead for a few rounds, during which time nothing can awaken you, except perhaps death. When (if?) you wake up, you will be thoroughly refreshed!";
        if (cast)
        {
            if (!get_check("You will enter a deep slumber. Are you sure?")) return NULL;
            repose_of_the_dead = TRUE;
            set_paralyzed(4 + randint1(4), FALSE);
        }
        break;

    case 29:
        if (name) return "Sepulchral Wind";
        if (desc) return "You call forth the wind of the dead. All nearby monsters are blown away!";
        {
            int power = spell_power(plev * 4);
            if (info) return info_power(power);
            if (cast) banish_monsters(power);
        }
        break;

    case 30:
        if (name) return "Deadly Touch";
        if (desc) return "Attempt to kill an adjacent monster.";
        if (cast && !_necro_do_touch(GF_DEATH_TOUCH, 0, 0, plev * 200)) return NULL;
        break;

    case 31:
        if (name) return "Necromancy";
        if (desc) return "Bridge the world of the living with the world of the dead!  Vast hordes of undead will come forth to serve the one true necromancer!";
        if (cast)
        {
            int i;
            int sp_sides = 20 + plev;
            int sp_base = plev;
            int power = spell_power(plev);

            power += randint1(power);

            for (i = 0; i < 18; i++)
            {
                int attempt = 10;
                int my, mx, what;

                while (attempt--)
                {
                    scatter(&my, &mx, py, px, 4, 0);

                    /* Require empty grids */
                    if (cave_empty_bold2(my, mx)) break;
                }
                if (attempt < 0) continue;
                switch (randint1(4))
                {
                case 1: what = SUMMON_LICH; break;
                case 2: what = SUMMON_WIGHT; break;
                case 3: what = SUMMON_VAMPIRE; break;
                case 4:
                default: what = SUMMON_GHOST; break;
                }
                summon_specific(-1, my, mx, power, what, (PM_ALLOW_GROUP | PM_FORCE_PET | PM_HASTE));
            }
            set_fast(randint1(sp_sides) + sp_base, FALSE);
        }
        break;

    }

    return "";
}
Ejemplo n.º 13
0
static void _bite_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Vampiric Bite");
        break;
    case SPELL_DESC:
        var_set_string(res, "As a vampire, you must feed on fresh blood in order to sustain your unlife!");
        break;
    case SPELL_INFO:
        var_set_string(res, info_damage(0, 0, _bite_amt()));
        break;
    case SPELL_CAST:
        var_set_bool(res, FALSE);
        if (d_info[dungeon_type].flags1 & DF1_NO_MELEE)
        {
            msg_print("Something prevents you from attacking.");
            return;
        }
        else
        {
            int x = 0, y = 0, amt, m_idx = 0;
            int dir = 0;

            if (use_old_target && target_okay())
            {
                y = target_row;
                x = target_col;
                m_idx = cave[y][x].m_idx;
                if (m_idx)
                {
                    if (m_list[m_idx].cdis > 1)
                        m_idx = 0;
                    else
                        dir = 5;
                }
            }

            if (!m_idx)
            {
                if (!get_rep_dir2(&dir)) return;
                if (dir == 5) return;
                y = py + ddy[dir];
                x = px + ddx[dir];
                m_idx = cave[y][x].m_idx;

                if (!m_idx)
                {
                    msg_print("There is no monster there.");
                    return;
                }
            }

            var_set_bool(res, TRUE);

            msg_print("You grin and bare your fangs...");
            amt = _bite_amt();

            vampiric_drain_hack = TRUE;
            if (project(0, 0, y, x, amt, GF_OLD_DRAIN, PROJECT_STOP | PROJECT_KILL | PROJECT_THRU, -1))
            {
                vampire_feed(amt);
            }
            else
                msg_print("Yechh. That tastes foul.");
            vampiric_drain_hack = FALSE;
        }
        break;
    case SPELL_COST_EXTRA:
        var_set_int(res, MIN(_bite_amt() / 10, 29));
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}