hartl@lan.informatik.tu-muenchen.dbp.de (Anton Hartl) (08/12/88)
Nethack Bug Fixes + Enhancements ================================ 1) BUG+FIX: If a nymph has stolen your badge/leash/blindfold (when applied) it remains applied. :-( 2) ENHANCEMENT: To make the wand of probing and the stethoscope more useful (i.e. after a gremlin has sucked you :-(), the routine ustatusline now prints information about acquired attributes such as fire/cold/poison resistance. #define ATTRIBUTEPROBING in config.h if you want to know more about yourself. 3) ENHANCEMENT: Had you ever a fantastic game? And just in that moment nethack crashed? Or your machine crashed? @#$%^&* Here is the *solution*! With our patches applied, you will be able to restore those games on the last level you left. :-) #define ANTICRASH in config.h if you want to be resurrected. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Anton "Ulysses" Hartl hartl@tumult.informatik.tu-muenchen.de (ARPA) ...{!uunet,!unido}!tumult!hartl (UUCP) Only those who attempt the absurd will achieve the impossible. ------------------------------------------------------------------------------- Franz "Oin" Schmausser schmauss@lan.informatik.tu-muenchen.dbp.de schmauss%lan.informatik.tu-muenchen.dbp.de@{relay.cs.net,unido.uucp} Monsters come from nowhere to hit YOU everywhere. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dept. of Computer Science, Technical University of Munich, Bavaria ---- snip ----- snip ----- snip ----- snip ----- snip ----- snip ----- snip --- *** config.h.orig Fri Aug 12 10:18:38 1988 --- config.h Fri Aug 12 10:24:56 1988 *************** *** 231,236 #define THEOLOGY /* Smarter gods - The Unknown Hacker */ #define STOOGES /* Three wild and crazy guys - Bruce Mewborne */ #define SINKS /* Kitchen sinks - Janet Walz */ #ifdef MSDOS #define TERMLIB /* enable use of termcap file c:\etc\termcap */ --- 231,238 ----- #define THEOLOGY /* Smarter gods - The Unknown Hacker */ #define STOOGES /* Three wild and crazy guys - Bruce Mewborne */ #define SINKS /* Kitchen sinks - Janet Walz */ + #define ANTICRASH /* anti crash facility by Oin & Ulysses */ + #define ATTRIBUTEPROBING /* Enhanced probing code by Oin & Ulysses */ #ifdef MSDOS #define TERMLIB /* enable use of termcap file c:\etc\termcap */ *** lev.c.orig Fri Aug 12 10:18:39 1988 --- lev.c Fri Aug 12 10:23:23 1988 *************** *** 12,17 extern int hackpid; extern xchar dlevel; extern char nul[]; #ifndef NOWORM #include "wseg.h" --- 12,25 ----- extern int hackpid; extern xchar dlevel; extern char nul[]; + #ifdef ANTICRASH + extern char save_game; + extern char crash_recover; + extern struct permonst pm_wizard; + extern char pl_character[PL_CSIZ]; + extern char fut_geno[60], genocided[60]; + static boolean freechain = TRUE; + #endif #ifndef NOWORM #include "wseg.h" *************** *** 106,111 #ifdef DGK if (count_only) return(0); #endif billobjs = 0; fgold = 0; ftrap = 0; --- 114,159 ----- #ifdef DGK if (count_only) return(0); #endif + + #ifdef ANTICRASH + if (!save_game) + { + int tmp; + + glo(-1); + if ((fd = creat(lock, 0644)) < 0) + { + done("tricked"); + } + freechain = FALSE; + saveobjchn(fd, invent); + saveobjchn(fd, fcobj); + savemonchn(fd, fallen_down); + freechain = TRUE; + tmp = getuid(); + bwrite(fd, (char *) &tmp, sizeof tmp); + bwrite(fd, (char *) &flags, sizeof(struct flag)); + bwrite(fd, (char *) &dlevel, sizeof dlevel); + bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel); + bwrite(fd, (char *) level_exists, sizeof level_exists); + bwrite(fd, (char *) &moves, sizeof moves); + bwrite(fd, (char *) &u, sizeof(struct you)); + #ifdef SPELLS + bwrite(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); + #endif + if(u.ustuck) + bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id); + bwrite(fd, (char *) pl_character, sizeof pl_character); + bwrite(fd, (char *) genocided, sizeof genocided); + bwrite(fd, (char *) fut_geno, sizeof fut_geno); + #ifdef HARD + bwrite(fd, (char *) &pm_wizard, sizeof(struct permonst)); + #endif + savenames(fd); + close(fd); + } + #endif /* ANTICRASH */ + billobjs = 0; fgold = 0; ftrap = 0; *************** *** 143,148 #ifdef DGK if (!count_only) #endif free((char *) otmp); otmp = otmp2; } --- 191,199 ----- #ifdef DGK if (!count_only) #endif + #ifdef ANTICRASH + if (freechain) + #endif free((char *) otmp); otmp = otmp2; } *************** *** 166,171 bwrite(fd, (char *) &xl, sizeof(int)); bwrite(fd, (char *) mtmp, xl + sizeof(struct monst)); if(mtmp->minvent) saveobjchn(fd,mtmp->minvent); free((char *) mtmp); mtmp = mtmp2; } --- 217,225 ----- bwrite(fd, (char *) &xl, sizeof(int)); bwrite(fd, (char *) mtmp, xl + sizeof(struct monst)); if(mtmp->minvent) saveobjchn(fd,mtmp->minvent); + #ifdef ANTICRASH + if (freechain) + #endif free((char *) mtmp); mtmp = mtmp2; } *** pri.c.orig Fri Aug 12 10:18:39 1988 --- pri.c Fri Aug 12 10:23:23 1988 *************** *** 482,487 # else u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac); # endif } #endif --- 482,510 ----- # else u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac); # endif + #ifdef ATTRIBUTEPROBING + pline + ( + "Your attributes are: %s%s%s%s%s%s%s%sprotection %+d", + ((HPoison_resistance & INTRINSIC) == INTRINSIC) + ? "poison resistance " : "", + ((HFire_resistance & INTRINSIC) == INTRINSIC) + ? "fire resistance " : "", + ((HCold_resistance & INTRINSIC) == INTRINSIC) + ? "cold resistance " : "", + ((HInvis & INTRINSIC) == INTRINSIC) + ? "invisibility " : "", + ((HSee_invisible & INTRINSIC) == INTRINSIC) + ? "see invisibles " : "", + ((Stealth & INTRINSIC) == INTRINSIC) + ? "stealth " : "", + ((Fast & INTRINSIC) == INTRINSIC) + ? "speed " : "", + ((HTelepat & INTRINSIC) == INTRINSIC) + ? "telepathy " : "", + Protection ? u.ublessed : 0 + ); + #endif } #endif *** steal.c.orig Fri Aug 12 10:18:39 1988 --- steal.c Fri Aug 12 10:23:23 1988 *************** *** 77,83 } tmp = 0; for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) ! tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1); tmp = rn2(tmp); for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1)) --- 77,83 ----- } tmp = 0; for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) ! tmp += ((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL)) ? 5 : 1); tmp = rn2(tmp); for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL)) ? 5 : 1)) *************** *** 80,86 tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1); tmp = rn2(tmp); for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) ! if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1)) < 0) break; if(!otmp) { impossible("Steal fails!"); --- 80,86 ----- tmp += ((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL)) ? 5 : 1); tmp = rn2(tmp); for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) ! if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL)) ? 5 : 1)) < 0) break; if(!otmp) { impossible("Steal fails!"); *************** *** 88,94 } if(otmp->o_id == stealoid) return(0); ! if((otmp->owornmask & (W_ARMOR | W_RING))){ switch(otmp->olet) { case RING_SYM: ringoff(otmp); --- 88,94 ----- } if(otmp->o_id == stealoid) return(0); ! if((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL))){ switch(otmp->olet) { case TOOL_SYM: switch(otmp->otyp){ *************** *** 90,95 return(0); if((otmp->owornmask & (W_ARMOR | W_RING))){ switch(otmp->olet) { case RING_SYM: ringoff(otmp); break; --- 90,117 ----- return(0); if((otmp->owornmask & (W_ARMOR | W_RING | W_TOOL))){ switch(otmp->olet) { + case TOOL_SYM: + switch(otmp->otyp){ + case BLINDFOLD: + if (Blindfolded && otmp->owornmask) { + Blindfolded = 0; + otmp->owornmask = 0; + if (!Blinded) + Blinded = 1; /* see on nexte */ + } + break; + + case BADGE: + if (Badged && otmp->owornmask) { + Badged = 0; + otmp->owornmask = 0; + } + break; + default: + break; + } + break; /* esac TOOL_SYM */ + case RING_SYM: ringoff(otmp); break; *************** *** 145,150 } else if(otmp == uwep) setuwep((struct obj *) 0); if(Punished && otmp == uball){ Punished = 0; freeobj(uchain); --- 167,200 ----- } else if(otmp == uwep) setuwep((struct obj *) 0); + #ifdef WALKIES + if (otmp->olet == TOOL_SYM && otmp->otyp == LEASH) + { + register struct monst *ltmp = fmon; + extern char *lmonnam(); + + while(ltmp && !ltmp->mleashed) + ltmp = ltmp->nmon; + + if(ltmp) { + char dfn[BUFSZ]; + + strcpy(dfn, + #ifdef RPH + /* a hack to include the dogs full name. +4 elminates */ + /* the 'the' at the start of the name */ + lmonnam(ltmp) + 4); + #else + ltmp->data->mname); + #endif + + ltmp->mleashed = 0; + if (next_to(ltmp)) + pline("%s removes the leash from your %s.", + Monnam(mtmp), dfn); + } + } + #endif if(Punished && otmp == uball){ Punished = 0; freeobj(uchain); *** unixmain.c.orig Fri Aug 12 10:18:40 1988 --- unixmain.c Fri Aug 12 10:23:24 1988 *************** *** 15,20 extern char *getlogin(), *getenv(); extern char plname[PL_NSIZ], pl_character[PL_CSIZ]; int (*afternmv)(); int (*occupation)(); --- 15,24 ----- extern char *getlogin(), *getenv(); extern char plname[PL_NSIZ], pl_character[PL_CSIZ]; + #ifdef ANTICRASH + extern char crash_recover; + #endif + int (*afternmv)(); int (*occupation)(); *************** *** 179,185 askname(); plnamesuffix(); /* strip suffix from name; calls askname() */ /* again if suffix was whole name */ ! /* accepts any suffix */ #ifdef WIZARD if(!wizard) { #endif --- 183,191 ----- askname(); plnamesuffix(); /* strip suffix from name; calls askname() */ /* again if suffix was whole name */ ! #ifdef ANTICRASH ! setftty(); ! #endif #ifdef WIZARD if(!wizard) { #endif *************** *** 222,227 } } #endif /* WIZARD /**/ setftty(); (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); regularize(SAVEF+5); /* avoid . or / in name */ --- 228,234 ----- } } #endif /* WIZARD /**/ + #ifndef ANTICRASH setftty(); #endif (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); *************** *** 223,228 } #endif /* WIZARD /**/ setftty(); (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); regularize(SAVEF+5); /* avoid . or / in name */ if((fd = open(SAVEF,0)) >= 0 && --- 230,236 ----- #endif /* WIZARD /**/ #ifndef ANTICRASH setftty(); + #endif (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); regularize(SAVEF+5); /* avoid . or / in name */ #ifdef ANTICRASH *************** *** 225,230 setftty(); (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); regularize(SAVEF+5); /* avoid . or / in name */ if((fd = open(SAVEF,0)) >= 0 && (uptodate(fd) || unlink(SAVEF) == 666)) { (void) signal(SIGINT,done1); --- 233,248 ----- #endif (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); regularize(SAVEF+5); /* avoid . or / in name */ + #ifdef ANTICRASH + if (crash_recover) + { + pline("Hello %s%s, welcome to %s!", + (Badged) ? "Officer " : "", plname, gamename); + (void) signal(SIGINT,done1); + flags.move = 0; + } + else + #endif if((fd = open(SAVEF,0)) >= 0 && (uptodate(fd) || unlink(SAVEF) == 666)) { (void) signal(SIGINT,done1); *** unixunix.c.orig Fri Aug 12 10:18:40 1988 --- unixunix.c Fri Aug 12 10:23:24 1988 *************** *** 27,32 extern char *getenv(); extern time_t time(); setrandom() { (void) srand((int) time ((time_t *) 0)); --- 27,41 ----- extern char *getenv(); extern time_t time(); + #ifdef ANTICRASH + extern char crash_recover; + extern struct permonst pm_wizard; + extern char pl_character[PL_CSIZ]; + extern char fut_geno[60], genocided[60]; + extern char crash_recover; + extern boolean level_exists[MAXLEVEL+1]; + #endif + setrandom() { (void) srand((int) time ((time_t *) 0)); *************** *** 170,175 if(!(kill(lockedpid, 0) == -1 && errno == ESRCH)) #endif return(0); } (void) close(fd); for(i = 1; i <= MAXLEVEL; i++) { /* try to remove all */ --- 179,188 ----- if(!(kill(lockedpid, 0) == -1 && errno == ESRCH)) #endif return(0); + #ifdef ANTICRASH + if (recover_from_crash()) + return(0); + #endif } (void) close(fd); for(i = 1; i <= MAXLEVEL; i++) { /* try to remove all */ *************** *** 229,234 if(veryold(fd)) /* if true, this closes fd and unlinks lock */ goto gotlock; (void) close(fd); } while(i < locknum); (void) unlink(LLOCK); --- 242,254 ----- if(veryold(fd)) /* if true, this closes fd and unlinks lock */ goto gotlock; (void) close(fd); + #ifdef ANTICRASH + if (crash_recover) + { + (void) unlink(LLOCK); + return; + } + #endif } while(i < locknum); (void) unlink(LLOCK); *************** *** 433,435 while((lp = index(s, '.')) || (lp = index(s, '/'))) *lp = '_'; } --- 453,584 ----- while((lp = index(s, '.')) || (lp = index(s, '/'))) *lp = '_'; } + + + #ifdef ANTICRASH + + #undef FMASK + #include <sys/file.h> + + recover_from_crash() + { + int fd; + char answer, readchar(); + + glo(-1); + if ((fd = open(lock, O_RDONLY)) < 0) + return(0); + + pline("Your last dungeon visit unfortunately ended in a disaster!"); + pline("Do you want to recover the crashed game? "); + answer = readchar(); + if (answer == 'Y' || answer == 'y') + return(recover_level(fd)); + else + return(0); + } + + recover_level(fd) + int fd; + { + int tmp; + unsigned mid; + struct obj *otmp; + extern struct obj *restobjchn(); + extern struct monst *restmonchn(); + + invent = restobjchn(fd); + for (otmp = invent; otmp; otmp = otmp->nobj) + if(otmp->owornmask) + setworn(otmp, otmp->owornmask); + fcobj = restobjchn(fd); + fallen_down = restmonchn(fd); + mread(fd, (char *) &tmp, sizeof tmp); + #ifdef WIZARD + if (!wizard) + #endif + if (tmp != getuid()) + { + /* strange ... */ + (void) close(fd); + puts("Saved game was not yours."); + return(0); + } + mread(fd, (char *) &flags, sizeof(struct flag)); + #ifdef DGK + /* Some config file OPTIONS take precedence over those in save file. + */ + flags.rawio = oldflags.rawio; + flags.DECRainbow = oldflags.DECRainbow; + flags.IBMBIOS = oldflags.IBMBIOS; + #endif + mread(fd, (char *) &dlevel, sizeof dlevel); + mread(fd, (char *) &maxdlevel, sizeof maxdlevel); + mread(fd, (char *) level_exists, sizeof level_exists); + mread(fd, (char *) &moves, sizeof moves); + mread(fd, (char *) &u, sizeof(struct you)); + #ifdef SPELLS + mread(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); + #endif + if (u.ustuck) + mread(fd, (char *) &mid, sizeof mid); + mread(fd, (char *) pl_character, sizeof pl_character); + mread(fd, (char *) genocided, sizeof genocided); + mread(fd, (char *) fut_geno, sizeof fut_geno); + #ifdef HARD + { + /* Save name pointer from being munged -- tom@uw-warp */ + char *name = pm_wizard.mname; + mread(fd, (char *) &pm_wizard, sizeof(struct permonst)); + pm_wizard.mname = name; + } + #endif + restnames(fd); + if (Punished) + { + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp->olet == CHAIN_SYM) + goto chainfnd; + panic("Cannot find the iron chain?"); + chainfnd: + uchain = otmp; + if (!uball) + { + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp->olet == BALL_SYM && otmp->spe) + goto ballfnd; + panic("Cannot find the iron ball?"); + ballfnd: + uball = otmp; + } + } + if (u.ustuck) + { + register struct monst *mtmp; + + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (mtmp->m_id == mid) + goto monfnd; + panic("Cannot find the monster ustuck."); + monfnd: + u.ustuck = mtmp; + } + close(fd); + + glo(dlevel); + if ((fd = open(lock, O_RDONLY)) < 0) + return(0); + getlev(fd, 0, 0); + close(fd); + + initrack(); + flags.nscrinh = 0; + setsee(); + seeobjs(); + docrt(); + + crash_recover = TRUE; + return(1); + } + + #endif
institut@csli.STANFORD.EDU (LSA Summer Institute Account) (08/17/88)
The original posting was too long to edit, but the first thing it mentioned was that if a nymph steals certain items while they are applied, you will still get the effects of that item (e.g., if you apply the leash and she steals it, the dog will still stay within a couple of spaces of you), or at least that's how I understood it. So what happens if you apply the blindfold, she steals it, and then you can't take it off (blind for rest of game?)... ======================================================================== Tom Wylie send email to wylie@score.stanford.edu, NOT THE ADDRESS ABOVE!!! (this ain't my account, I just use it for bboards) I'm the only gamer on the staff, so any opinions can only be my own.