billr@saab.CNA.TEK.COM (Bill Randle) (07/24/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 67
Archive-name: NetHack3/Part12
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 12 (of 38)."
# Contents: src/do.c src/do_wear.c
# Wrapped by billr@saab on Sun Jul 23 21:32:55 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/do.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/do.c'\"
else
echo shar: Extracting \"'src/do.c'\" \(19350 characters\)
sed "s/^X//" >'src/do.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)do.c 3.0 89/06/12
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X/* Contains code for 'd', 'D' (drop), '>', '<' (up, down) */
X
X#include "hack.h"
X
X#if defined(DGK) && !defined(TOS)
Xextern struct finfo fileinfo[];
X#else
Xextern boolean level_exists[];
X#endif
X
Xstatic int drop P((struct obj *));
X
Xstatic const char drop_types[] = { '0', GOLD_SYM, '#', 0 };
X
Xint
Xdodrop() {
X return(drop(getobj(drop_types, "drop")));
X}
X
X/* Used for objects which sometimes do special things when dropped; must be
X * called with the object not in any chain. Returns 1 if the object is
X * gone.
X */
Xboolean
Xflooreffects(obj,x,y)
Xstruct obj *obj;
Xint x,y;
X{
X if(obj->otyp == BOULDER && IS_POOL(levl[x][y].typ)) {
X#ifdef STRONGHOLD
X if(levl[x][y].typ == DRAWBRIDGE_UP)
X levl[x][y].drawbridgemask |= DB_FLOOR;
X else
X#endif
X levl[x][y].typ = ROOM;
X if (cansee(x,y))
X pline("There is a large splash as the boulder fills the %s.",
X (levl[x][y].typ==POOL) ? "pool" : "moat");
X else if (flags.soundok)
X You("hear a splash.");
X obfree(obj, (struct obj *)0);
X mnewsym(x,y);
X if ((x != u.ux || y != u.uy || Invisible) && !Blind)
X newsym(x,y);
X return TRUE;
X }
X return FALSE;
X}
X
X#ifdef ALTARS
Xvoid
Xdoaltarobj(obj) /* obj is an object dropped on an altar */
X register struct obj *obj;
X{
X if (Blind) return;
X if (obj->blessed || obj->cursed) {
X register const char *fcolor = Hallucination ? hcolor() :
X obj->blessed ? amber : black;
X
X pline("There is %s %s flash as %s hit%s the altar.",
X index(vowels, *fcolor) ? "an" : "a",
X fcolor,
X doname(obj),
X (obj->quan==1) ? "s" : "");
X if (!Hallucination) obj->bknown = 1;
X } else {
X pline("%s land%s on the altar.", Doname2(obj),
X (obj->quan==1) ? "s" : "");
X obj->bknown = 1;
X }
X}
X#endif
X
X#ifdef SINKS
Xstatic
Xvoid
Xtrycall(obj)
Xregister struct obj *obj;
X{
X if(!objects[obj->otyp].oc_name_known &&
X !objects[obj->otyp].oc_uname)
X docall(obj);
X}
X
Xstatic
Xvoid
Xdosinkring(obj) /* obj is a ring being dropped over a kitchen sink */
Xregister struct obj *obj;
X{
X register struct obj *otmp,*otmp2;
X register boolean ideed = TRUE;
X
X You("drop %s down the drain.", doname(obj));
X switch(obj->otyp) { /* effects that can be noticed without eyes */
X case RIN_SEARCHING:
X You("thought your %s got lost in the sink, but there it is!",
X xname(obj));
X dropx(obj);
X trycall(obj);
X return;
X case RIN_LEVITATION:
X pline("The sink quivers upward for a moment.");
X break;
X case RIN_POISON_RESISTANCE:
X You("smell rotten %s.", makeplural(pl_fruit));
X break;
X case RIN_AGGRAVATE_MONSTER:
X pline("Several flies buzz angrily around the sink.");
X break;
X case RIN_SHOCK_RESISTANCE:
X pline("Static electricity surrounds the sink.");
X break;
X case RIN_CONFLICT:
X You("hear loud noises coming from the drain.");
X break;
X case RIN_GAIN_STRENGTH:
X pline("The water flow seems %ser now.",
X (obj->spe<0) ? "weak" : "strong");
X break;
X case RIN_INCREASE_DAMAGE:
X pline("The water's force seems %ser now.",
X (obj->spe<0) ? "small" : "great");
X break;
X default:
X ideed = FALSE;
X break;
X }
X if(!Blind && !ideed) {
X ideed = TRUE;
X switch(obj->otyp) { /* effects that need eyes */
X case RIN_ADORNMENT:
X pline("The faucets flash brightly for a moment.");
X break;
X case RIN_REGENERATION:
X pline("The sink looks as good as new.");
X break;
X case RIN_INVISIBILITY:
X You("don't see anything happen to the sink.");
X break;
X case RIN_SEE_INVISIBLE:
X You("see some air in the sink.");
X break;
X case RIN_STEALTH:
X pline("The sink seems to blend into the floor for a moment.");
X break;
X case RIN_HUNGER:
X ideed = FALSE;
X for(otmp=fobj; otmp; otmp=otmp2) {
X otmp2 = otmp->nobj;
X if(otmp->ox == u.ux && otmp->oy == u.uy)
X if(otmp != uball && otmp != uchain) {
X pline("Suddenly, %s vanishes from the sink!",
X doname(otmp));
X delobj(otmp);
X ideed = TRUE;
X }
X }
X break;
X case RIN_FIRE_RESISTANCE:
X pline("The hot water faucet flashes brightly for a moment.");
X break;
X case RIN_COLD_RESISTANCE:
X pline("The cold water faucet flashes brightly for a moment.");
X break;
X case RIN_PROTECTION_FROM_SHAPE_CHAN:
X pline("The sink looks nothing like a fountain.");
X break;
X case RIN_PROTECTION:
X pline("The sink glows %s for a moment.",
X Hallucination ? hcolor() :
X (obj->spe<0) ? black : silver);
X break;
X case RIN_WARNING:
X pline("The sink glows %s for a moment.",
X Hallucination ? hcolor() : white);
X break;
X case RIN_TELEPORTATION:
X pline("The sink momentarily vanishes.");
X break;
X case RIN_TELEPORT_CONTROL:
X pline("The sink looks like it is being beamed aboard somewhere.");
X break;
X#ifdef POLYSELF
X case RIN_POLYMORPH:
X pline("The sink momentarily looks like a fountain.");
X break;
X case RIN_POLYMORPH_CONTROL:
X pline("The sink momentarily looks like a regularly erupting geyser.");
X break;
X#endif
X }
X }
X if(ideed)
X trycall(obj);
X else
X You("hear the ring bouncing down the drainpipe.");
X if (!rn2(20)) {
X pline("The sink backs up, leaving %s.", doname(obj));
X dropx(obj);
X }
X else
X useup(obj);
X}
X#endif
X
X/* some common tests when trying to drop or throw items */
Xboolean
Xcanletgo(obj,word)
Xregister struct obj *obj;
Xregister char *word;
X{
X if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){
X You("cannot %s something you are wearing.",word);
X return(FALSE);
X }
X if (obj->otyp == LOADSTONE && obj->cursed) {
X obj->bknown = 1;
X pline("For some reason, you cannot %s the stone%s!",
X word,
X obj->quan==1 ? "" : "s");
X return(FALSE);
X }
X#ifdef WALKIES
X if (obj->otyp == LEASH && obj->leashmon != 0) {
X pline ("The leash is tied around your %s.",
X body_part(HAND));
X return(FALSE);
X }
X#endif
X return(TRUE);
X}
X
Xstatic int
Xdrop(obj) register struct obj *obj; {
X if(!obj) return(0);
X if(obj->olet == GOLD_SYM) { /* pseudo object */
X register long amount = OGOLD(obj);
X
X/* Fix bug with dropping huge amounts of gold read as negative KAA */
X if(amount < 0) {
X u.ugold += amount;
X pline("The LRS would be very interested to know you have that much.");
X } else {
X /* uswallow test added by GAN 01/29/87 */
X if(flags.verbose)
X You("drop %ld gold piece%s.",
X amount, plur(amount));
X if(u.uswallow)
X (u.ustuck)->mgold += amount;
X else {
X mkgold(amount, u.ux, u.uy);
X if(Invisible) newsym(u.ux, u.uy);
X }
X }
X free((genericptr_t) obj);
X return(1);
X }
X if(!canletgo(obj,"drop"))
X return(0);
X if(obj == uwep) {
X if(welded(uwep)) {
X weldmsg(obj, FALSE);
X return(0);
X }
X setuwep((struct obj *)0);
X if(uwep) return 0; /* lifesaved and rewielded */
X }
X#ifdef SINKS
X if((obj->olet == RING_SYM) && IS_SINK(levl[u.ux][u.uy].typ)
X && !u.uswallow) {
X dosinkring(obj);
X return(1);
X }
X#endif
X#ifdef ALTARS
X if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) {
X /* turn water into [(un)holy] water */
X if (obj->otyp == POT_WATER) {
X obj->blessed = !!(levl[u.ux][u.uy].altarmask & A_LAW);
X obj->cursed = !!(levl[u.ux][u.uy].altarmask & A_CHAOS);
X }
X doaltarobj(obj); /* set bknown */
X } else
X#endif
X if(flags.verbose) You("drop %s.", doname(obj));
X dropx(obj);
X return(1);
X}
X
X/* Called in several places - should not produce texts */
Xvoid
Xdropx(obj)
Xregister struct obj *obj;
X{
X freeinv(obj);
X dropy(obj);
X}
X
Xvoid
Xdropy(obj)
Xregister struct obj *obj;
X{
X if (flooreffects(obj,u.ux,u.uy)) return;
X#ifdef WORM
X if(obj->otyp == CRYSKNIFE)
X obj->otyp = WORM_TOOTH;
X#endif
X /* uswallow check done by GAN 01/29/87 */
X if(u.uswallow)
X mpickobj(u.ustuck,obj);
X else {
X obj->ox = u.ux;
X obj->oy = u.uy;
X obj->nobj = fobj;
X fobj = obj;
X levl[u.ux][u.uy].omask = 1;
X if(Invisible) newsym(u.ux,u.uy);
X subfrombill(obj);
X stackobj(obj);
X }
X}
X
X/* drop several things */
Xint
Xdoddrop() {
X return(ggetobj("drop", drop, 0));
X}
X
X#ifdef STRONGHOLD
Xstatic boolean at_ladder = FALSE; /* on a ladder, used in goto_level */
X#endif
X
Xint
Xdodown()
X{
X struct trap *trap = 0;
X#ifdef STRONGHOLD
X if((u.ux != xdnstair || u.uy != ydnstair) &&
X (!xdnladder || u.ux != xdnladder || u.uy != ydnladder)) {
X#else
X if(u.ux != xdnstair || u.uy != ydnstair) {
X#endif /* STRONGHOLD /**/
X if (!(trap = t_at(u.ux,u.uy)) || trap->ttyp != TRAPDOOR
X || !trap->tseen) {
X You("can't go down here.");
X return(0);
X }
X }
X if(u.ustuck) {
X You("are being held, and cannot go down.");
X return(1);
X }
X if(Levitation) {
X#ifdef STRONGHOLD
X pline("You're floating high above the %s.",
X levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder");
X#else
X pline("You're floating high above the stairs.");
X#endif /* STRONGHOLD /**/
X return(0);
X }
X
X#ifdef WALKIES
X if(!next_to_u()) {
X You("are held back by your pet!");
X return(0);
X } else {
X#endif
X unsee();
X#ifdef STRONGHOLD
X if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
X#endif
X if (trap)
X pline("You jump into the trapdoor...");
X goto_level(dlevel+1, !trap);
X#ifdef STRONGHOLD
X at_ladder = FALSE;
X#endif
X#ifdef WALKIES
X }
X#endif
X return(1);
X}
X
Xint
Xdoup()
X{
X#ifdef STRONGHOLD
X if((u.ux != xupstair || u.uy != yupstair) &&
X (!xupladder || u.ux != xupladder || u.uy != yupladder)) {
X#else
X if(u.ux != xupstair || u.uy != yupstair) {
X#endif /* STRONGHOLD /**/
X You("can't go up here.");
X return(0);
X }
X if(u.ustuck) {
X You("are being held, and cannot go up.");
X return(1);
X }
X if(inv_weight() + 5 > 0) {
X /* No levitation check; inv_weight() already allows for it */
X#ifdef STRONGHOLD
X Your("load is too heavy to climb the %s.",
X levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder");
X#else
X Your("load is too heavy to climb the stairs.");
X#endif /* STRONGHOLD /**/
X return(1);
X }
X
X#ifdef ENDGAME
X if (dlevel == 1) {
X pline("Beware, there will be no return! Still climb? ");
X if (yn() != 'y') return(0);
X else more();
X }
X#endif
X#ifdef WALKIES
X if(!next_to_u()) {
X You("are held back by your pet!");
X return(0);
X } else {
X#endif
X unsee();
X#ifdef STRONGHOLD
X if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
X goto_level(dlevel-1,
X (dlevel-1 < stronghold_level || (at_ladder &&
X dlevel-1 >= tower_level && dlevel-1 < tower_level+2)));
X at_ladder = FALSE;
X#else
X goto_level(dlevel-1, (dlevel-1 <= medusa_level));
X#endif
X#ifdef WALKIES
X }
X#endif
X return(1);
X}
X
Xvoid
Xgoto_level(newlevel, at_stairs)
Xregister int newlevel;
Xregister boolean at_stairs;
X{
X register int fd;
X register boolean up = (newlevel < dlevel);
X
X#ifdef ENDGAME
X if(dlevel == ENDLEVEL) return; /* To be on the safe side.. */
X#endif
X if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
X if(newlevel <= 0)
X#ifdef ENDGAME
X if(u.uhave_amulet)
X newlevel = ENDLEVEL; /* Endgame Level !!! */
X else
X#endif
X done("escaped"); /* in fact < 0 is impossible */
X
X/* If you have the amulet and are trying to get out of Hell, going
X * up a set of stairs sometimes does some very strange things!
X */
X#ifdef HARD
X if(Inhell && up && at_stairs &&
X (dlevel < MAXLEVEL-3) && u.uhave_amulet) {
X newlevel = (rn2(5) ? newlevel :
X/* neutral */ !u.ualigntyp ? (rn2(2) ? dlevel : dlevel + (rnd(5) - 2)) :
X/* lawful */ (u.ualigntyp == U_LAWFUL) ? dlevel + (rnd(5) - 2) :
X/* chaotic */ dlevel);
X pline("A mysterious force surrounds you...");
X if(newlevel < 1) newlevel = dlevel;
X if(newlevel == dlevel) (void) dotele();
X
X }
X#endif /* HARD /* */
X if(newlevel == dlevel) return; /* this can happen */
X#ifdef STRONGHOLD
X /* In Nethack 3.0, Hell starts after the stronghold. Moreover,
X * there are traps in the stronghold, that can send the player
X * to hell (gnark, gnark)! So we have to test here:
X */
X if(!Inhell && newlevel > stronghold_level && !up && !at_ladder
X# ifdef ENDGAME
X && newlevel < ENDLEVEL
X# endif
X ) {
X#else
X if(!Inhell && newlevel >= HELLLEVEL && !up) {
X#endif /* STRONGHOLD /**/
X You("arrive at the center of the earth...");
X pline("Unfortunately, it is here that hell is located.");
X#ifdef MSDOS
X (void) fflush(stdout);
X#endif
X if(Fire_resistance) {
X pline("But the fire doesn't seem to harm you.");
X } else {
X int save_dlevel = dlevel;
X
X You("burn to a crisp.");
X You("die...");
X dlevel = maxdlevel = newlevel;
X killer = "visit to hell";
X done("burned");
X dlevel = newlevel = save_dlevel; /* in case they survive */
X }
X }
X
X glo(dlevel);
X#ifdef MSDOS
X /* Use O_TRUNC to force the file to be shortened if it already
X * exists and is currently longer.
X */
X fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
X#else
X fd = creat(lock, FCMASK);
X#endif
X if(fd < 0) {
X /*
X * This is not quite impossible: e.g., we may have
X * exceeded our quota. If that is the case then we
X * cannot leave this level, and cannot save either.
X * Another possibility is that the directory was not
X * writable.
X */
X#ifdef DGK
X pline("Cannot create level file '%s'.", lock);
X#else
X pline("A mysterious force prevents you from going %s.",
X up ? "up" : "down");
X#endif
X return;
X }
X
X#ifdef DGK
X if (!savelev(fd, dlevel, COUNT)) {
X# ifdef ZEROCOMP
X bflush(fd);
X# endif
X (void) close(fd);
X (void) unlink(lock);
X pline("NetHack is out of disk space for making levels!");
X You("can save, quit, or continue playing.");
X return;
X }
X#endif
X if(Punished) unplacebc();
X u.utrap = 0; /* needed in level_tele */
X u.ustuck = 0; /* idem */
X keepdogs();
X seeoff(1);
X if(u.uswallow) /* idem */
X u.uswldtim = u.uswallow = 0;
X flags.nscrinh = 1;
X u.ux = FAR; /* hack */
X (void) inshop(); /* probably was a trapdoor */
X
X#ifdef DGK
X# ifdef ZEROCOMP
X bflush(fd); /* forget buffer */
X# endif
X savelev(fd,dlevel, WRITE);
X#else
X savelev(fd,dlevel);
X#endif
X#ifdef ZEROCOMP
X bflush(fd); /* flush buffer */
X#endif
X (void) close(fd);
X#ifdef REINCARNATION
X if (newlevel == rogue_level || dlevel == rogue_level) {
X /* No graphics characters on Rogue levels */
X if (dlevel != rogue_level) {
X savesyms = showsyms;
X showsyms = defsyms;
X }
X if (newlevel != rogue_level)
X showsyms = savesyms;
X }
X#endif
X dlevel = newlevel;
X if(maxdlevel < dlevel)
X maxdlevel = dlevel;
X glo(dlevel);
X if(
X# ifdef ENDGAME
X dlevel == ENDLEVEL ||
X# endif
X#if defined(DGK) && !defined(TOS)
X /* If the level has no .where yet, it hasn't been made */
X !fileinfo[dlevel].where)
X#else
X !level_exists[dlevel])
X#endif
X mklev();
X else {
X#if defined(DGK) && !defined(TOS)
X /* If not currently accessible, swap it in. */
X if (fileinfo[dlevel].where != ACTIVE)
X swapin_file(dlevel);
X#endif
X#if defined(MSDOS) && !defined(TOS)
X if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {
X#else
X if((fd = open(lock,0)) < 0) {
X#endif
X pline("Cannot open %s .", lock);
X pline("Probably someone removed it.");
X done("tricked");
X }
X#ifdef ZEROCOMP
X minit();
X#endif
X getlev(fd, hackpid, dlevel, FALSE);
X (void) close(fd);
X }
X
X#ifdef ENDGAME
X if(dlevel != ENDLEVEL)
X#endif
X if(at_stairs) {
X if(up) {
X#ifdef STRONGHOLD
X if (!at_ladder) {
X#endif
X u.ux = xdnstair;
X u.uy = ydnstair;
X#ifdef STRONGHOLD
X } else {
X u.ux = xdnladder;
X u.uy = ydnladder;
X }
X#endif
X/* Remove bug which crashes with levitation/punishment KAA */
X if(Punished) {
X if(!Levitation)
X#ifdef STRONGHOLD
X pline("With great effort you climb the %s.",
X !at_ladder ? "stairs" : "ladder");
X#else
X pline("With great effort you climb the stairs.");
X#endif
X placebc(1);
X }
X } else {
X#ifdef STRONGHOLD
X if (!at_ladder) {
X#endif
X u.ux = xupstair;
X u.uy = yupstair;
X#ifdef STRONGHOLD
X } else {
X u.ux = xupladder;
X u.uy = yupladder;
X }
X#endif
X if(inv_weight() + 5 > 0 || Punished || Fumbling) {
X#ifdef STRONGHOLD
X You("fall down the %s.",
X !at_ladder ? "stairs" : "ladder");
X#else
X You("fall down the stairs.");
X#endif
X losehp(rnd(3), "fall");
X if(Punished) {
X if(uwep != uball && rn2(3)) {
X pline("... and are hit by the iron ball.");
X losehp(rnd(20), "iron ball");
X }
X placebc(1);
X }
X selftouch("Falling, you");
X }
X }
X } else { /* trapdoor or level_tele */
X register int tryct = 0;
X do {
X#ifdef STRONGHOLD
X /* Prevent teleport-landing inside the castle */
X if(dlevel == stronghold_level) {
X if(up) u.ux = (COLNO - rnd(8));
X else u.ux = rnd(6);
X }
X else
X /* Prevent teleport-landing inside Vlad's tower */
X if(dlevel >= tower_level && dlevel <= tower_level+2) {
X do {
X u.ux = rnd(COLNO-1);
X } while (u.ux > 29 && u.ux < 47);
X }
X else
X#endif
X u.ux = rnd(COLNO-1);
X u.uy = rn2(ROWNO);
X } while(tryct++ < 100 && (levl[u.ux][u.uy].typ != ROOM &&
X levl[u.ux][u.uy].typ != CORR) || levl[u.ux][u.uy].mmask);
X if(tryct >= 100)
X panic("goto_level: could not relocate player!");
X if(Punished){
X if(uwep != uball && !up /* %% */ && rn2(5)){
X pline("The iron ball falls on your %s.",
X body_part(HEAD));
X if (uarmh)
X Your("helmet doesn't help too much...");
X losehp(rnd(25), "iron ball");
X }
X placebc(1);
X }
X selftouch("Falling, you");
X }
X (void) inshop();
X initrack();
X
X losedogs();
X if(levl[u.ux][u.uy].mmask) mnexto(m_at(u.ux, u.uy));
X flags.nscrinh = 0;
X setsee();
X seeobjs(); /* make old cadavers disappear - riv05!a3 */
X docrt();
X if(!flags.nopick && (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask))
X pickup(1);
X else read_engr_at(u.ux,u.uy);
X#ifdef HARD
X /* Final confrontation */
X if (dlevel == 1 && u.uhave_amulet && flags.no_of_wizards == 0)
X resurrect();
X#endif
X}
X
Xint
Xdonull() {
X return(1); /* Do nothing, but let other things happen */
X}
X
Xstatic
Xint
Xwipeoff() {
X if(u.ucreamed < 4) u.ucreamed = 0;
X else u.ucreamed -= 4;
X if (Blinded < 4) Blinded = 0;
X else Blinded -= 4;
X if (!Blinded) {
X pline("You've got the glop off.");
X u.ucreamed = 0;
X make_blinded(0L,TRUE);
X return(0);
X } else if (!u.ucreamed) {
X Your("%s feels clean now.", body_part(FACE));
X return(0);
X }
X return(1); /* still busy */
X}
X
Xint
Xdowipe()
X{
X if(u.ucreamed) {
X static char buf[39];
X
X Sprintf(buf, "wiping off your %s", body_part(FACE));
X set_occupation(wipeoff, buf, 0);
X /* Not totally correct; what if they change back after now
X * but before they're finished wiping?
X */
X return(1);
X }
X Your("%s is already clean.", body_part(FACE));
X return(1);
X}
X
X/* split obj so that it gets size num */
X/* remainder is put in the object structure delivered by this call */
Xstruct obj *
Xsplitobj(obj, num) register struct obj *obj; register int num; {
Xregister struct obj *otmp;
X otmp = newobj(0);
X *otmp = *obj; /* copies whole structure */
X otmp->o_id = flags.ident++;
X otmp->onamelth = 0;
X obj->quan = num;
X obj->owt = weight(obj);
X otmp->quan -= num;
X otmp->owt = weight(otmp); /* -= obj->owt ? */
X obj->nobj = otmp;
X if(obj->unpaid) splitbill(obj,otmp);
X return(otmp);
X}
X
Xvoid
Xset_wounded_legs(side, timex)
Xregister long side;
Xregister int timex;
X{
X if(!Wounded_legs) ATEMP(A_DEX)--;
X
X if(!Wounded_legs || (Wounded_legs & TIMEOUT))
X Wounded_legs |= side + timex;
X else
X Wounded_legs |= side;
X}
X
Xvoid
Xheal_legs()
X{
X if(Wounded_legs) {
X if (ATEMP(A_DEX) < 0) ATEMP(A_DEX)++;
X
X if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) {
X Your("%s feel somewhat better.",
X makeplural(body_part(LEG)));
X } else {
X Your("%s feels somewhat better.",
X body_part(LEG));
X }
X Wounded_legs = 0;
X }
X}
END_OF_FILE
if test 19350 -ne `wc -c <'src/do.c'`; then
echo shar: \"'src/do.c'\" unpacked with wrong size!
fi
# end of 'src/do.c'
fi
if test -f 'src/do_wear.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/do_wear.c'\"
else
echo shar: Extracting \"'src/do_wear.c'\" \(32041 characters\)
sed "s/^X//" >'src/do_wear.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)do_wear.c 3.0 88/05/10
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
Xstatic int todelay;
X
Xstatic long takeoff_mask = 0L, taking_off = 0L;
Xstatic const long takeoff_order[] = { WORN_BLINDF, 1L, /* weapon */
X WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK,
X WORN_HELMET, WORN_AMUL, WORN_ARMOR,
X#ifdef SHIRT
X WORN_SHIRT,
X#endif
X WORN_BOOTS, 0L };
X
Xvoid
Xoff_msg(otmp) register struct obj *otmp; {
X if(flags.verbose)
X You("were wearing %s.", doname(otmp));
X}
X
X/* for items that involve no delay */
Xstatic void
Xon_msg(otmp) register struct obj *otmp; {
X register char *bp = xname(otmp);
X char buf[BUFSZ];
X
X setan(bp, buf);
X if(flags.verbose)
X You("are now wearing %s.", buf);
X}
X
Xboolean
Xis_boots(otmp) register struct obj *otmp; {
X return(otmp->otyp >= LOW_BOOTS &&
X otmp->otyp <= LEVITATION_BOOTS);
X}
X
Xboolean
Xis_helmet(otmp) register struct obj *otmp; {
X#ifdef TOLKIEN
X return(otmp->otyp >= ELVEN_LEATHER_HELM &&
X otmp->otyp <= HELM_OF_TELEPATHY);
X#else
X return(otmp->otyp >= ORCISH_HELM &&
X otmp->otyp <= HELM_OF_TELEPATHY);
X#endif
X}
X
Xboolean
Xis_gloves(otmp) register struct obj *otmp; {
X return(otmp->otyp >= LEATHER_GLOVES &&
X otmp->otyp <= GAUNTLETS_OF_DEXTERITY);
X}
X
Xboolean
Xis_cloak(otmp) register struct obj *otmp; {
X return(otmp->otyp >= MUMMY_WRAPPING &&
X otmp->otyp <= CLOAK_OF_DISPLACEMENT);
X}
X
Xboolean
Xis_shield(otmp) register struct obj *otmp; {
X return(otmp->otyp >= SMALL_SHIELD &&
X otmp->otyp <= SHIELD_OF_REFLECTION);
X}
X
X/*
X * The Type_on() functions should be called *after* setworn().
X * The Type_off() functions call setworn() themselves.
X */
X
Xstatic int
XBoots_on() {
X long oldprop =
X u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~(WORN_BOOTS | TIMEOUT);
X
X switch(uarmf->otyp) {
X case LOW_BOOTS:
X case IRON_SHOES:
X case HIGH_BOOTS:
X case WATER_WALKING_BOOTS:
X case JUMPING_BOOTS:
X break;
X case SPEED_BOOTS:
X if (!oldprop) {
X makeknown(uarmf->otyp);
X You("feel yourself speed up.");
X }
X break;
X case ELVEN_BOOTS:
X if (!oldprop) {
X makeknown(uarmf->otyp);
X You("walk very quietly.");
X }
X break;
X case FUMBLE_BOOTS:
X if (!oldprop)
X Fumbling += rnd(20);
X break;
X case LEVITATION_BOOTS:
X if (!oldprop) {
X makeknown(uarmf->otyp);
X float_up();
X }
X break;
X default: impossible("Unknown type of boots (%d)", uarmf->otyp);
X }
X return 0;
X}
X
Xint
XBoots_off() {
X register struct obj *obj = uarmf;
X /* For levitation, float_down() returns if Levitation, so we
X * must do a setworn() _before_ the levitation case.
X */
X long oldprop =
X u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~(WORN_BOOTS | TIMEOUT);
X
X setworn((struct obj *)0, W_ARMF);
X switch(obj->otyp) {
X case SPEED_BOOTS:
X if (!oldprop) {
X makeknown(obj->otyp);
X You("feel yourself slow down.");
X }
X break;
X case WATER_WALKING_BOOTS:
X if(is_pool(u.ux,u.uy) && !Levitation
X#ifdef POLYSELF
X && !is_flyer(uasmon)
X#endif
X ) {
X makeknown(obj->otyp);
X /* make boots known in case you survive the drowning */
X drown();
X }
X break;
X case ELVEN_BOOTS:
X if (!oldprop) {
X makeknown(obj->otyp);
X You("sure are noisy.");
X }
X break;
X case FUMBLE_BOOTS:
X if (!oldprop)
X Fumbling = 0;
X break;
X case LEVITATION_BOOTS:
X if (!oldprop) {
X (void) float_down();
X makeknown(obj->otyp);
X }
X break;
X case LOW_BOOTS:
X case IRON_SHOES:
X case HIGH_BOOTS:
X case JUMPING_BOOTS:
X break;
X default: impossible("Unknown type of boots (%d)", obj->otyp);
X }
X return 0;
X}
X
Xstatic int
XCloak_on() {
X long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].p_flgs & ~WORN_CLOAK;
X
X switch(uarmc->otyp) {
X case ELVEN_CLOAK:
X case CLOAK_OF_PROTECTION:
X case CLOAK_OF_DISPLACEMENT:
X makeknown(uarmc->otyp);
X break;
X case MUMMY_WRAPPING:
X#ifdef TOLKIEN
X case ORCISH_CLOAK:
X case DWARVISH_CLOAK:
X#endif
X case CLOAK_OF_MAGIC_RESISTANCE:
X break;
X case CLOAK_OF_INVISIBILITY:
X if (!oldprop && !See_invisible && !Blind) {
X makeknown(uarmc->otyp);
X pline("Suddenly you cannot see yourself.");
X }
X break;
X default: impossible("Unknown type of cloak (%d)", uarmc->otyp);
X }
X return 0;
X}
X
Xint
XCloak_off() {
X long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].p_flgs & ~WORN_CLOAK;
X
X switch(uarmc->otyp) {
X case MUMMY_WRAPPING:
X case ELVEN_CLOAK:
X#ifdef TOLKIEN
X case ORCISH_CLOAK:
X case DWARVISH_CLOAK:
X#endif
X case CLOAK_OF_PROTECTION:
X case CLOAK_OF_MAGIC_RESISTANCE:
X case CLOAK_OF_DISPLACEMENT:
X break;
X case CLOAK_OF_INVISIBILITY:
X if (!oldprop && !See_invisible && !Blind) {
X makeknown(uarmc->otyp);
X pline("Suddenly you can see yourself.");
X }
X break;
X default: impossible("Unknown type of cloak (%d)", uarmc->otyp);
X }
X setworn((struct obj *)0, W_ARMC);
X return 0;
X}
X
Xstatic int
XHelmet_on() {
X switch(uarmh->otyp) {
X case FEDORA:
X case HELMET:
X#ifdef TOLKIEN
X case ELVEN_LEATHER_HELM:
X case DWARVISH_IRON_HELM:
X#endif
X case ORCISH_HELM:
X case HELM_OF_TELEPATHY:
X break;
X case HELM_OF_BRILLIANCE:
X if (uarmh->spe) {
X ABON(A_INT) += uarmh->spe;
X ABON(A_WIS) += uarmh->spe;
X flags.botl = 1;
X makeknown(uarmh->otyp);
X }
X break;
X case HELM_OF_OPPOSITE_ALIGNMENT:
X if (u.ualigntyp == U_NEUTRAL) u.ualigntyp = rnd(2) ? -1 : 1;
X else u.ualigntyp = -(u.ualigntyp);
X makeknown(uarmh->otyp);
X flags.botl = 1;
X break;
X default: impossible("Unknown type of helm (%d)", uarmh->otyp);
X }
X return 0;
X}
X
Xint
XHelmet_off() {
X switch(uarmh->otyp) {
X case FEDORA:
X case HELMET:
X#ifdef TOLKIEN
X case ELVEN_LEATHER_HELM:
X case DWARVISH_IRON_HELM:
X#endif
X case ORCISH_HELM:
X case HELM_OF_TELEPATHY:
X break;
X case HELM_OF_BRILLIANCE:
X if (uarmh->spe) {
X ABON(A_INT) -= uarmh->spe;
X ABON(A_WIS) -= uarmh->spe;
X flags.botl = 1;
X }
X break;
X case HELM_OF_OPPOSITE_ALIGNMENT:
X#ifdef THEOLOGY
X u.ualigntyp = u.ualignbase[0];
X#else
X if (pl_character[0] == 'P' ||
X pl_character[0] == 'T' ||
X pl_character[0] == 'W')
X u.ualigntyp = U_NEUTRAL;
X else u.ualigntyp = -(u.ualigntyp);
X#endif
X flags.botl = 1;
X break;
X default: impossible("Unknown type of helm (%d)", uarmh->otyp);
X }
X setworn((struct obj *)0, W_ARMH);
X return 0;
X}
X
Xstatic int
XGloves_on() {
X long oldprop =
X u.uprops[objects[uarmg->otyp].oc_oprop].p_flgs & ~(WORN_GLOVES | TIMEOUT);
X
X switch(uarmg->otyp) {
X case LEATHER_GLOVES:
X break;
X case GAUNTLETS_OF_FUMBLING:
X if (!oldprop)
X Fumbling += rnd(20);
X break;
X case GAUNTLETS_OF_POWER:
X makeknown(uarmg->otyp);
X flags.botl = 1; /* taken care of in attrib.c */
X break;
X case GAUNTLETS_OF_DEXTERITY:
X if (uarmg->spe) makeknown(uarmg->otyp);
X ABON(A_DEX) += uarmg->spe;
X flags.botl = 1;
X break;
X default: impossible("Unknown type of gloves (%d)", uarmg->otyp);
X }
X return 0;
X}
X
Xint
XGloves_off() {
X long oldprop =
X u.uprops[objects[uarmg->otyp].oc_oprop].p_flgs & ~(WORN_GLOVES | TIMEOUT);
X
X switch(uarmg->otyp) {
X case LEATHER_GLOVES:
X break;
X case GAUNTLETS_OF_FUMBLING:
X if (!oldprop)
X Fumbling = 0;
X break;
X case GAUNTLETS_OF_POWER:
X makeknown(uarmg->otyp);
X flags.botl = 1; /* taken care of in attrib.c */
X break;
X case GAUNTLETS_OF_DEXTERITY:
X if (uarmg->spe) makeknown(uarmg->otyp);
X ABON(A_DEX) -= uarmg->spe;
X flags.botl = 1;
X break;
X default: impossible("Unknown type of gloves (%d)", uarmg->otyp);
X }
X setworn((struct obj *)0, W_ARMG);
X return 0;
X}
X
X/*
Xstatic int
XShield_on() {
X switch(uarms->otyp) {
X case SMALL_SHIELD:
X#ifdef TOLKIEN
X case ELVEN_SHIELD:
X case URUK_HAI_SHIELD:
X case ORCISH_SHIELD:
X case DWARVISH_ROUNDSHIELD:
X#endif
X case LARGE_SHIELD:
X case SHIELD_OF_REFLECTION:
X break;
X default: impossible("Unknown type of shield (%d)", uarms->otyp);
X }
X return 0;
X}
X*/
X
Xint
XShield_off() {
X/*
X switch(uarms->otyp) {
X case SMALL_SHIELD:
X#ifdef TOLKIEN
X case ELVEN_SHIELD:
X case URUK_HAI_SHIELD:
X case ORCISH_SHIELD:
X case DWARVISH_ROUNDSHIELD:
X#endif
X case LARGE_SHIELD:
X case SHIELD_OF_REFLECTION:
X break;
X default: impossible("Unknown type of shield (%d)", uarms->otyp);
X }
X*/
X setworn((struct obj *)0, W_ARMS);
X return 0;
X}
X
X/* This must be done in worn.c, because one of the possible intrinsics conferred
X * is fire resistance, and we have to immediately set HFire_resistance in worn.c
X * since worn.c will check it before returning.
Xstatic int
XArmor_on()
X{
X return 0;
X}
X */
X
Xint
XArmor_off()
X{
X setworn((struct obj *)0, W_ARM);
X return 0;
X}
X
X/* The gone functions differ from the off functions in that if you die from
X * taking it off and have life saving, you still die.
X */
Xint
XArmor_gone()
X{
X setnotworn(uarm);
X return 0;
X}
X
Xstatic void
XAmulet_on()
X{
X char buf[BUFSZ];
X
X switch(uamul->otyp) {
X case AMULET_OF_ESP:
X case AMULET_OF_LIFE_SAVING:
X case AMULET_VERSUS_POISON:
X case AMULET_OF_REFLECTION:
X break;
X case AMULET_OF_CHANGE:
X makeknown(AMULET_OF_CHANGE);
X flags.female = !flags.female;
X max_rank_sz();
X /* Don't use same message as polymorph */
X You("are suddenly very %s!", flags.female ? "feminine"
X : "masculine");
X if (pl_character[0]=='P')
X Strcpy(pl_character+6, flags.female? "ess":"");
X if (pl_character[0]=='C')
X Strcpy(pl_character+5, flags.female ? "woman" : "man");
X#ifdef WIZARD
X if (!wizard) {
X#endif
Xnewname: more();
X do {
X pline("What shall you be called, %s? ",
X flags.female ? "madam" : "sir");
X getlin(buf);
X } while (buf[0]=='\033' || buf[0]==0);
X if (!strcmp(plname,buf)) {
X pline("Sorry, that name no longer seems appropriate!");
X goto newname;
X }
X flags.botl = 1;
X (void)strncpy(plname, buf, sizeof(plname)-1);
X Sprintf(SAVEF, "save/%d%s", getuid(), plname);
X regularize(SAVEF+5); /* avoid . or / in name */
X#ifdef WIZARD
X }
X#endif
X pline("The amulet disintegrates!");
X useup(uamul);
X break;
X case AMULET_OF_STRANGULATION:
X makeknown(AMULET_OF_STRANGULATION);
X pline("It constricts your throat!");
X Strangled = 6;
X break;
X case AMULET_OF_RESTFUL_SLEEP:
X Sleeping = rnd(100);
X break;
X case AMULET_OF_YENDOR:
X break;
X }
X}
X
Xvoid
XAmulet_off()
X{
X switch(uamul->otyp) {
X case AMULET_OF_ESP:
X case AMULET_OF_LIFE_SAVING:
X case AMULET_VERSUS_POISON:
X case AMULET_OF_REFLECTION:
X break;
X case AMULET_OF_CHANGE:
X impossible("Wearing an amulet of change?");
X break;
X case AMULET_OF_STRANGULATION:
X if (Strangled) {
X You("can breathe more easily!");
X Strangled = 0;
X }
X break;
X case AMULET_OF_RESTFUL_SLEEP:
X Sleeping = 0;
X break;
X case AMULET_OF_YENDOR:
X break;
X }
X setworn((struct obj *)0, W_AMUL);
X}
X
Xvoid
XRing_on(obj)
Xregister struct obj *obj;
X{
X long oldprop = u.uprops[objects[obj->otyp].oc_oprop].p_flgs & ~W_RING;
X
X switch(obj->otyp){
X case RIN_TELEPORTATION:
X case RIN_REGENERATION:
X case RIN_SEARCHING:
X case RIN_STEALTH:
X case RIN_HUNGER:
X case RIN_AGGRAVATE_MONSTER:
X case RIN_POISON_RESISTANCE:
X case RIN_FIRE_RESISTANCE:
X case RIN_COLD_RESISTANCE:
X case RIN_SHOCK_RESISTANCE:
X case RIN_CONFLICT:
X case RIN_WARNING:
X case RIN_TELEPORT_CONTROL:
X#ifdef POLYSELF
X case RIN_POLYMORPH:
X case RIN_POLYMORPH_CONTROL:
X#endif
X break;
X case RIN_SEE_INVISIBLE:
X if (Invisible && !Blind) {
X newsym(u.ux,u.uy);
X pline("Suddenly you can see yourself.");
X makeknown(RIN_SEE_INVISIBLE);
X }
X break;
X case RIN_INVISIBILITY:
X if (!oldprop && !See_invisible && !Blind) {
X makeknown(RIN_INVISIBILITY);
X Your("body takes on a %s transparency...",
X Hallucination ? "normal" : "strange");
X }
X case RIN_ADORNMENT:
X ABON(A_CHA) += obj->spe;
X flags.botl = 1;
X if (obj->spe || objects[RIN_ADORNMENT].oc_name_known) {
X makeknown(RIN_ADORNMENT);
X obj->known = 1;
X }
X break;
X case RIN_LEVITATION:
X if(!oldprop) {
X float_up();
X makeknown(RIN_LEVITATION);
X obj->known = 1;
X }
X break;
X case RIN_GAIN_STRENGTH:
X ABON(A_STR) += obj->spe;
X flags.botl = 1;
X if (obj->spe || objects[RIN_GAIN_STRENGTH].oc_name_known) {
X makeknown(RIN_GAIN_STRENGTH);
X obj->known = 1;
X }
X break;
X case RIN_INCREASE_DAMAGE:
X u.udaminc += obj->spe;
X break;
X case RIN_PROTECTION_FROM_SHAPE_CHAN:
X rescham();
X break;
X case RIN_PROTECTION:
X flags.botl = 1;
X if (obj->spe || objects[RIN_PROTECTION].oc_name_known) {
X makeknown(RIN_PROTECTION);
X obj->known = 1;
X }
X break;
X }
X}
X
Xstatic void
XRing_off_or_gone(obj,gone)
Xregister struct obj *obj;
Xboolean gone;
X{
X register long mask = obj->owornmask & W_RING;
X
X if(!(u.uprops[objects[obj->otyp].oc_oprop].p_flgs & mask))
X impossible("Strange... I didn't know you had that ring.");
X if(gone) setnotworn(obj);
X else setworn((struct obj *)0, obj->owornmask);
X switch(obj->otyp) {
X case RIN_TELEPORTATION:
X case RIN_REGENERATION:
X case RIN_SEARCHING:
X case RIN_STEALTH:
X case RIN_HUNGER:
X case RIN_AGGRAVATE_MONSTER:
X case RIN_POISON_RESISTANCE:
X case RIN_FIRE_RESISTANCE:
X case RIN_COLD_RESISTANCE:
X case RIN_SHOCK_RESISTANCE:
X case RIN_CONFLICT:
X case RIN_WARNING:
X case RIN_TELEPORT_CONTROL:
X#ifdef POLYSELF
X case RIN_POLYMORPH:
X case RIN_POLYMORPH_CONTROL:
X#endif
X break;
X case RIN_SEE_INVISIBLE:
X if (Invisible && !Blind) {
X pline("Suddenly you cannot see yourself.");
X makeknown(RIN_SEE_INVISIBLE);
X }
X break;
X case RIN_INVISIBILITY:
X if (!(Invisible & ~W_RING) && !See_invisible && !Blind) {
X Your("body seems to unfade...");
X makeknown(RIN_INVISIBILITY);
X }
X break;
X case RIN_ADORNMENT:
X ABON(A_CHA) -= obj->spe;
X flags.botl = 1;
X break;
X case RIN_LEVITATION:
X (void) float_down();
X if (!Levitation) makeknown(RIN_LEVITATION);
X break;
X case RIN_GAIN_STRENGTH:
X ABON(A_STR) -= obj->spe;
X flags.botl = 1;
X break;
X case RIN_INCREASE_DAMAGE:
X u.udaminc -= obj->spe;
X break;
X case RIN_PROTECTION_FROM_SHAPE_CHAN:
X /* If you're no longer protected, let the chameleons
X * change shape again -dgk
X */
X restartcham();
X break;
X }
X}
X
Xvoid
XRing_off(obj)
Xstruct obj *obj;
X{
X Ring_off_or_gone(obj,FALSE);
X}
X
Xvoid
XRing_gone(obj)
Xstruct obj *obj;
X{
X Ring_off_or_gone(obj,TRUE);
X}
X
Xvoid
XBlindf_on(otmp)
Xregister struct obj *otmp;
X{
X setworn(otmp, W_TOOL);
X on_msg(otmp);
X seeoff(0);
X}
X
Xvoid
XBlindf_off(otmp)
Xregister struct obj *otmp;
X{
X setworn((struct obj *)0, otmp->owornmask);
X off_msg(otmp);
X if (!Blinded) make_blinded(1L,FALSE); /* See on next move */
X else You("still cannot see.");
X}
X
X/* called in main to set intrinsics of worn start-up items */
Xvoid
Xset_wear() {
X/* if (uarm) (void) Armor_on(); */
X if (uarmc) (void) Cloak_on();
X if (uarmf) (void) Boots_on();
X if (uarmg) (void) Gloves_on();
X if (uarmh) (void) Helmet_on();
X/* if (uarms) (void) Shield_on(); */
X}
X
Xstatic const char clothes[] = {ARMOR_SYM, 0};
Xstatic const char accessories[] = {RING_SYM, AMULET_SYM, TOOL_SYM, 0};
X
Xint
Xdotakeoff() {
X register struct obj *otmp;
X int armorpieces = 0;
X
X#define MOREARM(x) if (x) { armorpieces++; otmp = x; }
X MOREARM(uarmh);
X MOREARM(uarms);
X MOREARM(uarmg);
X MOREARM(uarmf);
X if (uarmc) {
X armorpieces++;
X otmp = uarmc;
X } else if (uarm) {
X armorpieces++;
X otmp = uarm;
X#ifdef SHIRT
X } else if (uarmu) {
X armorpieces++;
X otmp = uarmu;
X#endif
X }
X if (!armorpieces) {
X pline("Not wearing any armor.");
X return 0;
X }
X if (armorpieces > 1)
X otmp = getobj(clothes, "take off");
X if (otmp == 0) return(0);
X if (!(otmp->owornmask & W_ARMOR)) {
X You("are not wearing that.");
X return(0);
X }
X if (((otmp == uarm) && (uarmc))
X#ifdef SHIRT
X || ((otmp == uarmu) && (uarmc || uarm))
X#endif
X ) {
X You("can't take that off.");
X return(0);
X }
X if(otmp == uarmg && uwep && uwep->cursed) { /* myers@uwmacc */
X You("seem unable to take off the gloves while holding your %s.",
X is_sword(uwep) ? "sword" : "weapon");
X uwep->bknown = 1;
X return(0);
X }
X if(otmp == uarmg && Glib) {
X You("can't remove the slippery gloves with your slippery fingers.");
X return(0);
X }
X if(otmp == uarmf && u.utrap && u.utraptype == TT_BEARTRAP) { /* -3. */
X pline("The bear trap prevents you from pulling your foot out.");
X return(0);
X }
X (void) armoroff(otmp);
X return(1);
X}
X
Xint
Xdoremring() {
X register struct obj *otmp;
X int Accessories = 0;
X
X#define MOREACC(x) if (x) { Accessories++; otmp = x; }
X MOREACC(uleft);
X MOREACC(uright);
X MOREACC(uamul);
X MOREACC(ublindf);
X
X if(!Accessories) {
X pline("Not wearing any accessories.");
X return(0);
X }
X if (Accessories != 1) otmp = getobj(accessories, "take off");
X if(!otmp) return(0);
X if(!(otmp->owornmask & (W_RING | W_AMUL | W_TOOL))) {
X You("are not wearing that.");
X return(0);
X }
X if(cursed(otmp)) return(0);
X if(otmp->olet == RING_SYM) {
X#ifdef POLYSELF
X if (nolimbs(uasmon)) {
X pline("It seems to be stuck.");
X return(0);
X }
X#endif
X if (uarmg && uarmg->cursed) {
X uarmg->bknown = 1;
XYou("seem unable to remove your ring without taking off your gloves.");
X return(0);
X }
X if (welded(uwep) && bimanual(uwep)) {
X uwep->bknown = 1;
XYou("seem unable to remove the ring while your hands hold your %s.",
X is_sword(uwep) ? "sword" : "weapon");
X return(0);
X }
X if (welded(uwep) && otmp==uright) {
X uwep->bknown = 1;
XYou("seem unable to remove the ring while your right hand holds your %s.",
X is_sword(uwep) ? "sword" : "weapon");
X return(0);
X }
X /* Sometimes we want to give the off_msg before removing and
X * sometimes after; for instance, "you were wearing a moonstone
X * ring (on right hand)" is desired but "you were wearing a
X * square amulet (being worn)" is not because of the redundant
X * "being worn".
X */
X off_msg(otmp);
X Ring_off(otmp);
X } else if(otmp->olet == AMULET_SYM) {
X Amulet_off();
X off_msg(otmp);
X } else Blindf_off(otmp); /* does its own off_msg */
X return(1);
X}
X
Xint
Xcursed(otmp) register struct obj *otmp; {
X /* Curses, like chickens, come home to roost. */
X if(otmp->cursed){
X You("can't. %s to be cursed.",
X (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1)
X ? "They seem" : "It seems");
X otmp->bknown = 1;
X return(1);
X }
X return(0);
X}
X
Xint
Xarmoroff(otmp) register struct obj *otmp; {
X register int delay = -objects[otmp->otyp].oc_delay;
X
X if(cursed(otmp)) return(0);
X if(delay) {
X nomul(delay);
X if (is_helmet(otmp)) {
X nomovemsg = "You finish taking off your helmet.";
X afternmv = Helmet_off;
X }
X else if (is_gloves(otmp)) {
X nomovemsg = "You finish taking off your gloves.";
X afternmv = Gloves_off;
X }
X else if (is_boots(otmp)) {
X nomovemsg = "You finish taking off your boots.";
X afternmv = Boots_off;
X }
X else {
X nomovemsg = "You finish taking off your suit.";
X afternmv = Armor_off;
X }
X } else {
X /* Be warned! We want off_msg after removing the item to
X * avoid "You were wearing ____ (being worn)." However, an
X * item which grants fire resistance might cause some trouble
X * if removed in Hell and lifesaving puts it back on; in this
X * case the message will be printed at the wrong time (after
X * the messages saying you died and were lifesaved). Luckily,
X * no cloak, shield, or fast-removable armor grants fire
X * resistance, so we can safely do the off_msg afterwards.
X * Rings do grant fire resistance, but for rings we want the
X * off_msg before removal anyway so there's no problem. Take
X * care in adding armors granting fire resistance; this code
X * might need modification.
X */
X if(is_cloak(otmp))
X (void) Cloak_off();
X else if(is_shield(otmp))
X (void) Shield_off();
X else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
X off_msg(otmp);
X }
X return(1);
X}
X
Xint
Xdowear() {
X register struct obj *otmp;
X register int delay;
X register int err = 0;
X long mask = 0;
X
X#ifdef POLYSELF
X /* cantweararm checks for suits of armor */
X /* verysmall or nohands checks for shields, gloves, etc... */
X if ((verysmall(uasmon) || nohands(uasmon))) {
X pline("Don't even bother.");
X return(0);
X }
X#endif
X otmp = getobj(clothes, "wear");
X if(!otmp) return(0);
X#ifdef POLYSELF
X if (cantweararm(uasmon) && !is_shield(otmp) &&
X !is_helmet(otmp) && !is_gloves(otmp) &&
X !is_boots(otmp)) {
X pline("The %s will not fit on your body.",
X is_cloak(otmp) ? "cloak" :
X# ifdef SHIRT
X otmp->otyp == HAWAIIAN_SHIRT ? "shirt" :
X# endif
X "suit");
X return(0);
X }
X#endif
X if(otmp->owornmask & W_ARMOR) {
X You("are already wearing that!");
X return(0);
X }
X if(is_helmet(otmp)) {
X if(uarmh) {
X You("are already wearing a helmet.");
X err++;
X } else
X mask = W_ARMH;
X } else if(is_shield(otmp)){
X if(uarms) {
X You("are already wearing a shield.");
X err++;
X }
X if(uwep && bimanual(uwep)) {
X You("cannot hold a shield and wield a two-handed %s.",
X is_sword(uwep) ? "sword" : "weapon");
X err++;
X }
X if(!err) mask = W_ARMS;
X } else if(is_boots(otmp)) {
X if(uarmf) {
X You("are already wearing boots.");
X err++;
X } else
X mask = W_ARMF;
X } else if(is_gloves(otmp)) {
X if(uarmg) {
X You("are already wearing gloves.");
X err++;
X } else
X if(uwep && uwep->cursed) {
X You("cannot wear gloves over your %s.",
X is_sword(uwep) ? "sword" : "weapon");
X err++;
X } else
X mask = W_ARMG;
X#ifdef SHIRT
X } else if( otmp->otyp == HAWAIIAN_SHIRT ) {
X if (uarm || uarmc || uarmu) {
X if(!uarm && !uarmc) /* then uarmu */
X You("are already wearing a shirt.");
X else
X You("can't wear that over your %s.",
X (uarm && !uarmc) ? "armor" : "cloak");
X err++;
X } else
X mask = W_ARMU;
X#endif
X } else if(is_cloak(otmp)) {
X if(uarmc) {
X You("are already wearing a cloak.");
X err++;
X } else
X mask = W_ARMC;
X } else {
X if(uarmc) {
X You("cannot wear armor over a cloak.");
X err++;
X } else if(uarm) {
X You("are already wearing some armor.");
X err++;
X }
X if(!err) mask = W_ARM;
X }
X/* Unnecessary since now only weapons and special items like pick-axes get
X * welded to your hand, not armor
X if(welded(otmp)) {
X if(!err++)
X weldmsg(otmp, FALSE);
X }
X */
X if(err) return(0);
X
X otmp->known = 1;
X if(otmp == uwep)
X setuwep((struct obj *)0);
X setworn(otmp, mask);
X delay = -objects[otmp->otyp].oc_delay;
X if(delay){
X nomul(delay);
X if(is_boots(otmp)) afternmv = Boots_on;
X if(is_helmet(otmp)) afternmv = Helmet_on;
X if(is_gloves(otmp)) afternmv = Gloves_on;
X/* if(otmp == uarm) afternmv = Armor_on; */
X nomovemsg = "You finish your dressing maneuver.";
X } else {
X if(is_cloak(otmp)) (void) Cloak_on();
X/* if(is_shield(otmp)) (void) Shield_on(); */
X on_msg(otmp);
X }
X return(1);
X}
X
Xint
Xdoputon() {
X register struct obj *otmp;
X long mask = 0;
X
X if(uleft && uright && uamul && ublindf) {
X#ifdef POLYSELF
X Your("%s%s are full, and you're already wearing an amulet and a blindfold.",
X (humanoid(uasmon) || u.usym==S_CENTAUR) ? "ring-" : "",
X makeplural(body_part(FINGER)));
X#else
X Your("ring-fingers are full, and you're already wearing an amulet and a blindfold.");
X#endif
X return(0);
X }
X otmp = getobj(accessories, "wear");
X if(!otmp) return(0);
X if(otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) {
X You("are already wearing that!");
X return(0);
X }
X if(welded(otmp)) {
X weldmsg(otmp, TRUE);
X return(0);
X }
X if(otmp == uwep)
X setuwep((struct obj *)0);
X if(otmp->olet == RING_SYM) {
X#ifdef POLYSELF
X if(nolimbs(uasmon)) {
X You("cannot make the ring stick to your body.");
X return(0);
X }
X#endif
X if(uleft && uright){
X#ifdef POLYSELF
X pline("There are no more %s%s to fill.",
X (humanoid(uasmon) || u.usym==S_CENTAUR)
X ? "ring-" : "",
X makeplural(body_part(FINGER)));
X#else
X pline("There are no more ring-fingers to fill.");
X#endif
X return(0);
X }
X if(uleft) mask = RIGHT_RING;
X else if(uright) mask = LEFT_RING;
X else do {
X char answer;
X
X#ifdef POLYSELF
X pline("What %s%s, Right or Left? ",
X (humanoid(uasmon) || u.usym==S_CENTAUR)
X ? "ring-" : "",
X body_part(FINGER));
X#else
X pline("What ring-finger, Right or Left? ");
X#endif
X if(index(quitchars, (answer = readchar())))
X return(0);
X switch(answer){
X case 'l':
X case 'L':
X mask = LEFT_RING;
X break;
X case 'r':
X case 'R':
X mask = RIGHT_RING;
X break;
X }
X } while(!mask);
X if (uarmg && uarmg->cursed) {
X uarmg->bknown = 1;
X You("cannot remove your gloves to put on the ring.");
X return(0);
X }
X if (welded(uwep) && bimanual(uwep)) {
X /* welded will set bknown */
X You("cannot free your weapon hands to put on the ring.");
X return(0);
X }
X if (welded(uwep) && mask==RIGHT_RING) {
X /* welded will set bknown */
X You("cannot free your weapon hand to put on the ring.");
X return(0);
X }
X setworn(otmp, mask);
X Ring_on(otmp);
X } else if (otmp->olet == AMULET_SYM) {
X if(uamul) {
X You("are already wearing an amulet.");
X return(0);
X }
X setworn(otmp, W_AMUL);
X if (otmp->otyp == AMULET_OF_CHANGE) {
X Amulet_on();
X /* Don't do a prinv() since the amulet is now gone */
X return(1);
X }
X Amulet_on();
X } else { /* it's a blindfold */
X if (ublindf) {
X You("are already wearing a blindfold.");
X return(0);
X }
X if (otmp->otyp != BLINDFOLD) {
X You("can't wear that!");
X return(0);
X }
X Blindf_on(otmp);
X return(1);
X }
X prinv(otmp);
X return(1);
X}
X
Xvoid
Xfind_ac() {
X register int uac = 10;
X#ifdef POLYSELF
X if (u.mtimedone) uac = mons[u.umonnum].ac;
X#endif
X if(uarm) uac -= ARM_BONUS(uarm);
X if(uarmc) uac -= ARM_BONUS(uarmc);
X if(uarmh) uac -= ARM_BONUS(uarmh);
X if(uarmf) uac -= ARM_BONUS(uarmf);
X if(uarms) uac -= ARM_BONUS(uarms);
X if(uarmg) uac -= ARM_BONUS(uarmg);
X#ifdef SHIRT
X if(uarmu) uac -= ARM_BONUS(uarmu);
X#endif
X if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
X if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
X#ifdef THEOLOGY
X if (Protection & INTRINSIC) uac -= u.ublessed;
X#endif
X if(uac != u.uac){
X u.uac = uac;
X flags.botl = 1;
X }
X}
X
Xvoid
Xglibr(){
Xregister struct obj *otmp;
Xint xfl = 0;
X if(!uarmg) if(uleft || uright)
X#ifdef POLYSELF
X if(!nolimbs(uasmon))
X#endif
X {
X /* Note: at present also cursed rings fall off */
X /* changed 10/30/86 by GAN */
X Your("%s off your %s.",
X#ifdef HARD
X ((uleft && !uleft->cursed) && (uright && !uright->cursed)) ? "rings slip" : "ring slips",
X#else
X (uleft && uright) ? "rings slip" : "ring slips",
X#endif
X makeplural(body_part(FINGER)));
X xfl++;
X if((otmp = uleft) != (struct obj *)0){
X Ring_off(uleft);
X dropx(otmp);
X }
X if((otmp = uright) != (struct obj *)0){
X Ring_off(uright);
X dropx(otmp);
X }
X }
X if(((otmp = uwep) != (struct obj *)0)
X#ifdef HARD
X && !otmp->cursed
X#endif
X ) {
X /* Note: at present also cursed weapons fall */
X /* changed 10/30/86 by GAN */
X Your("%s %sslips from your %s.",
X is_sword(uwep) ? "sword" : "weapon",
X xfl ? "also " : "",
X makeplural(body_part(HAND)));
X setuwep((struct obj *)0);
X dropx(otmp);
X }
X}
X
Xstruct obj *
Xsome_armor(){
Xregister struct obj *otmph = (uarmc ? uarmc : uarm);
X if(uarmh && (!otmph || !rn2(4))) otmph = uarmh;
X if(uarmg && (!otmph || !rn2(4))) otmph = uarmg;
X if(uarmf && (!otmph || !rn2(4))) otmph = uarmf;
X if(uarms && (!otmph || !rn2(4))) otmph = uarms;
X#ifdef SHIRT
X if(!uarm && !uarmc && uarmu && (!otmph || !rn2(4))) otmph = uarmu;
X#endif
X return(otmph);
X}
X
Xvoid
Xcorrode_armor(){
Xregister struct obj *otmph = some_armor();
X
X if (otmph && otmph != uarmf) {
X if (otmph->rustfree || objects[otmph->otyp].oc_material != METAL ||
X otmph->otyp >= LEATHER_ARMOR) {
X Your("%s not affected!",
X aobjnam(otmph, "are"));
X return;
X }
X Your("%s!", aobjnam(otmph, "corrode"));
X otmph->spe--;
X adj_abon(otmph, -1);
X }
X}
X
Xstatic int
Xselect_off(otmp)
Xregister struct obj *otmp;
X{
X if(!otmp) return(0);
X if(cursed(otmp)) return(0);
X#ifdef POLYSELF
X if(otmp->olet==RING_SYM && nolimbs(uasmon)) return(0);
X#endif
X if(welded(uwep) && (otmp==uarmg || otmp==uright || (otmp==uleft
X && bimanual(uwep))))
X return(0);
X if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) {
X uarmg->bknown = 1;
X return(0);
X }
X if((otmp==uarm
X#ifdef SHIRT
X || otmp==uarmu
X#endif
X ) && uarmc && uarmc->cursed) {
X uarmc->bknown = 1;
X return(0);
X }
X#ifdef SHIRT
X if(otmp==uarmu && uarm && uarm->cursed) {
X uarm->bknown = 1;
X return(0);
X }
X#endif
X
X if(otmp == uarm) takeoff_mask |= WORN_ARMOR;
X else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK;
X else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS;
X else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES;
X else if(otmp == uarmh) takeoff_mask |= WORN_HELMET;
X else if(otmp == uarms) takeoff_mask |= WORN_SHIELD;
X#ifdef SHIRT
X else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
X#endif
X else if(otmp == uleft) takeoff_mask |= LEFT_RING;
X else if(otmp == uright) takeoff_mask |= RIGHT_RING;
X else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
X else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
X else if(otmp == uwep) takeoff_mask |= 1L; /* WIELDED_WEAPON */
X
X else impossible("select_off: %s???", doname(otmp));
X
X return(0);
X}
X
Xstatic struct obj *
Xdo_takeoff() {
X
X register struct obj *otmp = 0;
X
X if (taking_off == 1L) { /* weapon */
X if(!cursed(uwep)) {
X setuwep((struct obj *) 0);
X You("are empty %s.", body_part(HANDED));
X }
X } else if (taking_off == WORN_ARMOR) {
X otmp = uarm;
X if(!cursed(otmp)) (void) Armor_off();
X } else if (taking_off == WORN_CLOAK) {
X otmp = uarmc;
X if(!cursed(otmp)) (void) Cloak_off();
X } else if (taking_off == WORN_BOOTS) {
X otmp = uarmf;
X if(!cursed(otmp)) (void) Boots_off();
X } else if (taking_off == WORN_GLOVES) {
X otmp = uarmg;
X if(!cursed(otmp)) (void) Gloves_off();
X } else if (taking_off == WORN_HELMET) {
X otmp = uarmh;
X if(!cursed(otmp)) (void) Helmet_off();
X } else if (taking_off == WORN_SHIELD) {
X otmp = uarms;
X if(!cursed(otmp)) (void) Shield_off();
X#ifdef SHIRT
X } else if (taking_off == WORN_SHIRT) {
X otmp = uarmu;
X if(!cursed(otmp))
X setworn((struct obj *)0, uarmu->owornmask & W_ARMOR);
X#endif
X } else if (taking_off == WORN_AMUL) {
X otmp = uamul;
X if(!cursed(otmp)) Amulet_off();
X } else if (taking_off == LEFT_RING) {
X otmp = uleft;
X if(!cursed(otmp)) Ring_off(uleft);
X } else if (taking_off == RIGHT_RING) {
X otmp = uright;
X if(!cursed(otmp)) Ring_off(uright);
X } else if (taking_off == WORN_BLINDF) {
X if(!cursed(ublindf)) {
X setworn((struct obj *)0, ublindf->owornmask);
X if(!Blinded) make_blinded(1L,FALSE); /* See on next move */
X else You("still cannot see.");
X }
X } else impossible("do_takeoff: taking off %lx", taking_off);
X
X return(otmp);
X}
X
Xstatic int
Xtake_off() {
X
X register int i;
X register struct obj *otmp;
X
X if(taking_off) {
X if(todelay > 0) {
X
X todelay--;
X return(1); /* still busy */
X } else if((otmp = do_takeoff())) off_msg(otmp);
X
X takeoff_mask &= ~taking_off;
X taking_off = 0L;
X }
X
X for(i = 0; takeoff_order[i]; i++)
X if(takeoff_mask & takeoff_order[i]) {
X
X taking_off = takeoff_order[i];
X break;
X }
X
X otmp = (struct obj *) 0;
X
X if (taking_off == 0L) {
X You("finish disrobing.");
X return 0;
X } else if (taking_off == 1L) {
X todelay = 1;
X } else if (taking_off == WORN_ARMOR) {
X otmp = uarm;
X } else if (taking_off == WORN_CLOAK) {
X otmp = uarmc;
X } else if (taking_off == WORN_BOOTS) {
X otmp = uarmf;
X } else if (taking_off == WORN_GLOVES) {
X otmp = uarmg;
X } else if (taking_off == WORN_HELMET) {
X otmp = uarmh;
X } else if (taking_off == WORN_SHIELD) {
X otmp = uarms;
X#ifdef SHIRT
X } else if (taking_off == WORN_SHIRT) {
X otmp = uarmu;
X#endif
X } else if (taking_off == WORN_AMUL) {
X todelay = 1;
X } else if (taking_off == LEFT_RING) {
X todelay = 1;
X } else if (taking_off == RIGHT_RING) {
X todelay = 1;
X } else if (taking_off == WORN_BLINDF) {
X todelay = 2;
X } else {
X impossible("take_off: taking off %lx", taking_off);
X return 0; /* force done */
X }
X
X if(otmp) todelay = objects[otmp->otyp].oc_delay;
X set_occupation(take_off, "disrobing", 0);
X return(1); /* get busy */
X}
X
Xint
Xdoddoremarm() {
X
X if(taking_off || takeoff_mask) {
X
X You("continue disrobing.");
X set_occupation(take_off, "disrobing", 0);
X return(take_off());
X }
X
X (void) ggetobj("take off", select_off, 0);
X if(takeoff_mask) return(take_off());
X else return(0);
X}
X
Xvoid
Xadj_abon(otmp, delta)
Xregister struct obj *otmp;
Xregister schar delta;
X{
X if (uarmg && otmp->otyp == GAUNTLETS_OF_DEXTERITY) {
X ABON(A_DEX) += (delta);
X flags.botl = 1;
X }
X if (uarmh && otmp->otyp == HELM_OF_BRILLIANCE) {
X ABON(A_INT) += (delta);
X ABON(A_WIS) += (delta);
X flags.botl = 1;
X }
X}
END_OF_FILE
if test 32041 -ne `wc -c <'src/do_wear.c'`; then
echo shar: \"'src/do_wear.c'\" unpacked with wrong size!
fi
# end of 'src/do_wear.c'
fi
echo shar: End of archive 12 \(of 38\).
cp /dev/null ark12isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 38 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0