Beispiel #1
0
static void _isolation_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Isolation");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attempts to teleport away all monsters in Line of Sight other than your marked foe.");
        break;
    case SPELL_CAST:
        if (!p_ptr->duelist_target_idx)
        {
            msg_print("You need to mark your target first.");
            var_set_bool(res, FALSE);
        }
        else
        {
            project_hack(GF_ISOLATION, p_ptr->lev * 4);
            var_set_bool(res, TRUE);
        }
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
Beispiel #2
0
static void _pharaohs_curse_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Pharaoh's Curse");
        break;
    case SPELL_DESC:
        var_set_string(res, "Curses all nearby monsters, doing great damage and various effects.");
        break;
    case SPELL_CAST:
        {
            int power = spell_power(p_ptr->lev * 4);
            project_hack(GF_PHARAOHS_CURSE, p_ptr->lev + randint1(p_ptr->lev));
            if (p_ptr->lev >= 46)
                confuse_monsters(power);
            if (p_ptr->lev >= 47)
                slow_monsters(power);
            if (p_ptr->lev >= 48)
                turn_monsters(power);
            if (p_ptr->lev >= 49)
                stun_monsters(power);
            if (one_in_(5))
            {
                int mode = 0;
                if (one_in_(2))
                    mode = PM_FORCE_PET;
                if (summon_named_creature(0, py, px, MON_GREATER_MUMMY, mode))
                {
                    msg_print("You have disturbed the rest of an ancient pharaoh!");
                }
            }
            take_hit(DAMAGE_USELIFE, p_ptr->lev + randint1(p_ptr->lev), "the Pharaoh's Curse", -1);
            var_set_bool(res, TRUE);
        }
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
/**********************************************************************
 * 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 "";
}