Beispiel #1
0
/*
 * This routine changes the address of obj. Be careful not to call it
 * when there might be pointers around in unknown places. For now: only
 * when obj is in the inventory.
 */
static void do_oname(struct obj *obj)
{
	char buf[BUFSZ], qbuf[QBUFSZ];
	const char *aname;
	short objtyp;

	sprintf(qbuf, "What do you want to name %s %s?",
		is_plural(obj) ? "these" : "this", xname(obj));
	getlin(qbuf, buf);
	if (!*buf || *buf == '\033')	return;
	/* strip leading and trailing spaces; unnames item if all spaces */
	mungspaces(buf);

	/* relax restrictions over proper capitalization for artifacts */
	if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
		strcpy(buf, aname);

	if (obj->oartifact) {
		pline("The artifact seems to resist the attempt.");
		return;
	} else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
		int n = rn2((int)strlen(buf));
		char c1, c2;

		c1 = lowc(buf[n]);
		do c2 = 'a' + rn2('z'-'a'); while (c1 == c2);
		buf[n] = (buf[n] == c1) ? c2 : highc(c2);  /* keep same case */
		pline("While engraving your %s slips.", body_part(HAND));
		win_pause_output(P_MESSAGE);
		pline("You engrave: \"%s\".",buf);
	}
	oname(obj, buf);
}
Beispiel #2
0
/*
 * This routine changes the address of obj. Be careful not to call it
 * when there might be pointers around in unknown places. For now: only
 * when obj is in the inventory.
 */
int
do_oname(const struct nh_cmd_arg *arg)
{
    const char *qbuf, *buf;
    const char *aname;
    short objtyp;
    struct obj *obj;

    obj = getargobj(arg, nameable, "name");
    if (!obj)
        return 0;

    qbuf = msgprintf("What do you want to name %s %s?",
                     is_plural(obj) ? "these" : "this",
                     safe_qbuf("", sizeof("What do you want to name these ?"),
                               xname(obj), simple_typename(obj->otyp),
                               is_plural(obj) ? "things" : "thing"));
    buf = getarglin(arg, qbuf);
    if (!*buf || *buf == '\033')
        return 0;
    /* strip leading and trailing spaces; unnames item if all spaces */
    buf = msgmungspaces(buf);

    /* relax restrictions over proper capitalization for artifacts */
    if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
        buf = aname;

    char slipbuf[strlen(buf) + 1];
    if (obj->oartifact) {
        pline("The artifact seems to resist the attempt.");
        return 0;
    } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
        int n = rn2((int)strlen(buf));
        char c1, c2;
        strcpy(slipbuf, buf);

        c1 = lowc(buf[n]);
        do
            c2 = 'a' + rn2('z' - 'a' + 1);
        while (c1 == c2);

        slipbuf[n] = (slipbuf[n] == c1) ? c2 : highc(c2);   /* keep same case */
        pline("While engraving your %s slips.", body_part(HAND));
        win_pause_output(P_MESSAGE);
        pline("You engrave: \"%s\".", slipbuf);
        buf = slipbuf;
    }
    oname(obj, buf);
    return 0;
}
Beispiel #3
0
/* study while confused: returns TRUE if the book is destroyed */
static boolean
confused_book(struct obj *spellbook)
{
    boolean gone = FALSE;

    if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
        spellbook->in_use = TRUE;       /* in case called from learn */
        pline("Being confused you have difficulties in controlling your "
              "actions.");
        win_pause_output(P_MESSAGE);
        pline("You accidentally tear the spellbook to pieces.");
        if (!objects[spellbook->otyp].oc_name_known &&
            !objects[spellbook->otyp].oc_uname)
            docall(spellbook);
        useup(spellbook);
        gone = TRUE;
    } else {
        pline("You find yourself reading the %s line over and over again.",
              spellbook == u.utracked[tos_book] ? "next" : "first");
    }
    return gone;
}
void
level_tele_impl(boolean wizard_tele)
{
    int newlev;
    d_level newlevel;
    const char *escape_by_flying = 0;   /* when surviving dest of -N */
    boolean force_dest = FALSE;
    const char *buf, *killer = NULL;

    if ((Uhave_amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
        && !wizard_tele) {
        pline("You feel very disoriented for a moment.");
        return;
    }
    if ((Teleport_control && !Stunned) || wizard_tele) {
        int trycnt = 0;
        const char *qbuf = "To what level do you want to teleport?";
        do {
            if (++trycnt == 2) {
                if (wizard_tele)
                    qbuf = msgcat(qbuf, " [type a number or ? for a menu]");
                else
                    qbuf = msgcat(qbuf, " [type a number]");
            }
            buf = getlin(qbuf, FALSE);
            if (!strcmp(buf, "\033")) { /* cancelled */
                if (Confusion && rnl(5)) {
                    pline("Oops...");
                    goto random_levtport;
                }
                return;
            } else if (!strcmp(buf, "*")) {
                goto random_levtport;
            } else if (Confusion && rnl(5)) {
                pline("Oops...");
                goto random_levtport;
            }

            if (wizard_tele && !strcmp(buf, "?")) {
                schar destlev = 0;
                xchar destdnum = 0;

                if ((newlev = (int)print_dungeon(TRUE, &destlev, &destdnum))) {
                    newlevel.dnum = destdnum;
                    newlevel.dlevel = destlev;
                    if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
                        const char *dest = "Destination is earth level";
                        if (!Uhave_amulet) {
                            struct obj *obj;

                            obj = mksobj(level, AMULET_OF_YENDOR, TRUE, FALSE,
                                         rng_main);
                            if (obj) {
                                addinv(obj);
                                dest = msgcat(dest, " with the amulet");
                            }
                        }
                        assign_level(&newlevel, &earth_level);
                        pline("%s.", dest);
                    }
                    force_dest = TRUE;
                } else
                    return;
            } else if ((newlev = lev_by_name(buf)) == 0)
                newlev = atoi(buf);
        } while (!newlev && !digit(buf[0]) && (buf[0] != '-' || !digit(buf[1]))
                 && trycnt < 10);

        /* no dungeon escape via this route */
        if (newlev == 0) {
            if (trycnt >= 10)
                goto random_levtport;
            if (ynq("Go to Nowhere.  Are you sure?") != 'y')
                return;
            pline("You %s in agony as your body begins to warp...",
                  is_silent(youmonst.data) ? "writhe" : "scream");
            win_pause_output(P_MESSAGE);
            pline("You cease to exist.");
            if (invent)
                pline("Your possessions land on the %s with a thud.",
                      surface(u.ux, u.uy));
            done(DIED, "committed suicide");
            pline("An energized cloud of dust begins to coalesce.");
            pline("Your body rematerializes%s.",
                  invent ? ", and you gather up all your possessions" : "");
            return;
        }

        /* if in Knox and the requested level > 0, stay put. we let negative
           values requests fall into the "heaven" loop. */
        if (Is_knox(&u.uz) && newlev > 0) {
            pline("You shudder for a moment.");
            return;
        }
        /* if in Quest, the player sees "Home 1", etc., on the status line,
           instead of the logical depth of the level.  controlled level
           teleport request is likely to be relativized to the status line, and
           consequently it should be incremented to the value of the logical
           depth of the target level. we let negative values requests fall into
           the "heaven" loop. */
        if (In_quest(&u.uz) && newlev > 0)
            newlev = newlev + find_dungeon(&u.uz).depth_start - 1;
    } else {    /* involuntary level tele */
    random_levtport:
        newlev = random_teleport_level();
        if (newlev == depth(&u.uz)) {
            pline("You shudder for a moment.");
            return;
        }
    }

    if (!next_to_u()) {
        pline("You shudder for a moment.");
        return;
    }

    if (In_endgame(&u.uz)) {    /* must already be wizard */
        int llimit = dunlevs_in_dungeon(&u.uz);

        if (newlev >= 0 || newlev <= -llimit) {
            pline("You can't get there from here.");
            return;
        }
        newlevel.dnum = u.uz.dnum;
        newlevel.dlevel = llimit + newlev;
        schedule_goto(&newlevel, FALSE, FALSE, 0, NULL, NULL);
        return;
    }

    if (newlev < 0 && !force_dest) {
        if (*u.ushops0) {
            /* take unpaid inventory items off of shop bills */
            in_mklev = TRUE;    /* suppress map update */
            u_left_shop(u.ushops0, TRUE);
            /* you're now effectively out of the shop */
            *u.ushops0 = *u.ushops = '\0';
            in_mklev = FALSE;
        }
        if (newlev <= -10) {
            pline("You arrive in heaven.");
            verbalize("Thou art early, but we'll admit thee.");
            killer = "went to heaven prematurely";
        } else if (newlev == -9) {
            pline("You feel deliriously happy. ");
            pline("(In fact, you're on Cloud 9!) ");
            win_pause_output(P_MESSAGE);
        } else
            pline("You are now high above the clouds...");

        if (killer) {
            ;   /* arrival in heaven is pending */
        } else if (Levitation) {
            escape_by_flying = "float gently down to earth";
        } else if (Flying) {
            escape_by_flying = "fly down to the ground";
        } else {
            pline("Unfortunately, you don't know how to fly.");
            pline("You plummet a few thousand feet to your death.");
            killer = msgcat_many("teleported out of the dungeon and fell to ",
                                 uhis(), " death", NULL);
        }
    }

    if (killer) {       /* the chosen destination was not survivable */
        d_level lsav;

        /* set specific death location; this also suppresses bones */
        lsav = u.uz;    /* save current level, see below */
        u.uz.dnum = 0;  /* main dungeon */
        u.uz.dlevel = (newlev <= -10) ? -10 : 0;        /* heaven or surface */
        done(DIED, killer);
        /* can only get here via life-saving (or declining to die in
           explore|debug mode); the hero has now left the dungeon... */
        escape_by_flying = "find yourself back on the surface";
        u.uz = lsav;    /* restore u.uz so escape code works */
    }

    /* calls done(ESCAPED) if newlevel==0 */
    if (escape_by_flying) {
        pline("You %s.", escape_by_flying);
        done(ESCAPED, "teleported to safety");
    } else if (u.uz.dnum == medusa_level.dnum &&
               newlev >= (find_dungeon(&u.uz).depth_start +
                          dunlevs_in_dungeon(&u.uz))) {
        if (!(wizard_tele && force_dest))
            find_hell(&newlevel);
    } else {
        /* if invocation did not yet occur, teleporting into the last level of
           Gehennom is forbidden. */
        if (!wizard_tele)
            if (Inhell && !u.uevent.invoked &&
                newlev >= (find_dungeon(&u.uz).depth_start +
                           dunlevs_in_dungeon(&u.uz) - 1)) {
                newlev = (find_dungeon(&u.uz).depth_start +
                          dunlevs_in_dungeon(&u.uz) - 2);
                pline("Sorry...");
            }
        /* no teleporting out of quest dungeon */
        if (In_quest(&u.uz) && newlev < depth(&qstart_level))
            newlev = depth(&qstart_level);
        /* the player thinks of levels purely in logical terms, so we must
           translate newlev to a number relative to the current dungeon. */
        if (!(wizard_tele && force_dest))
            get_level(&newlevel, newlev);
    }
    schedule_goto(&newlevel, FALSE, FALSE, 0, NULL, NULL);
    /* in case player just read a scroll and is about to be asked to call it
       something, we can't defer until the end of the turn */
    if (!flags.mon_moving)
        deferred_goto();
}
Beispiel #5
0
/* returns 0 if something was detected		*/
int food_detect(struct obj *sobj, boolean *scr_known)
{
    struct obj *obj;
    struct monst *mtmp;
    int ct = 0, ctu = 0;
    boolean confused = (Confusion || (sobj && sobj->cursed)), stale;
    char oclass = confused ? POTION_CLASS : FOOD_CLASS;
    const char *what = confused ? "something" : "food";
    int uw = u.uinwater;

    stale = clear_stale_map(oclass, 0);

    for (obj = level->objlist; obj; obj = obj->nobj)
	if (o_in(obj, oclass)) {
	    if (obj->ox == u.ux && obj->oy == u.uy) ctu++;
	    else ct++;
	}
    for (mtmp = level->monlist; mtmp && !ct; mtmp = mtmp->nmon) {
	/* no DEADMONSTER(mtmp) check needed since dmons never have inventory */
	for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (o_in(obj, oclass)) {
		ct++;
		break;
	    }
    }
    
    if (!ct && !ctu) {
	*scr_known = stale && !confused;
	if (stale) {
	    doredraw();
	    pline("You sense a lack of %s nearby.", what);
	    if (sobj && sobj->blessed) {
		if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE));
		u.uedibility = 1;
	    }
	} else if (sobj) {
	    char buf[BUFSZ];
	    sprintf(buf, "Your %s twitches%s.", body_part(NOSE),
			(sobj->blessed && !u.uedibility) ? " then starts to tingle" : "");
	    if (sobj->blessed && !u.uedibility) {
		boolean savebeginner = flags.beginner;	/* prevent non-delivery of */
		flags.beginner = FALSE;			/* 	message            */
		strange_feeling(sobj, buf);
		flags.beginner = savebeginner;
		u.uedibility = 1;
	    } else
		strange_feeling(sobj, buf);
	}
	return !stale;
    } else if (!ct) {
	*scr_known = TRUE;
	pline("You %s %s nearby.", sobj ? "smell" : "sense", what);
	if (sobj && sobj->blessed) {
		if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE));
		u.uedibility = 1;
	}
    } else {
	struct obj *temp;
	*scr_known = TRUE;
	cls();
	u.uinwater = 0;
	for (obj = level->objlist; obj; obj = obj->nobj)
	    if ((temp = o_in(obj, oclass)) != 0) {
		if (temp != obj) {
		    temp->ox = obj->ox;
		    temp->oy = obj->oy;
		}
		map_object(temp,1);
	    }
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
	    /* no DEADMONSTER(mtmp) check needed since dmons never have inventory */
	    for (obj = mtmp->minvent; obj; obj = obj->nobj)
		if ((temp = o_in(obj, oclass)) != 0) {
		    temp->ox = mtmp->mx;
		    temp->oy = mtmp->my;
		    map_object(temp,1);
		    break;	/* skip rest of this monster's inventory */
		}
	newsym(u.ux,u.uy);
	if (sobj) {
	    if (sobj->blessed) {
	    	pline("Your %s %s to tingle and you smell %s.", body_part(NOSE),
	    		u.uedibility ? "continues" : "starts", what);
		u.uedibility = 1;
	    } else
		pline("Your %s tingles and you smell %s.", body_part(NOSE), what);
	}
	else pline("You sense %s.", what);
	win_pause_output(P_MAP);
	exercise(A_WIS, TRUE);
	doredraw();
	u.uinwater = uw;
	if (Underwater) under_water(2);
	if (u.uburied) under_ground(2);
    }
    return 0;
}
Beispiel #6
0
/* look for gold, on the floor or in monsters' possession */
int gold_detect(struct obj *sobj, boolean *scr_known)
{
    struct obj *obj;
    struct monst *mtmp;
    int uw = u.uinwater;
    struct obj *temp;
    boolean stale;

    *scr_known = stale = clear_stale_map(COIN_CLASS, sobj->blessed ? GOLD : 0);

    /* look for gold carried by monsters (might be in a container) */
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably not needed in this case but... */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    *scr_known = TRUE;
	    goto outgoldmap;	/* skip further searching */
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && o_material(obj, GOLD)) {
	    	*scr_known = TRUE;
	    	goto outgoldmap;
	    } else if (o_in(obj, COIN_CLASS)) {
		*scr_known = TRUE;
		goto outgoldmap;	/* skip further searching */
	    }
    }
    
    /* look for gold objects */
    for (obj = level->objlist; obj; obj = obj->nobj) {
	if (sobj->blessed && o_material(obj, GOLD)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	} else if (o_in(obj, COIN_CLASS)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	}
    }

    if (!*scr_known) {
	/* no gold found on floor or monster's inventory.
	   adjust message if you have gold in your inventory */
	char buf[BUFSZ];
	if (youmonst.data == &mons[PM_GOLD_GOLEM]) {
		sprintf(buf, "You feel like a million %s!", currency(2L));
	} else if (hidden_gold() || money_cnt(invent))
		strcpy(buf, "You feel worried about your future financial situation.");
	else
		strcpy(buf, "You feel materially poor.");
	strange_feeling(sobj, buf);
	return 1;
    }
    /* only under me - no separate display required */
    if (stale) doredraw();
    pline("You notice some gold between your %s.", makeplural(body_part(FOOT)));
    return 0;

outgoldmap:
    cls();

    u.uinwater = 0;
    /* Discover gold locations. */
    for (obj = level->objlist; obj; obj = obj->nobj) {
    	if (sobj->blessed && (temp = o_material(obj, GOLD))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	} else if ((temp = o_in(obj, COIN_CLASS))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	}
    }
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably overkill here */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    struct obj gold;

	    gold.otyp = GOLD_PIECE;
	    gold.ox = mtmp->mx;
	    gold.oy = mtmp->my;
	    map_object(&gold,1);
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && (temp = o_material(obj, GOLD))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    } else if ((temp = o_in(obj, COIN_CLASS))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    }
    }
    
    newsym(u.ux,u.uy);
    pline("You feel very greedy, and sense gold!");
    exercise(A_WIS, TRUE);
    win_pause_output(P_MAP);
    doredraw();
    u.uinwater = uw;
    if (Underwater) under_water(2);
    if (u.uburied) under_ground(2);
    return 0;
}