view xrogue/misc.c @ 188:135ec7f15ffe

srogue: remove remnants of deleted savefile checks. save_file() used fstat() and direct write() as part of the inode check which was deleted in f11eeafc. These operations no longer had any effect.
author John "Elwin" Edwards
date Mon, 03 Aug 2015 07:04:48 -0400
parents cadff8f047a1
children f54901b9c39b
line wrap: on
line source

/*
    misc.c - routines dealing specifically with miscellaneous magic
    
    XRogue: Expeditions into the Dungeons of Doom
    Copyright (C) 1991 Robert Pietkivitch
    All rights reserved.
    
    Based on "Advanced Rogue"
    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
    All rights reserved.

    See the file LICENSE.TXT for full copyright and licensing information.
*/

#include <stdlib.h>
#include <curses.h>
#include <ctype.h>
#include <string.h>
#include "rogue.h"

/*
 * changeclass:
 *      Change the player's class to the specified one.
 */

changeclass(newclass)
long *newclass;
{
    if (*newclass == player.t_ctype) {
        msg("You feel more skillful.");
        raise_level();
    }
    else {
        /*
         * reset his class and then use check_level to reset hit
         * points and the right level for his exp pts
         * drop exp pts by 10%
         */
        long save;

        msg("You are transformed into a %s! ", char_class[*newclass].name);

        /*
         * if he becomes a thief or an assassin give him studded leather armor
         */
        if ((*newclass == C_THIEF || *newclass == C_ASSASSIN) &&
            cur_armor != NULL && cur_armor->o_which != STUDDED_LEATHER)
                cur_armor->o_which = STUDDED_LEATHER;
        /*
         * if he becomes a monk he can't wear any armor
     * so give him a cloak of protection
         */
        if (*newclass == C_MONK && cur_armor != NULL) {
                cur_armor->o_ac = armors[cur_armor->o_which].a_class - 
                                  cur_armor->o_ac;
                cur_armor->o_type = MM;
                cur_armor->o_which = MM_PROTECT;
                cur_armor->o_flags &= ~(ISPROT | ISKNOW);
                cur_misc[WEAR_CLOAK] = cur_armor;
                cur_armor = NULL;
        }
    /*
     * otherwise give him plate armor
     */
        if ((*newclass != C_THIEF ||
         *newclass != C_ASSASSIN || *newclass != C_MONK) &&
         cur_armor != NULL && cur_armor->o_which != PLATE_ARMOR) 
                cur_armor->o_which = PLATE_ARMOR;

        /*
         * if he used to be a spell caster of some sort, kill the fuse
         */
        if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER)
                extinguish(spell_recovery);
        if (player.t_ctype == C_DRUID || player.t_ctype == C_MONK)
                extinguish(chant_recovery);
        if ((player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN) &&
             !cur_relic[HEIL_ANKH])
                extinguish(prayer_recovery);

        /*
         * if he becomes a spell caster of some kind, give him a fuse
         */
        if (*newclass == C_MAGICIAN || *newclass == C_RANGER)
                fuse(spell_recovery, (VOID *)NULL, SPELLTIME, AFTER);
        if (*newclass == C_DRUID || *newclass == C_MONK)
                fuse(chant_recovery, (VOID *)NULL, SPELLTIME, AFTER);
        if ((*newclass==C_CLERIC || *newclass==C_PALADIN) && !cur_misc[HEIL_ANKH])
                fuse(prayer_recovery, (VOID *)NULL, SPELLTIME, AFTER);
        /*
         * if he's changing from a fighter, ranger, or paladin then we
     * may have to change his sword since only these types can wield
     * the two-handed sword.
         */
        if ((player.t_ctype == C_FIGHTER ||
        player.t_ctype == C_RANGER   ||
            player.t_ctype == C_PALADIN) &&
        cur_weapon != NULL && cur_weapon->o_type == WEAPON &&
            (cur_weapon->o_which == BASWORD  ||
        cur_weapon->o_which == TWOSWORD) &&
            !(*newclass == C_FIGHTER || *newclass == C_RANGER ||
            *newclass == C_PALADIN)  &&
        cur_weapon->o_which == TWOSWORD)
                cur_weapon->o_which = SWORD;

        /*
         * if he's changing from a thief, assassin, fighter, or monk
     * then we may have to change his sword again since only these
     * types can wield the bastard sword.
         */
        if ((player.t_ctype == C_THIEF  || player.t_ctype == C_ASSASSIN ||
            player.t_ctype == C_FIGHTER || player.t_ctype == C_MONK)    &&
        cur_weapon != NULL && cur_weapon->o_type == WEAPON &&
            (cur_weapon->o_which == BASWORD  ||
            cur_weapon->o_which == TWOSWORD) &&
            !(*newclass == C_THIEF || *newclass == C_ASSASSIN ||
            *newclass == C_MONK)   &&
        cur_weapon->o_which == BASWORD)
                cur_weapon->o_which = SWORD;

        /*
         * if he was a thief, assassin, or monk then take out
     * the trap_look() daemon
         */
        if (player.t_ctype == C_THIEF || player.t_ctype == C_MONK ||
            player.t_ctype == C_ASSASSIN)
                kill_daemon(trap_look);

        /*
         * if he becomes a thief, assassin, or monk then add 
     * the trap_look() daemon
         */
        if (*newclass == C_THIEF || *newclass == C_ASSASSIN ||
        *newclass == C_MONK)
                start_daemon(trap_look, (VOID *)NULL, AFTER);

    /* adjust stats */
        char_type = player.t_ctype = *newclass;
        save = pstats.s_hpt;
        max_stats.s_hpt = pstats.s_hpt = 0;
        max_stats.s_lvl = pstats.s_lvl = 0; 
        max_stats.s_lvladj = pstats.s_lvladj = 0; 
        max_stats.s_exp = pstats.s_exp + rnd(4);
        check_level();
        if (pstats.s_hpt > save) /* don't add to current hits */
            pstats.s_hpt = save;
    }
    dsrpt_player(); /* this should disrupt whatever we were doing */
}

/*
 * Use the relic that our monster is wielding.
 */

m_use_relic(monster)
register struct thing *monster;
{
    register struct object *obj;

    /* Make sure we really have it */
    if (monster->t_using) obj = OBJPTR(monster->t_using);
    else {
        debug("Relic not set!");
        monster->t_action = A_NIL;
        return;
    }

    /* Now let's see what we're using */
    if (obj->o_type == RELIC) switch (obj->o_which) {
        case MING_STAFF: {
            static struct object missile = {
              MISSILE, {0,0}, 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
            };

            debug("Firing Ming's staff");
            sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
            do_motion(&missile,
                       monster->t_newpos.y, monster->t_newpos.x, monster);
            hit_monster(unc(missile.o_pos), &missile, monster);
            monster->t_artifact = monster->t_artifact * 4 / 5;
        }
        when EMORI_CLOAK:
            debug("stunning with Emori's cloak");
            do_zap(monster, obj, &monster->t_newpos, WS_PARALYZE, NULL);
            obj->o_charges = 0;

        when ASMO_ROD: {
            char *name;

            switch (rnd(3)) { /* Select a function */
                case 0:    name = "lightning bolt";
                when 1:    name = "flame";
                otherwise: name = "ice";
            }
            shoot_bolt( monster, 
                        monster->t_pos, 
                        monster->t_newpos, 
                        FALSE, 
                        monster->t_index, 
                        name, 
                        roll(monster->t_stats.s_lvl,6));
            monster->t_artifact /= 2;
        }
        when BRIAN_MANDOLIN:
            /* Make sure the defendant is still around */
            if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
                         hero.y, hero.x) < 25) {
                if (!save(VS_MAGIC, &player, -4) &&
                    !ISWEARING(R_ALERT)) {
                    msg("Some beautiful music enthralls you.");
                    player.t_no_move += movement(&player) * FREEZETIME;
                    player.t_action = A_FREEZE;
                    monster->t_artifact = monster->t_artifact * 2 / 3;
                }
                else {
                    msg("You wince at a sour note.");
                    monster->t_artifact /= 3;
                }
            }
        when GERYON_HORN:
            /* Make sure the defendant is still around */
            if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
                         hero.y, hero.x) < 25) {
                if (!ISWEARING(R_HEROISM) &&
                    !save(VS_MAGIC, &player, -4)) {
                        turn_on(player, ISFLEE);
                        player.t_dest = &monster->t_pos;
                        msg("A shrill blast terrifies you.");
                        monster->t_artifact = monster->t_artifact * 3 / 4;
                }
                else  {
                    msg("A shrill blast sends chills up your spine! ");
                    monster->t_artifact /= 3;
                }
            }

        otherwise:
            /* Unknown RELIC! */
            debug("Unknown wielded relic %d", obj->o_which);
    }
    else debug("Declared relic is %d", obj->o_type);

    turn_off(*monster, CANSURPRISE);
    /* Reset the monsters actions */
    monster->t_action = A_NIL;
    monster->t_using = NULL;
}
 
/*
 * add something to the contents of something else
 */

put_contents(bag, item)
register struct object *bag;            /* the holder of the items */
register struct linked_list *item;      /* the item to put inside  */
{
    register struct linked_list *titem;
    register struct object *tobj;

    bag->o_ac++;
    tobj = OBJPTR(item);
    for (titem = bag->contents; titem != NULL; titem = next(titem)) {
        if ((OBJPTR(titem))->o_which == tobj->o_which)
            break;
    }
    if (titem == NULL) {        /* if not a duplicate put at beginning */
        attach(bag->contents, item);
    }
    else {
        item->l_prev = titem;
        item->l_next = titem->l_next;
        if (next(titem) != NULL) 
            (titem->l_next)->l_prev = item;
        titem->l_next = item;
    }
}

/*
 * remove something from something else
 */

take_contents(bag, item)
register struct object *bag;            /* the holder of the items */
register struct linked_list *item;
{

    if (bag->o_ac <= 0) {
        msg("Nothing to take out");
        return;
    }
    bag->o_ac--;
    detach(bag->contents, item);
    if (!add_pack(item, FALSE))
        put_contents(bag, item);
}


do_bag(item)
register struct linked_list *item;
{

    register struct linked_list *titem = NULL;
    register struct object *obj, *tobj;
    bool doit = TRUE;

    obj = OBJPTR(item);
    while (doit) {
        msg("What do you want to do? (* for a list): ");
        mpos = 0;
        switch (wgetch(cw)) {
            case EOF:
            case ESC:
                msg ("");
                doit = FALSE;
            when '1':
                inventory(obj->contents, ALL);

            when '2':
                if (obj->o_ac >= MAXCONTENTS) {
                    msg("the %s is full", m_magic[obj->o_which].mi_name);
                    break;
                }
                switch (obj->o_which) {
                case MM_BEAKER:
                    titem = get_item(pack, "put in", POTION, FALSE, FALSE);
                when MM_BOOK:
                    titem = get_item(pack, "put in", SCROLL, FALSE, FALSE);
                }
                if (titem == NULL)
                    break;
                detach(pack, titem);
                inpack--;
                put_contents(obj, titem);
            
            when '3':
                titem = get_item(obj->contents,"take out",ALL,FALSE,FALSE);
                if (titem == NULL)
                    break;
                take_contents(obj, titem);
                
            when '4': 
                switch (obj->o_which) {
                case MM_BEAKER:
                    titem = get_item(obj->contents,"quaff",ALL,FALSE,FALSE);
                    if (titem == NULL)
                        break;
                    tobj = OBJPTR(titem);
                    obj->o_ac--;
                    detach(obj->contents, titem);
                    quaff(tobj->o_which, 
                          tobj->o_kind,
                          tobj->o_flags,
                          TRUE);
                    if (p_know[tobj->o_which] && p_guess[tobj->o_which])
                    {
                        free(p_guess[tobj->o_which]);
                        p_guess[tobj->o_which] = NULL;
                    }