Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!mcvax!play From: play@mcvax.UUCP (funhouse) Newsgroups: net.sources Subject: Hack sources (part 6 of 15) Message-ID: <6248@mcvax.UUCP> Date: Mon, 17-Dec-84 19:32:49 EST Article-I.D.: mcvax.6248 Posted: Mon Dec 17 19:32:49 1984 Date-Received: Wed, 19-Dec-84 02:14:44 EST Organization: CWI, Amsterdam Lines: 1033 # This is part 6 (of 15) of the Hack sources. Send complaints to # mcvax!play . # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # hack.end.c hack.engrave.c hack.fight.c echo x - hack.end.c cat > "hack.end.c" << '//E*O*F hack.end.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #include #include #define Sprintf (void) sprintf extern char plname[], pl_character[]; extern char *itoa(), *ordin(), *eos(), *getlogin(); xchar maxdlevel = 1; done1() { (void) signal(SIGINT,SIG_IGN); pline("Really quit?"); if(readchar() != 'y') { (void) signal(SIGINT,done1); clrlin(); (void) fflush(stdout); if(multi > 0) nomul(0); return(0); } done("quit"); /* NOTREACHED */ } int done_stopprint; done_intr(){ done_stopprint++; (void) signal(SIGINT,SIG_IGN); } done_in_by(mtmp) register struct monst *mtmp; { static char buf[BUFSZ]; pline("You die ..."); if(mtmp->data->mlet == ' '){ Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra); killer = buf; } else if(mtmp->mnamelth) { Sprintf(buf, "%s called %s", mtmp->data->mname, NAME(mtmp)); killer = buf; } else if(mtmp->minvis) { Sprintf(buf, "invisible %s", mtmp->data->mname); killer = buf; } else killer = mtmp->data->mname; done("died"); } /* called with arg "died", "escaped", "quit", "choked", "panic" or "starved" */ /* Be careful not to call panic from here! */ done(st1) register char *st1; { #ifdef WIZARD if(wizard && *st1 == 'd'){ u.ustr = u.ustrmax += 2; u.uhp = u.uhpmax += 10; if(uarm) uarm->spe++; if(uwep) uwep->spe++; /* NB: uwep need not be a weapon! */ u.uswldtim = 0; pline("For some reason you are still alive."); flags.move = 0; if(multi > 0) multi = 0; else multi = -1; flags.botl = 1; return; } #endif WIZARD (void) signal(SIGINT, done_intr); if(*st1 == 'q' && u.uhp < 1){ st1 = "died"; killer = "quit while already on Charon's boat"; } if(*st1 == 's') killer = "starvation"; paybill(); clearlocks(); if(index("cds", *st1)){ savebones(); outrip(); } settty((char *) 0); /* does a cls() */ if(!done_stopprint) printf("Goodbye %s %s...\n\n", pl_character, plname); { long int tmp; tmp = u.ugold - u.ugold0; if(tmp < 0) tmp = 0; if(*st1 == 'd') tmp -= tmp/10; else killer = st1; u.urexp += tmp; } if(*st1 == 'e') { extern struct monst *mydogs; register struct monst *mtmp = mydogs; register struct obj *otmp; register int i; register unsigned worthlessct = 0; u.urexp += 50 * maxdlevel; if(mtmp) { if(!done_stopprint) printf("You"); while(mtmp) { if(!done_stopprint) printf(" and %s", monnam(mtmp)); u.urexp += mtmp->mhp; mtmp = mtmp->nmon; } if(!done_stopprint) printf("\nescaped from the dungeon with %lu points,\n", u.urexp); } else if(!done_stopprint) printf("You escaped from the dungeon with %lu points,\n", u.urexp); for(otmp = invent; otmp; otmp = otmp->nobj) { if(otmp->olet == GEM_SYM){ objects[otmp->otyp].oc_name_known = 1; i = otmp->quan*objects[otmp->otyp].g_val; if(i == 0) { worthlessct += otmp->quan; continue; } u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); } else if(otmp->olet == AMULET_SYM) { otmp->known = 1; i = (otmp->spe < 0) ? 2 : 5000; u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); if(otmp->spe >= 0) u.urexp *= 2; } } if(worthlessct) if(!done_stopprint) printf("\t%d worthless piece%s of coloured glass,\n", worthlessct, plur(worthlessct)); killer=st1; } else if(!done_stopprint) printf("You %s on dungeon level %d with %lu points,\n", st1,dlevel,u.urexp); if(!done_stopprint) printf("and %lu piece%s of gold, after %lu move%s.\n", u.ugold, (u.ugold == 1) ? "" : "s", moves, (moves == 1) ? "" : "s"); if(!done_stopprint) printf("You were level %d with a maximum of %d hit points when you %s.\n", u.ulevel, u.uhpmax, st1); if(*st1 == 'e'){ getret(); /* all those pieces of coloured glass ... */ cls(); } #ifdef WIZARD if(!wizard) #endif WIZARD topten(); if(done_stopprint) printf("\n\n"); exit(0); } #define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry)) #define NAMSZ 8 #define DTHSZ 40 #define PERSMAX 1 #define POINTSMIN 1 /* must be > 0 */ #define ENTRYMAX 100 /* must be >= 10 */ struct toptenentry { struct toptenentry *tt_next; long int points; int level,maxlvl,hp,maxhp; char plchar; char str[NAMSZ+1]; char death[DTHSZ+1]; } *tt_head; topten(){ int rank, rank0 = -1, rank1 = 0; int occ_cnt = PERSMAX; register struct toptenentry *t0, *t1, *tprev; char *recfile = "record"; FILE *rfile; register flg = 0; if(!(rfile = fopen(recfile,"r"))){ puts("Cannot open record file!"); return; } (void) putchar('\n'); /* create a new 'topten' entry */ t0 = newttentry(); t0->level = dlevel; t0->maxlvl = maxdlevel; t0->hp = u.uhp; t0->maxhp = u.uhpmax; t0->points = u.urexp; t0->plchar = pl_character[0]; (void) strncpy(t0->str, plname, NAMSZ); (t0->str)[NAMSZ] = 0; (void) strncpy(t0->death, killer, DTHSZ); (t0->death)[DTHSZ] = 0; /* assure minimum number of points */ if(t0->points < POINTSMIN) t0->points = 0; t1 = tt_head = newttentry(); tprev = 0; /* rank0: -1 undefined, 0 not_on_list, n n_th on list */ for(rank = 1; ; ) { if(fscanf(rfile, "%d %d %d %d %ld %c %[^,],%[^\n]", &t1->level, &t1->maxlvl, &t1->hp, &t1->maxhp, &t1->points, &t1->plchar, t1->str, t1->death) != 8 || t1->points < POINTSMIN) t1->points = 0; if(rank0 < 0 && t1->points < t0->points) { rank0 = rank++; if(tprev == 0) tt_head = t0; else tprev->tt_next = t0; t0->tt_next = t1; occ_cnt--; flg++; /* ask for a rewrite */ } else tprev = t1; if(t1->points == 0) break; if(strncmp(t1->str, t0->str, NAMSZ) == 0 && t1->plchar == t0->plchar && --occ_cnt <= 0){ if(rank0 < 0){ rank0 = 0; rank1 = rank; printf("You didn't beat your previous score of %ld points.\n\n", t1->points); } if(occ_cnt < 0){ flg++; continue; } } if(rank <= ENTRYMAX){ t1 = t1->tt_next = newttentry(); rank++; } if(rank > ENTRYMAX){ t1->points = 0; break; } } if(flg) { /* rewrite record file */ (void) fclose(rfile); if(!(rfile=fopen(recfile,"w"))){ puts("Cannot write record file\n"); return; } if(!done_stopprint) if(rank0 > 0){ if(rank0 <= 10) puts("You made the top ten list!\n"); else printf("You reached the %d%s place on the top %d list.\n\n", rank0, ordin(rank0), ENTRYMAX); } } if(rank0 == 0) rank0 = rank1; if(rank0 <= 0) rank0 = rank; if(!done_stopprint) outheader(); t1 = tt_head; for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) { if(flg) fprintf(rfile,"%d %d %d %d %ld %c %s,%s\n", t1->level, t1->maxlvl, t1->hp, t1->maxhp, t1->points, t1->plchar,t1->str,t1->death); if(done_stopprint) continue; if(rank > 5 && (rank < rank0 - 4 || rank > rank0 + 4)) continue; if(rank == rank0 - 4 && rank0 > 10) (void) putchar('\n'); if(rank != rank0) (void) outentry(rank, t1, 0); else if(!rank1) (void) outentry(rank, t1, 1); else { int t0lth = outentry(0, t0, -1); int t1lth = outentry(rank, t1, t0lth); if(t1lth > t0lth) t0lth = t1lth; (void) outentry(0, t0, t0lth); } } if(rank0 >= rank) (void) outentry(0, t0, 1); (void) fclose(rfile); } outheader() { char linebuf[BUFSZ]; register char *bp; (void) strcpy(linebuf, "Number Points Name"); bp = eos(linebuf); while(bp < linebuf + COLNO - 9) *bp++ = ' '; (void) strcpy(bp, "Hp [max]"); puts(linebuf); } /* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */ int outentry(rank,t1,so) register struct toptenentry *t1; { boolean quit = FALSE, killed = FALSE, starv = FALSE; char linebuf[BUFSZ]; linebuf[0] = 0; if(rank) Sprintf(eos(linebuf), "%3d", rank); else Sprintf(eos(linebuf), " "); Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->str); if(t1->plchar == 'X') Sprintf(eos(linebuf), " "); else Sprintf(eos(linebuf), "-%c ", t1->plchar); if(!strcmp("escaped", t1->death)) Sprintf(eos(linebuf), "escaped the dungeon [max level %d]", t1->maxlvl); else { if(!strncmp(t1->death,"quit",4)) Sprintf(eos(linebuf), "quit"), quit = TRUE; else if(!strcmp(t1->death,"choked")) Sprintf(eos(linebuf), "choked in his food"); else if(!strncmp(t1->death,"starv",5)) Sprintf(eos(linebuf), "starved to death"), starv = TRUE; else Sprintf(eos(linebuf), "was killed"), killed = TRUE; Sprintf(eos(linebuf), " on%s level %d", (killed || starv) ? "" : " dungeon", t1->level); if(t1->maxlvl != t1->level) Sprintf(eos(linebuf), " [max %d]", t1->maxlvl); if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4); } if(killed) Sprintf(eos(linebuf), " by %s%s", !strncmp(t1->death, "the ", 4) ? "" : index(vowels,*t1->death) ? "an " : "a ", t1->death); Sprintf(eos(linebuf), "."); if(t1->maxhp) { register char *bp = eos(linebuf); char hpbuf[10]; int hppos; Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-"); hppos = COLNO - 7 - strlen(hpbuf); if(bp <= linebuf + hppos) { while(bp < linebuf + hppos) *bp++ = ' '; (void) strcpy(bp, hpbuf); Sprintf(eos(bp), " [%d]", t1->maxhp); } } if(so == 0) puts(linebuf); else if(so > 0) { register char *bp = eos(linebuf); if(so >= COLNO) so = COLNO-1; while(bp < linebuf + so) *bp++ = ' '; *bp = 0; standoutbeg(); fputs(linebuf,stdout); standoutend(); (void) putchar('\n'); } return(strlen(linebuf)); } char * itoa(a) int a; { static char buf[12]; Sprintf(buf,"%d",a); return(buf); } char * ordin(n) int n; { register int d = n%10; return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" : (d==2) ? "nd" : "rd"); } clearlocks(){ register x; (void) signal(SIGHUP,SIG_IGN); for(x = 1; x <= maxdlevel; x++) { glo(x); (void) unlink(lock); /* not all levels need be present */ } (*index(lock,'.')) = 0; (void) unlink(lock); } #ifdef NOSAVEONHANGUP hangup(){ (void) signal(SIGINT,SIG_IGN); clearlocks(); exit(1); } #endif NOSAVEONHANGUP char * eos(s) register char *s; { while(*s) s++; return(s); } /* it is the callers responsibility to check that there is room for c */ charcat(s,c) register char *s, c; { while(*s) s++; *s++ = c; *s = 0; } prscore(argc,argv) int argc; char **argv; { extern char *hname; char *player0; char **players; int playerct; int rank; register struct toptenentry *t1; char *recfile = "record"; FILE *rfile; register flg = 0; register int i; if(!(rfile = fopen(recfile,"r"))){ puts("Cannot open record file!"); return; } if(argc > 1 && !strncmp(argv[1], "-s", 2)){ if(!argv[1][2]){ argc--; argv++; } else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) { argv[1]++; argv[1][0] = '-'; } else argv[1] += 2; } if(argc <= 1){ player0 = getlogin(); if(!player0) player0 = "player"; playerct = 1; players = &player0; } else { playerct = --argc; players = ++argv; } putchar('\n'); t1 = tt_head = newttentry(); for(rank = 1; ; rank++) { if(fscanf(rfile, "%d %d %d %d %ld %c %[^,],%[^\n]", &t1->level, &t1->maxlvl, &t1->hp, &t1->maxhp, &t1->points, &t1->plchar, t1->str, t1->death) != 8) t1->points = 0; if(t1->points == 0) break; for(i = 0; i < playerct; i++){ if(strcmp(players[i], "all") == 0 || strncmp(t1->str, players[i], NAMSZ) == 0 || (players[i][0] == '-' && players[i][1] == t1->plchar && players[i][2] == 0) || (digit(players[i][0]) && rank <= atoi(players[i]))) flg++; } t1 = t1->tt_next = newttentry(); } (void) fclose(rfile); if(!flg) { printf("Cannot find any entries for "); if(playerct > 1) printf("any of "); for(i=0; ipoints != 0; rank++, t1 = t1->tt_next) { for(i = 0; i < playerct; i++){ if(strcmp(players[i], "all") == 0 || strncmp(t1->str, players[i], NAMSZ) == 0 || (players[i][0] == '-' && players[i][1] == t1->plchar && players[i][2] == 0) || (digit(players[i][0]) && rank <= atoi(players[i]))) goto out; } continue; out: (void) outentry(rank, t1, 0); } } //E*O*F hack.end.c// echo x - hack.engrave.c cat > "hack.engrave.c" << '//E*O*F hack.engrave.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" extern char *nomovemsg; extern char nul[]; struct engr { struct engr *nxt_engr; char *engr_txt; xchar engr_x, engr_y; unsigned engr_lth; /* for save & restore; not length of text */ long engr_time; /* moment engraving was (will be) finished */ xchar engr_type; #define DUST 1 #define ENGRAVE 2 #define BURN 3 } *head_engr; struct engr * engr_at(x,y) register xchar x,y; { register struct engr *ep = head_engr; while(ep) { if(x == ep->engr_x && y == ep->engr_y) return(ep); ep = ep->nxt_engr; } return((struct engr *) 0); } sengr_at(s,x,y) register char *s; register xchar x,y; { register struct engr *ep = engr_at(x,y); register char *t; register int n; if(ep && ep->engr_time <= moves) { t = ep->engr_txt; /* if(!strcmp(s,t)) return(1); */ n = strlen(s); while(*t) { if(!strncmp(s,t,n)) return(1); t++; } } return(0); } wipe_engr_at(x,y,cnt) register xchar x,y,cnt; { register struct engr *ep = engr_at(x,y); register int lth,pos; char ch; if(ep){ if(ep->engr_type != DUST) { cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1; } lth = strlen(ep->engr_txt); if(lth && cnt > 0 ) { while(cnt--) { pos = rn2(lth); if((ch = ep->engr_txt[pos]) == ' ') continue; ep->engr_txt[pos] = (ch != '?') ? '?' : ' '; } } while(lth && ep->engr_txt[lth-1] == ' ') ep->engr_txt[--lth] = 0; while(ep->engr_txt[0] == ' ') ep->engr_txt++; if(!ep->engr_txt[0]) del_engr(ep); } } read_engr_at(x,y) register int x,y; { register struct engr *ep = engr_at(x,y); if(ep && ep->engr_txt[0]) { switch(ep->engr_type) { case DUST: pline("Something is written here in the dust."); break; case ENGRAVE: pline("Something is engraved here on the floor."); break; case BURN: pline("Some text has been burned here in the floor."); break; default: pline("Something is written in a very strange way."); impossible(); } pline("You read: \"%s\".", ep->engr_txt); } } doengrave(){ register int len; register char *sp; register struct engr *ep, *oep = engr_at(u.ux,u.uy); char buf[BUFSZ]; xchar type; int spct; /* number of leading spaces */ register struct obj *otmp; multi = 0; /* one may write with finger, weapon or wand */ otmp = getobj("#-)/", "write with"); if(!otmp) return(0); if(otmp == (struct obj *)(-1)) type = DUST; else if(otmp->otyp == WAN_FIRE && otmp->spe) { type = BURN; otmp->spe--; } else if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD || otmp->otyp == CRYSKNIFE || otmp->otyp == LONG_SWORD || otmp->otyp == AXE){ type = ENGRAVE; if((int)otmp->spe <= -3) { type = DUST; pline("Your %s too dull for engraving.", aobjnam(otmp, "are")); if(oep && oep->engr_type != DUST) return(1); } } else type = DUST; if(oep && oep->engr_type == DUST){ pline("You wipe out the message that was written here."); del_engr(oep); oep = 0; } if(type == DUST && oep){ pline("You cannot wipe out the message that is %s in the rock.", (oep->engr_type == BURN) ? "burned" : "engraved"); return(1); } pline("What do you want to %s on the floor here? ", (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write"); getlin(buf); clrlin(); spct = 0; sp = buf; while(*sp == ' ') spct++, sp++; len = strlen(sp); if(!len) { if(type == BURN) otmp->spe++; return(0); } switch(type) { case DUST: case BURN: if(len > 15) { multi = -(len/10); nomovemsg = "You finished writing."; } break; case ENGRAVE: { int len2 = (otmp->spe + 3) * 2 + 1; char *bufp = doname(otmp); if(digit(*bufp)) pline("Your %s get dull.", bufp); else { if(!strncmp(bufp,"a ",2)) bufp += 2; else if(!strncmp(bufp,"an ",3)) bufp += 3; pline("Your %s gets dull.", bufp); } if(len2 < len) { len = len2; sp[len] = 0; otmp->spe = -3; nomovemsg = "You cannot engrave more."; } else { otmp->spe -= len/2; nomovemsg = "You finished engraving."; } multi = -len; } break; } if(oep) len += strlen(oep->engr_txt) + spct; ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1)); ep->nxt_engr = head_engr; head_engr = ep; ep->engr_x = u.ux; ep->engr_y = u.uy; sp = (char *)(ep + 1); /* (char *)ep + sizeof(struct engr) */ ep->engr_txt = sp; if(oep) { (void) strcpy(sp, oep->engr_txt); (void) strcat(sp, buf); del_engr(oep); } else (void) strcpy(sp, buf); ep->engr_lth = len+1; ep->engr_type = type; ep->engr_time = moves-multi; /* kludge to protect pline against excessively long texts */ if(len > BUFSZ-20) sp[BUFSZ-20] = 0; return(1); } save_engravings(fd) int fd; { register struct engr *ep = head_engr; while(ep) { if(!ep->engr_lth || !ep->engr_txt[0]){ ep = ep->nxt_engr; continue; } bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth)); bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth); ep = ep->nxt_engr; } bwrite(fd, (char *) nul, sizeof(unsigned)); } rest_engravings(fd) int fd; { register struct engr *ep; unsigned lth; head_engr = 0; while(1) { mread(fd, (char *) <h, sizeof(unsigned)); if(lth == 0) return; ep = (struct engr *) alloc(sizeof(struct engr) + lth); mread(fd, (char *) ep, sizeof(struct engr) + lth); ep->nxt_engr = head_engr; head_engr = ep; } } del_engr(ep) register struct engr *ep; { register struct engr *ept; if(ep == head_engr) head_engr = ep->nxt_engr; else { for(ept = head_engr; ept; ept = ept->nxt_engr) if(ept->nxt_engr == ep) { ept->nxt_engr = ep->nxt_engr; goto fnd; } pline("Error in del_engr?"); impossible(); fnd: ; } free((char *) ep); } //E*O*F hack.engrave.c// echo x - hack.fight.c cat > "hack.fight.c" << '//E*O*F hack.fight.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" extern struct permonst li_dog, dog, la_dog; extern char *exclam(), *xname(); static boolean far_noise; static long noisetime; /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ hitmm(magr,mdef) register struct monst *magr,*mdef; { register struct permonst *pa = magr->data, *pd = mdef->data; int hit; schar tmp; boolean vis; if(index("Eauy", pa->mlet)) return(0); tmp = pd->ac + pa->mlevel; if(mdef->mconf || mdef->mfroz || mdef->msleep){ tmp += 4; if(mdef->msleep) mdef->msleep = 0; } hit = (tmp > rnd(20)); if(hit) mdef->msleep = 0; vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); if(vis){ char buf[BUFSZ]; if(mdef->mimic) seemimic(mdef); if(magr->mimic) seemimic(magr); (void) sprintf(buf,"%s %s", Monnam(magr), hit ? "hits" : "misses"); pline("%s %s.", buf, monnam(mdef)); } else { boolean far = (dist(magr->mx, magr->my) > 15); if(far != far_noise || moves-noisetime > 10) { far_noise = far; noisetime = moves; pline("You hear some noises%s.", far ? " in the distance" : ""); } } if(hit){ if(magr->data->mlet == 'c' && !magr->cham) { magr->orig_hp += 3; if(vis) pline("%s is turned to stone!", Monnam(mdef)); else if(mdef->mtame) pline("You have a peculiarly sad feeling for a moment, then it passes."); monstone(mdef); hit = 2; } else if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { magr->orig_hp += 1 + rn2(pd->mlevel+1); if(magr->mtame && magr->orig_hp > 8*pa->mlevel){ if(pa == &li_dog) magr->data = pa = &dog; else if(pa == &dog) magr->data = pa = &la_dog; } if(vis) pline("%s is killed!", Monnam(mdef)); else if(mdef->mtame) pline("You have a sad feeling for a moment, then it passes."); mondied(mdef); hit = 2; } } return(hit); } /* drop (perhaps) a cadaver and remove monster */ mondied(mdef) register struct monst *mdef; { register struct permonst *pd = mdef->data; if(letter(pd->mlet) && rn2(3)){ mksobj_at(pd->mlet,CORPSE,mdef->mx,mdef->my); if(cansee(mdef->mx,mdef->my)){ unpmon(mdef); atl(mdef->mx,mdef->my,fobj->olet); } stackobj(fobj); } mondead(mdef); } /* drop a rock and remove monster */ monstone(mdef) register struct monst *mdef; { extern char mlarge[]; if(index(mlarge, mdef->data->mlet)) mksobj_at(ROCK_SYM, ENORMOUS_ROCK, mdef->mx, mdef->my); else mksobj_at(WEAPON_SYM, ROCK, mdef->mx, mdef->my); if(cansee(mdef->mx, mdef->my)){ unpmon(mdef); atl(mdef->mx,mdef->my,fobj->olet); } mondead(mdef); } fightm(mtmp) register struct monst *mtmp; { register struct monst *mon; for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) if(rn2(4)) return(hitmm(mtmp,mon)); } return(-1); } hitu(mtmp,dam) register struct monst *mtmp; register dam; { register tmp; if(mtmp->mhide && mtmp->mundetected) { mtmp->mundetected = 0; if(!Blind) { register struct obj *obj; extern char * Xmonnam(); if(obj = o_at(mtmp->mx,mtmp->my)) pline("%s was hidden under %s!", Xmonnam(mtmp), doname(obj)); } } tmp = u.uac; /* give people with Ac = -10 at least some vulnerability */ if(tmp < 0) { dam += tmp; /* decrease damage */ if(dam <= 0) dam = 1; tmp = -rn2(-tmp); } tmp += mtmp->data->mlevel; if(multi < 0) tmp += 4; if(Invis || !mtmp->mcansee) tmp -= 2; if(mtmp->mtrapped) tmp -= 2; if(tmp <= rnd(20)) { if(Blind) pline("It misses."); else pline("%s misses.",Monnam(mtmp)); return(0); } if(Blind) pline("It hits!"); else pline("%s hits!",Monnam(mtmp)); losehp_m(dam, mtmp); return(1); } /* u is hit by sth, but not a monster */ thitu(tlev,dam,name) register tlev,dam; register char *name; { char buf[BUFSZ]; setan(name,buf); if(u.uac + tlev <= rnd(20)) { if(Blind) pline("It misses."); else pline("You are almost hit by %s!", buf); return(0); } else { if(Blind) pline("You are hit!"); else pline("You are hit by %s!", buf); losehp(dam,name); return(1); } } char mlarge[] = "bCDdegIlmnoPSsTUwY~,&"; boolean hmon(mon,obj,thrown) /* return TRUE if mon still alive */ register struct monst *mon; register struct obj *obj; register thrown; { register tmp; if(!obj){ tmp = rnd(2); /* attack with bare hands */ if(mon->data->mlet == 'c' && !uarmg){ pline("You hit the cockatrice with your bare hands"); pline("You turn to stone ..."); done_in_by(mon); } } else if(obj->olet == WEAPON_SYM) { if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) tmp = rnd(2); else { if(index(mlarge, mon->data->mlet)) { tmp = rnd(objects[obj->otyp].wldam); if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6); else if(obj->otyp == FLAIL) tmp += rnd(4); } else { tmp = rnd(objects[obj->otyp].wsdam); } tmp += obj->spe; if(!thrown && obj == uwep && obj->otyp == BOOMERANG && !rn2(3)){ pline("As you hit %s, the boomerang breaks into splinters.", monnam(mon)); freeinv(obj); setworn((struct obj *) 0, obj->owornmask); obfree(obj, (struct obj *) 0); tmp++; } } if(mon->data->mlet == 'O' && !strcmp(ONAME(obj), "Orcrist")) tmp += rnd(10); } else switch(obj->otyp) { case HEAVY_IRON_BALL: tmp = rnd(25); break; case EXPENSIVE_CAMERA: pline("You succeed in destroying your camera. Congratulations!"); freeinv(obj); if(obj->owornmask) setworn((struct obj *) 0, obj->owornmask); obfree(obj, (struct obj *) 0); return(TRUE); case DEAD_COCKATRICE: pline("You hit %s with the cockatrice corpse", monnam(mon)); pline("%s is turned to stone!", Monnam(mon)); killed(mon); return(FALSE); case CLOVE_OF_GARLIC: if(index(" VWZ", mon->data->mlet)) mon->mflee = 1; tmp = 1; break; default: /* non-weapons can damage because of their weight */ /* (but not too much) */ tmp = obj->owt/10; if(tmp < 1) tmp = 1; else tmp = rnd(tmp); if(tmp > 6) tmp = 6; } /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ tmp += u.udaminc + dbon(); if(u.uswallow) if(mon->data->mlet == 'P') { if((tmp -= u.uswldtim) <= 0) { pline("Your arms are no longer able to hit."); return(TRUE); } } if(tmp < 1) tmp = 1; mon->mhp -= tmp; if(mon->mhp < 1) { killed(mon); return(FALSE); } if(thrown) { /* this assumes that we cannot throw plural things */ hit( xname(obj) /* or: objects[obj->otyp].oc_name */, mon, exclam(tmp) ); return(TRUE); } if(Blind) pline("You hit it."); else pline("You hit %s%s", monnam(mon), exclam(tmp)); if(u.umconf) { if(!Blind) { pline("Your hands stop glowing blue."); if(!mon->mfroz && !mon->msleep) pline("%s appears confused.",Monnam(mon)); } mon->mconf = 1; u.umconf = 0; } return(TRUE); /* mon still alive */ } //E*O*F hack.fight.c// exit 0