Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!columbia!caip!clyde!cbatt!cbosgd!ucbvax!ucdavis!deneb!u566393908ea From: u566393908ea@ucdavis.UUCP (u566393908ea) Newsgroups: net.sources.games Subject: VMS Larn 12.0 is here! (part 2 of 6) Message-ID: <495@ucdavis.UUCP> Date: Sat, 30-Aug-86 18:02:03 EDT Article-I.D.: ucdavis.495 Posted: Sat Aug 30 18:02:03 1986 Date-Received: Sun, 31-Aug-86 09:09:34 EDT Distribution: net Organization: University of California, Davis Lines: 2668 Hello all! This is a port of Larn v12.0 to VAX/VMS. Now everyone can save his/her daughter!! Just unpack using /bin/sh and read readme.txt. - Mark Nagel P.S. Thanks to Lord Kahless for letting me post this! -------------------------------cut here------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # diag.c # display.c # fortune.c # global.c # header.h # help.c # This archive created: Sat Aug 30 14:46:47 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'diag.c'" '(11426 characters)' if test -f 'diag.c' then echo shar: will not over-write existing file "'diag.c'" else cat << \SHAR_EOF > 'diag.c' /* diag.c Larn is copyrighted 1986 by Noah Morgan. */ #include #include #include "header.h" extern int rmst,maxitm,lasttime; static struct tms cputime; /* *************************** DIAG -- dungeon diagnostics *************************** subroutine to print out data for debugging */ #ifdef EXTRA static int rndcount[16]; diag() { register int i,j; int hit,dam; cursors(); lwclose(); if (lcreat(diagfile) < 0) { /* open the diagnostic file */ lcreat((char *) 0); lprcat("\ndiagnostic failure\n"); return(-1); } write(1, "\nDiagnosing . . .\n", 18); lprcat("\n\nBeginning of DIAG diagnostics ----------\n"); /* for the character attributes */ lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long) c[HP],(long) c[HPMAX]); lprintf("\ngold: %d Experience: %d Character level: %d Level in caverns: %d", (long) c[GOLD],(long) c[EXPERIENCE],(long) c[LEVEL],(long) level); lprintf("\nTotal types of monsters: %d",(long) MAXMONST + 8); lprcat("\f\nHere's the dungeon:\n\n"); i = level; for (j = 0; j < MAXLEVEL + MAXVLEVEL; j++) { newcavelevel(j); lprintf("\nMaze for level %s:\n", levelname[level]); diagdrawscreen(); } newcavelevel(i); lprcat("\f\nNow for the monster data:\n\n"); lprcat(" Monster Name LEV AC DAM ATT DEF GOLD HP EXP \n"); lprcat("--------------------------------------------------------------------------\n"); for (i = 0; i <= MAXMONST + 8; i++) { lprintf("%19s %2d %3d ", monster[i].name,(long) monster[i].level,(long) monster[i].armorclass); lprintf(" %3d %3d %3d ",(long) monster[i].damage,(long) monster[i].attack,(long) monster[i].defense); lprintf("%6d %3d %6d\n",(long) monster[i].gold,(long) monster[i].hitpoints,(long) monster[i].experience); } lprcat("\n\nHere's a Table for the to hit percentages\n"); lprcat("\n We will be assuming that players level = 2 * monster level"); lprcat("\n and that the players dexterity and strength are 16."); lprcat("\n to hit: if (rnd(22) <(2[monst AC] + your level + dex + WC/8 -1)/2) then hit"); lprcat("\n damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4"); lprcat("\n to hit: if rnd(22) < to hit then player hits\n"); lprcat("\n Each entry is as follows: to hit / damage / number hits to kill\n"); lprcat("\n monster WC = 4 WC = 20 WC = 40"); lprcat("\n---------------------------------------------------------------"); for (i = 0; i <= MAXMONST + 8; i++) { hit = 2 * monster[i].armorclass + 2 * monster[i].level + 16; dam = 16 - c[HARDGAME]; lprintf("\n%20s %2d/%2d/%2d %2d/%2d/%2d %2d/%2d/%2d", monster[i].name, (long)(hit / 2),(long) max(0, dam + 2),(long)(monster[i].hitpoints /(dam + 2) + 1), (long)((hit + 2) / 2),(long) max(0, dam + 10),(long)(monster[i].hitpoints /(dam + 10) + 1), (long)((hit + 5) / 2),(long) max(0, dam + 20),(long)(monster[i].hitpoints /(dam + 20) + 1)); } lprcat("\n\nHere's the list of available potions:\n\n"); for (i = 0; i < MAXPOTION; i++) lprintf("%20s\n", &potionname[i][1]); lprcat("\n\nHere's the list of available scrolls:\n\n"); for (i = 0; i < MAXSCROLL; i++) lprintf("%20s\n", &scrollname[i][1]); lprcat("\n\nHere's the spell list:\n\n"); lprcat("spell name description\n"); lprcat("-------------------------------------------------------------------------------------------\n\n"); for (j = 0; j < SPNUM; j++) { lprc(' '); lprcat(spelcode[j]); lprintf(" %21s %s\n", spelname[j], speldescript[j]); } lprcat("\n\nFor the c[] array:\n"); for (j = 0; j < 100; j += 10) { lprintf("\nc[%2d] = ",(long) j); for (i = 0; i < 9; i++) lprintf("%5d ",(long) c[i + j]); } lprcat("\n\nTest of random number generator ----------------"); lprcat("\n for 25,000 calls divided into 16 slots\n\n"); for (i = 0; i < 16; i++) rndcount[i] = 0; for (i = 0; i < 25000; i++) rndcount[rund(16)]++; for (i = 0; i < 16; i++) { lprintf(" %5d",(long) rndcount[i]); if (i == 7) lprc('\n'); } lprcat("\n\n"); lwclose(); lcreat((char *) 0); lprcat("Done Diagnosing . . ."); return(0); } /* subroutine to count the number of occurrences of an object */ dcount(l) int l; { register int i,j,p; int k = 0; for (i = 0; i < MAXX; i++) for (j = 0; j < MAXY; j++) for (p = 0; p < MAXLEVEL; p++) if (cell[p * MAXX * MAXY + i * MAXY + j].item == l) k++; return(k); } /* subroutine to draw the whole screen as the player knows it */ diagdrawscreen() { register int i,j,k; for (i = 0; i < MAXY; i++) { /* for the east west walls of this line */ for (j = 0; j < MAXX; j++) if (k = mitem[j][i]) lprc(monstnamelist[k]); else lprc(objnamelist[item[j][i]]); lprc('\n'); } } #endif /* to save the game in a file */ static long int zzz = 0; savegame(fname) char *fname; { register int i,k; register struct sphere *sp; struct stat statbuf; nosignal = 1; lflush(); savelevel(); ointerest(); if (lcreat(fname) < 0) { lcreat((char *) 0); lprintf("\nCan't open file \"%s\" to save game\n", fname); nosignal = 0; return(-1); } set_score_output(); lwrite((char *) beenhere, MAXLEVEL + MAXVLEVEL); for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++) if (beenhere[k]) lwrite((char *) & cell[k * MAXX * MAXY], sizeof(struct cel) * MAXY * MAXX); times(&cputime); /* get cpu time */ c[CPUTIME] += (cputime.tms_utime + cputime.tms_stime - start_cpu) / 100; lwrite((char *) &c[0], 100 * sizeof(long)); lprint((long) gtime); lprc(level); lprc(playerx); lprc(playery); lwrite((char *) iven, 26); lwrite((char *) ivenarg, 26 * sizeof(short)); for (k = 0; k < MAXSCROLL; k++) lprc(scrollname[k][0]); for (k = 0; k < MAXPOTION; k++) lprc(potionname[k][0]); lwrite((char *) spelknow, SPNUM); lprc(wizard); lprc(rmst); /* random monster generation counter */ for (i = 0; i < 90; i++) lprc(itm[i].qty); lwrite((char *) course, 25); lprc(cheat); lprc(VERSION); for (i = 0; i < MAXMONST; i++) lprc(monster[i].genocided);/* genocide info */ for (sp = spheres; sp; sp = sp -> p) lwrite((char *) sp, sizeof(struct sphere));/* save spheres of annihilation */ time(&zzz); lprint((long)(zzz - initialtime)); lwrite((char *) & zzz, sizeof(long)); if (fstat(lfd, &statbuf) < 0) lprint(0L); else { lprint((long) statbuf.st_ino[0]); /* inode # */ lprint((long) statbuf.st_ino[1]); /* inode # */ lprint((long) statbuf.st_ino[2]); /* inode # */ } lwclose(); lastmonst[0] = 0; #ifndef VT100 setscroll(); #endif VT100 lcreat((char *) 0); nosignal = 0; return(0); } restoregame(fname) char *fname; { register int i,k; register struct sphere *sp,*sp2; struct stat filetimes; cursors(); lprcat("\nRestoring . . ."); lflush(); if (lopen(fname) <= 0) { lcreat((char *) 0); lprintf("\nCan't open file \"%s\" to restore game\n", fname); nap(2000); c[GOLD] = c[BANKACCOUNT] = 0; died(-265); return; } lrfill((char *) beenhere, MAXLEVEL + MAXVLEVEL); for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++) if (beenhere[k]) lrfill((char *) & cell[k * MAXX * MAXY], sizeof(struct cel) * MAXY * MAXX); lrfill((char *) & c[0], 100 * sizeof(long)); gtime = lrint(); level = c[CAVELEVEL] = lgetc(); playerx = lgetc(); playery = lgetc(); lrfill((char *) iven, 26); lrfill((char *) ivenarg, 26 * sizeof(short)); for (k = 0; k < MAXSCROLL; k++) scrollname[k][0] = lgetc(); for (k = 0; k < MAXPOTION; k++) potionname[k][0] = lgetc(); lrfill((char *) spelknow, SPNUM); wizard = lgetc(); rmst = lgetc(); /* random monster creation flag */ for (i = 0; i < 90; i++) itm[i].qty = lgetc(); lrfill((char *) course, 25); cheat = lgetc(); if (VERSION != lgetc()) { /* version number */ cheat = 1; lprcat("Sorry, But your save file is for an older version of larn\n"); nap(2000); c[GOLD] = c[BANKACCOUNT] = 0; died(-266); return; } for (i = 0; i < MAXMONST; i++) monster[i].genocided = lgetc();/* genocide info */ for (sp = 0, i = 0; i < c[SPHCAST]; i++) { sp2 = sp; sp =(struct sphere *) malloc(sizeof(struct sphere)); if (sp == 0) { write(2, "Can't malloc() for sphere space\n", 32); break; } lrfill((char *) sp, sizeof(struct sphere));/* get spheres of annihilation */ sp->p = 0; /* null out pointer */ if (i == 0) spheres = sp; /* beginning of list */ else sp2->p = sp; } time(&zzz); initialtime = zzz - lrint(); fstat(fd, &filetimes); /* get the creation and modification time of file */ lrfill((char *) & zzz, sizeof(long)); zzz += 6; if (filetimes.st_ctime > zzz) fsorry(); /* file create time */ else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time */ if (c[HP] < 0) { died(284); return; } /* died a post mortem death */ oldx = oldy = 0; i = lrint(); /* inode # */ if (i &&(filetimes.st_ino[0] != i)) fsorry(); i = lrint(); /* inode # */ if (i &&(filetimes.st_ino[1] != i)) fsorry(); i = lrint(); /* inode # */ if (i &&(filetimes.st_ino[2] != i)) fsorry(); lrclose(); if (strcmp(fname, ckpfile) == 0) { if (lappend(fname) < 0) fcheat(); else { lprc(' '); lwclose(); } lcreat((char *) 0); } else if (delete(fname) < 0) fcheat(); /* can't unlink save file */ /* for the greedy cheater checker */ for (k = 0; k < 6; k++) if (c[k] > 99) greedy(); if (c[HPMAX] > 999 || c[SPELLMAX] > 125) greedy(); if (c[LEVEL] == 25 && c[EXPERIENCE] > skill[24]) {/* if patch up lev 25 player */ long tmp; tmp = c[EXPERIENCE] - skill[24];/* amount to go up */ c[EXPERIENCE] = skill[24]; raiseexperience((long) tmp); } getlevel(); lasttime = gtime; } /* subroutine to not allow greedy cheaters */ greedy() { #if WIZID if (wizard) return; #endif lprcat("\n\nI am so sorry, but your character is a little TOO good! Since this\n"); lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n"); lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n"); lprcat("to continue.\n"); nap(5000); c[GOLD] = c[BANKACCOUNT] = 0; died(-267); return; } /* subroutine to not allow altered save files and terminate the attempted restart */ fsorry() { lprcat("\nSorry, but your savefile has been altered.\n"); lprcat("However, seeing as I am a good sport, I will let you play.\n"); lprcat("Be advised though, you won't be placed on the normal scoreboard."); cheat = 1; nap(4000); } /* subroutine to not allow game if save file can't be deleted */ fcheat() { #if WIZID if (wizard) return; #endif lprcat("\nSorry, but your savefile can't be deleted. This can only mean\n"); lprcat("that you tried to CHEAT by protecting the directory the savefile\n"); lprcat("is in. Since this is unfair to the rest of the larn community, I\n"); lprcat("cannot let you play this game.\n"); nap(5000); c[GOLD] = c[BANKACCOUNT] = 0; died(-268); return; } SHAR_EOF if test 11426 -ne "`wc -c < 'diag.c'`" then echo shar: error transmitting "'diag.c'" '(should have been 11426 characters)' fi fi # end of overwriting check echo shar: extracting "'display.c'" '(13152 characters)' if test -f 'display.c' then echo shar: will not over-write existing file "'display.c'" else cat << \SHAR_EOF > 'display.c' /* display.c Larn is copyrighted 1986 by Noah Morgan. */ #include "header.h" #define makecode(_a,_b,_c)(((_a)<<16) +((_b)<<8) +(_c)) static int minx,maxx,miny,maxy,k,m; static char bot1f = 0,bot2f = 0,bot3f = 0; char always = 0; /* bottomline() now for the bottom line of the display */ bottomline() { recalc(); bot1f = 1; } bottomhp() { bot2f = 1; } bottomspell() { bot3f = 1; } bottomdo() { if (bot1f) { bot3f = bot1f = bot2f = 0; bot_linex(); return; } if (bot2f) { bot2f = 0; bot_hpx(); } if (bot3f) { bot3f = 0; bot_spellx(); } } bot_linex() { register int i; if (cbak[SPELLS] <= -50 ||(always)) { cursor(1, 18); if (c[SPELLMAX] > 99) lprintf("Spells:%3d(%3d)",(long) c[SPELLS],(long) c[SPELLMAX]); else lprintf("Spells:%3d(%2d) ",(long) c[SPELLS],(long) c[SPELLMAX]); lprintf(" AC: %-3d WC: %-3d Level",(long) c[AC],(long) c[WCLASS]); if (c[LEVEL] > 99) lprintf("%3d",(long) c[LEVEL]); else lprintf(" %-2d",(long) c[LEVEL]); lprintf(" Exp: %-9d %s\n",(long) c[EXPERIENCE], class[c[LEVEL] - 1]); lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ", (long) c[HP],(long) c[HPMAX],(long)(c[STRENGTH] + c[STREXTRA]),(long) c[INTELLIGENCE]); lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:", (long) c[WISDOM],(long) c[CONSTITUTION],(long) c[DEXTERITY],(long) c[CHARISMA]); if ((level == 0) ||(wizard)) c[TELEFLAG] = 0; if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]); lprintf(" Gold: %-6d",(long) c[GOLD]); always = 1; botside(); c[TMP] = c[STRENGTH] + c[STREXTRA]; for (i = 0; i < 100; i++) cbak[i] = c[i]; return; } botsub(makecode(SPELLS, 8, 18), "%3d"); if (c[SPELLMAX] > 99) botsub(makecode(SPELLMAX, 12, 18), "%3d)"); else botsub(makecode(SPELLMAX, 12, 18), "%2d) "); botsub(makecode(HP, 5, 19), "%3d"); botsub(makecode(HPMAX, 9, 19), "%3d"); botsub(makecode(AC, 21, 18), "%-3d"); botsub(makecode(WCLASS, 30, 18), "%-3d"); botsub(makecode(EXPERIENCE, 49, 18), "%-9d"); if (c[LEVEL] != cbak[LEVEL]) { cursor(59, 18); lprcat(class[c[LEVEL] - 1]); } if (c[LEVEL] > 99) botsub(makecode(LEVEL, 40, 18), "%3d"); else botsub(makecode(LEVEL, 40, 18), " %-2d"); c[TMP] = c[STRENGTH] + c[STREXTRA]; botsub(makecode(TMP, 18, 19), "%-2d"); botsub(makecode(INTELLIGENCE, 25, 19), "%-2d"); botsub(makecode(WISDOM, 32, 19), "%-2d"); botsub(makecode(CONSTITUTION, 39, 19), "%-2d"); botsub(makecode(DEXTERITY, 46, 19), "%-2d"); botsub(makecode(CHARISMA, 53, 19), "%-2d"); if ((level != cbak[CAVELEVEL]) ||(c[TELEFLAG] != cbak[TELEFLAG])) { if ((level == 0) ||(wizard)) c[TELEFLAG] = 0; cbak[TELEFLAG] = c[TELEFLAG]; cbak[CAVELEVEL] = level; cursor(59, 19); if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]); } botsub(makecode(GOLD, 69, 19), "%-6d"); botside(); } /* special subroutine to update only the gold number on the bottomlines called from ogold() */ bottomgold() { botsub(makecode(GOLD, 69, 19), "%-6d"); /* botsub(GOLD,"%-6d",69,19); */ } /* special routine to update hp and level fields on bottom lines called in monster.c hitplayer() and spattack() */ bot_hpx() { if (c[EXPERIENCE] != cbak[EXPERIENCE]) { recalc(); bot_linex(); } else botsub(makecode(HP, 5, 19), "%3d"); } /* special routine to update number of spells called from regen() */ bot_spellx() { botsub(makecode(SPELLS, 9, 18), "%2d"); } /* common subroutine for a more economical bottomline() */ static struct bot_side_def { int typ; char *string; } bot_data[] = { STEALTH, "stealth", UNDEADPRO, "undead pro", SPIRITPRO, "spirit pro", CHARMCOUNT, "Charm", TIMESTOP, "Time Stop", HOLDMONST, "Hold Monst", GIANTSTR, "Giant Str", FIRERESISTANCE, "Fire Resit", DEXCOUNT, "Dexterity", STRCOUNT, "Strength", SCAREMONST, "Scare", HASTESELF, "Haste Self", CANCELLATION, "Cancel", INVISIBILITY, "Invisible", ALTPRO, "Protect 3", PROTECTIONTIME, "Protect 2", WTW, "Wall-Walk" }; botside() { register int i,idx; for (i = 0; i < 17; i++) { idx = bot_data[i].typ; if ((always) ||(c[idx] != cbak[idx])) { if ((always) ||(cbak[idx] == 0)) { if (c[idx]) { cursor(70, i + 1); lprcat(bot_data[i].string); } } else if (c[idx] == 0) { cursor(70, i + 1); lprcat(" "); } cbak[idx] = c[idx]; } } always = 0; } static botsub(idx, str) register int idx; char *str; { register int x,y; y = idx & 0xff; x =(idx >> 8) & 0xff; idx >>= 16; if (c[idx] != cbak[idx]) { cbak[idx] = c[idx]; cursor(x, y); lprintf(str,(long) c[idx]); } } /* * subroutine to draw only a section of the screen * only the top section of the screen is updated. If entire lines * are being drawn, then they will be cleared first. */ int d_xmin = 0,d_xmax = MAXX,d_ymin = 0,d_ymax = MAXY; /* for limited screen drawing */ draws(xmin, xmax, ymin, ymax) int xmin,xmax,ymin,ymax; { register int i,idx; if (xmin == 0 && xmax == MAXX) { /* clear section of screen as needed */ if (ymin == 0) cl_up(79, ymax); else for (i = ymin; i < ymin; i++) cl_line(1, i + 1); xmin = -1; } d_xmin = xmin; d_xmax = xmax; d_ymin = ymin; d_ymax = ymax; /* for limited screen drawing */ drawscreen(); if (xmin <= 0 && xmax == MAXX) {/* draw stuff on right side of screen as needed */ for (i = ymin; i < ymax; i++) { idx = bot_data[i].typ; if (c[idx]) { cursor(70, i + 1); lprcat(bot_data[i].string); } cbak[idx] = c[idx]; } } } /* drawscreen() subroutine to redraw the whole screen as the player knows it */ globaldef char screen[MAXX][MAXY]; /* template for the screen */ char d_flag; drawscreen() { register int i,j,k; int lastx,lasty; /* variables used to optimize the object printing */ if (d_xmin == 0 && d_xmax == MAXX && d_ymin == 0 && d_ymax == MAXY) { d_flag = 1; clear(); /* clear the screen */ } else { d_flag = 0; cursor(1, 1); } if (d_xmin < 0) d_xmin = 0; /* d_xmin=-1 means display all without bottomline */ for (i = d_ymin; i < d_ymax; i++) for (j = d_xmin; j < d_xmax; j++) if (know[j][i] == 0) screen[j][i] = ' '; else if (k = mitem[j][i]) screen[j][i] = monstnamelist[k]; else if ((k = item[j][i]) == OWALL) screen[j][i] = '#'; else screen[j][i] = ' '; for (i = d_ymin; i < d_ymax; i++) { j = d_xmin; while ((screen[j][i] == ' ') &&(j < d_xmax)) j++; /* was m=0 */ if (j >= d_xmax) m = d_xmin; /* don't search backwards if blank line */ else { /* search backwards for end of line */ m = d_xmax - 1; while ((screen[m][i] == ' ') &&(m > d_xmin)) --m; if (j <= m) cursor(j + 1, i + 1); else continue; } while (j <= m) { if (j <= m - 3) { for (k = j; k <= j + 3; k++) if (screen[k][i] != ' ') k = 1000; if (k < 1000) { while (screen[j][i] == ' ' && j <= m) j++; cursor(j + 1, i + 1); } } lprc(screen[j++][i]); } } setbold(); /* print out only bold objects now */ for (lastx = lasty = 127, i = d_ymin; i < d_ymax; i++) for (j = d_xmin; j < d_xmax; j++) { if (k = item[j][i]) if (k != OWALL) if ((know[j][i]) &&(mitem[j][i] == 0)) if (objnamelist[k] != ' ') { if (lasty != i + 1 || lastx != j) cursor(lastx = j + 1, lasty = i + 1); else lastx++; lprc(objnamelist[k]); } } resetbold(); if (d_flag) { always = 1; botside(); always = 1; bot_linex(); } oldx = 99; d_xmin = 0, d_xmax = MAXX, d_ymin = 0, d_ymax = MAXY;/* for limited screen drawing */ } /* showcell(x,y) subroutine to display a cell location on the screen */ showcell(x, y) int x,y; { register int i,j,k,m; if (c[BLINDCOUNT]) return; /* see nothing if blind */ if (c[AWARENESS]) { minx = x - 3; maxx = x + 3; miny = y - 3; maxy = y + 3; } else { minx = x - 1; maxx = x + 1; miny = y - 1; maxy = y + 1; } if (minx < 0) minx = 0; if (maxx > MAXX - 1) maxx = MAXX - 1; if (miny < 0) miny = 0; if (maxy > MAXY - 1) maxy = MAXY - 1; for (j = miny; j <= maxy; j++) for (m = minx; m <= maxx; m++) if (know[m][j] == 0) { cursor(m + 1, j + 1); x = maxx; while (know[x][j]) --x; for (i = m; i <= x; i++) { if ((k = mitem[i][j]) != 0) lprc(monstnamelist[k]); else switch(k = item[i][j]) { case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: case OIVDARTRAP: case OIVTRAPDOOR: lprc(objnamelist[k]); break; default: setbold(); lprc(objnamelist[k]); resetbold(); }; know[i][j] = 1; } m = maxx; } } /* this routine shows only the spot that is given it. the spaces around these coordinated are not shown used in godirect() in monster.c for missile weapons display */ show1cell(x, y) int x,y; { if (c[BLINDCOUNT]) return; /* see nothing if blind */ cursor(x + 1, y + 1); if ((k = mitem[x][y]) != 0) lprc(monstnamelist[k]); else switch(k = item[x][y]) { case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: case OIVDARTRAP: case OIVTRAPDOOR: lprc(objnamelist[k]); break; default: setbold(); lprc(objnamelist[k]); resetbold(); }; know[x][y] |= 1; /* we end up knowing about it */ } /* showplayer() subroutine to show where the player is on the screen cursor values start from 1 up */ showplayer() { cursor(playerx + 1, playery + 1); oldx = playerx; oldy = playery; } /* moveplayer(dir) subroutine to move the player from one room to another returns 0 if can't move in that direction or hit a monster or on an object else returns 1 nomove is set to 1 to stop the next move(inadvertent monsters hitting players when walking into walls) if player walks off screen or into wall */ globaldef short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 }; globaldef short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 }; moveplayer(dir) int dir; /* from = present room # direction = [1-north] [2-east] [3-south] [4-west] [5-northeast] [6-northwest] [7-southeast] [8-southwest] if direction=0, don't move--just show where he is */ { register int k,m,i,j; if (c[CONFUSE]) if (c[LEVEL] < rnd(30)) dir = rund(9); /* if confused any dir */ k = playerx + diroffx[dir]; m = playery + diroffy[dir]; if (k < 0 || k >= MAXX || m < 0 || m >= MAXY) { nomove = 1; return(yrepcount = 0); } i = item[k][m]; j = mitem[k][m]; if (i == OWALL && c[WTW] == 0) { nomove = 1; return(yrepcount = 0); } /* hit a wall */ if (k == 33 && m == MAXY - 1 && level == 1) { newcavelevel(0); for (k = 0; k < MAXX; k++) for (m = 0; m < MAXY; m++) if (item[k][m] == OENTRANCE) { playerx = k; playery = m; positionplayer(); drawscreen(); return(0); } } if (j > 0) { hitmonster(k, m); return(yrepcount = 0); } /* hit a monster */ lastpx = playerx; lastpy = playery; playerx = k; playery = m; if (i && i != OTRAPARROWIV && i != OIVTELETRAP && i != OIVDARTRAP && i != OIVTRAPDOOR) return(yrepcount = 0); else return(1); } /* * function to show what magic items have been discovered thus far * enter with -1 for just spells, anything else will give scrolls & potions */ static int lincount,count; seemagic(arg) int arg; { register int i,number; count = lincount = 0; nosignal = 1; if (arg == -1) { /* if display spells while casting one */ for (number = i = 0; i < SPNUM; i++) if (spelknow[i]) number++; number =(number + 2) / 3 + 4;/* # lines needed to display */ cl_up(79, number); cursor(1, 1); } else { resetscroll(); clear(); } lprcat("The magic spells you have discovered thus far:\n\n"); for (i = 0; i < SPNUM; i++) if (spelknow[i]) { lprintf("%s %-20s ", spelcode[i], spelname[i]); seepage(); } if (arg == -1) { seepage(); more(); nosignal = 0; draws(0, MAXX, 0, number); return; } lincount += 3; if (count != 0) { count = 2; seepage(); } lprcat("\nThe magic scrolls you have found to date are:\n\n"); count = 0; for (i = 0; i < MAXSCROLL; i++) if (scrollname[i][0]) if (scrollname[i][1] != ' ') { lprintf("%-26s", &scrollname[i][1]); seepage(); } lincount += 3; if (count != 0) { count = 2; seepage(); } lprcat("\nThe magic potions you have found to date are:\n\n"); count = 0; for (i = 0; i < MAXPOTION; i++) if (potionname[i][0]) if (potionname[i][1] != ' ') { lprintf("%-26s", &potionname[i][1]); seepage(); } if (lincount != 0) more(); nosignal = 0; setscroll(); drawscreen(); } /* * subroutine to paginate the seemagic function */ seepage() { if (++count == 3) { lincount++; count = 0; lprc('\n'); if (lincount > 17) { lincount = 0; more(); clear(); } } } SHAR_EOF if test 13152 -ne "`wc -c < 'display.c'`" then echo shar: error transmitting "'display.c'" '(should have been 13152 characters)' fi fi # end of overwriting check echo shar: extracting "'fortune.c'" '(1991 characters)' if test -f 'fortune.c' then echo shar: will not over-write existing file "'fortune.c'" else cat << \SHAR_EOF > 'fortune.c' /* fortune.c Larn is copyrighted 1986 by Noah Morgan. */ #include #include #include "header.h" /* * function to return a random fortune from the fortune file */ static char *base = 0; /* pointer to the fortune text */ static char **flines = 0; /* array of pointers to each fortune */ static int fd = 0; /* true if we have load the fortune info */ static int nlines = 0; /* # lines in fortune database */ char *fortune (file) char *file; { register char *p, *bptr; register int lines,tmp,i; struct stat stat; char *malloc (); if (fd == 0) { if ((fd = open (file, O_RDONLY)) < 0)/* open the file */ return (0); /* can't find file */ /* find out how big fortune file is and get memory for it */ stat.st_size = 16384; if ((fstat (fd, &stat) < 0) || ((base = malloc (1 + stat.st_size)) == 0)) { close (fd); fd = -1; free ((char *) base); return (0); /* can't stat file */ } /* read in the entire fortune file */ bptr = base; while ((i = read(fd,bptr,stat.st_size)) > 0) bptr += i; if (bptr == base) { close (fd); fd = -1; free ((char *) base); return (0); /* can't read file */ } close (fd); base[stat.st_size] = 0; /* final NULL termination */ /* count up all the lines (and NULL terminate) to know memory needs */ for (p = base, lines = 0; p < base + stat.st_size; p++)/* count lines */ if (*p == '\n') *p = 0, lines++; nlines = lines; /* get memory for array of pointers to each fortune */ if ((flines = (char **) malloc (nlines * sizeof (char *))) == 0) { free ((char *) base); fd = -1; return (0); /* malloc() failure */ } /* now assign each pointer to a line */ for (p = base, tmp = 0; tmp < nlines; tmp++) { flines[tmp] = p; while (*p++); /* advance to next line */ } } if (fd > 2) /* if we have a database to look at */ return (flines[rund ((nlines <= 0) ? 1 : nlines)]); else return (0); } SHAR_EOF if test 1991 -ne "`wc -c < 'fortune.c'`" then echo shar: error transmitting "'fortune.c'" '(should have been 1991 characters)' fi fi # end of overwriting check echo shar: extracting "'global.c'" '(16893 characters)' if test -f 'global.c' then echo shar: will not over-write existing file "'global.c'" else cat << \SHAR_EOF > 'global.c' /* global.c Larn is copyrighted 1986 by Noah Morgan. * * raiselevel() subroutine to raise the player one level * loselevel() subroutine to lower the player by one level * raiseexperience(x) subroutine to increase experience points * loseexperience(x) subroutine to lose experience points * losehp(x) subroutine to remove hit points from the player * losemhp(x) subroutine to remove max # hit points from the player * raisehp(x) subroutine to gain hit points * raisemhp(x) subroutine to gain maximum hit points * losespells(x) subroutine to lose spells * losemspells(x) subroutine to lose maximum spells * raisespells(x) subroutine to gain spells * raisemspells(x) subroutine to gain maximum spells * recalc() function to recalculate the armor class of the player * makemonst(lev) function to return monster number for a randomly selected monster * positionplayer() function to be sure player is not in a wall * quit() subroutine to ask if the player really wants to quit */ #include "header.h" extern int score[],dropflag; extern int random; /* the random number seed */ extern char *what[],*who[]; extern char winner[]; extern char sciv[SCORESIZE + 1][26][2]; /* *********** RAISE LEVEL *********** raiselevel() subroutine to raise the player one level uses the skill[] array to find level boundarys uses c[EXPERIENCE] c[LEVEL] */ raiselevel() { if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]] - c[EXPERIENCE])); } /* *********** LOOSE LEVEL *********** loselevel() subroutine to lower the players character level by one */ loselevel() { if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL] - 1] + 1)); } /* **************** RAISE EXPERIENCE **************** raiseexperience(x) subroutine to increase experience points */ raiseexperience(x) register long x; { register int i,tmp; i = c[LEVEL]; c[EXPERIENCE] += x; while (c[EXPERIENCE] >= skill[c[LEVEL]] &&(c[LEVEL] < MAXPLEVEL)) { tmp =(c[CONSTITUTION] - c[HARDGAME]) >> 1; c[LEVEL]++; raisemhp((int)(rnd(3) + rnd((tmp > 0) ? tmp : 1))); raisemspells((int) rund(3)); if (c[LEVEL] < 7 - c[HARDGAME]) raisemhp((int)(c[CONSTITUTION] >> 2)); } if (c[LEVEL] != i) { cursors(); beep(); lprintf("\nWelcome to level %d",(long) c[LEVEL]);/* if we changed levels */ } bottomline(); } /* **************** LOOSE EXPERIENCE **************** loseexperience(x) subroutine to lose experience points */ loseexperience(x) register long x; { register int i,tmp; i = c[LEVEL]; c[EXPERIENCE] -= x; if (c[EXPERIENCE] < 0) c[EXPERIENCE] = 0; while (c[EXPERIENCE] < skill[c[LEVEL] - 1]) { if (--c[LEVEL] <= 1) c[LEVEL] = 1; /* down one level */ tmp =(c[CONSTITUTION] - c[HARDGAME]) >> 1;/* lose hpoints */ losemhp((int) rnd((tmp > 0) ? tmp : 1));/* lose hpoints */ if (c[LEVEL] < 7 - c[HARDGAME]) losemhp((int)(c[CONSTITUTION] >> 2)); losemspells((int) rund(3));/* lose spells */ } if (i != c[LEVEL]) { cursors(); beep(); lprintf("\nYou went down to level %d!",(long) c[LEVEL]); } bottomline(); } /* ******** LOOSE HP ******** losehp(x) losemhp(x) subroutine to remove hit points from the player warning -- will kill player if hp goes to zero */ losehp(x) register int x; { if ((c[HP] -= x) <= 0) { beep(); lprcat("\n"); nap(3000); died(lastnum); } } losemhp(x) register int x; { c[HP] -= x; if (c[HP] < 1) c[HP] = 1; c[HPMAX] -= x; if (c[HPMAX] < 1) c[HPMAX] = 1; } /* ******** RAISE HP ******** raisehp(x) raisemhp(x) subroutine to gain maximum hit points */ raisehp(x) register int x; { if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX]; } raisemhp(x) register int x; { c[HPMAX] += x; c[HP] += x; } /* ************ RAISE SPELLS ************ raisespells(x) raisemspells(x) subroutine to gain maximum spells */ raisespells(x) register int x; { if ((c[SPELLS] += x) > c[SPELLMAX]) c[SPELLS] = c[SPELLMAX]; } raisemspells(x) register int x; { c[SPELLMAX] += x; c[SPELLS] += x; } /* ************ LOOSE SPELLS ************ losespells(x) losemspells(x) subroutine to lose maximum spells */ losespells(x) register int x; { if ((c[SPELLS] -= x) < 0) c[SPELLS] = 0; } losemspells(x) register int x; { if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX] = 0; if ((c[SPELLS] -= x) < 0) c[SPELLS] = 0; } /* makemonst(lev) int lev; function to return monster number for a randomly selected monster for the given cave level */ makemonst(lev) register int lev; { register int tmp,x; if (lev < 1) lev = 1; if (lev > 12) lev = 12; tmp = WATERLORD; if (lev < 5) while (tmp == WATERLORD) tmp = rnd((x = monstlevel[lev - 1]) ? x : 1); else while (tmp == WATERLORD) tmp = rnd((x = monstlevel[lev - 1] - monstlevel[lev - 4]) ? x : 1) + monstlevel[lev - 4]; while (monster[tmp].genocided && tmp < MAXMONST) tmp++; /* genocided? */ return(tmp); } /* positionplayer() function to be sure player is not in a wall */ positionplayer() { int try = 2; while ((item[playerx][playery] || mitem[playerx][playery]) &&(try)) if (++playerx >= MAXX - 1) { playerx = 1; if (++playery >= MAXY - 1) { playery = 1; --try; } } if (try == 0) lprcat("Failure in positionplayer\n"); } /* recalc() function to recalculate the armor class of the player */ recalc() { register int i,j,k; c[AC] = c[MOREDEFENSES]; if (c[WEAR] >= 0) switch(iven[c[WEAR]]) { case OSHIELD: c[AC] += 2 + ivenarg[c[WEAR]]; break; case OLEATHER: c[AC] += 2 + ivenarg[c[WEAR]]; break; case OSTUDLEATHER: c[AC] += 3 + ivenarg[c[WEAR]]; break; case ORING: c[AC] += 5 + ivenarg[c[WEAR]]; break; case OCHAIN: c[AC] += 6 + ivenarg[c[WEAR]]; break; case OSPLINT: c[AC] += 7 + ivenarg[c[WEAR]]; break; case OPLATE: c[AC] += 9 + ivenarg[c[WEAR]]; break; case OPLATEARMOR: c[AC] += 10 + ivenarg[c[WEAR]]; break; case OSSPLATE: c[AC] += 12 + ivenarg[c[WEAR]]; break; } if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]]; if (c[WIELD] < 0) c[WCLASS] = 0; else { i = ivenarg[c[WIELD]]; switch(iven[c[WIELD]]) { case ODAGGER: c[WCLASS] = 3 + i; break; case OBELT: c[WCLASS] = 7 + i; break; case OSHIELD: c[WCLASS] = 8 + i; break; case OSPEAR: c[WCLASS] = 10 + i; break; case OFLAIL: c[WCLASS] = 14 + i; break; case OBATTLEAXE: c[WCLASS] = 17 + i; break; case OLANCE: c[WCLASS] = 19 + i; break; case OLONGSWORD: c[WCLASS] = 22 + i; break; case O2SWORD: c[WCLASS] = 26 + i; break; case OSWORD: c[WCLASS] = 32 + i; break; case OSWORDofSLASHING: c[WCLASS] = 30 + i; break; case OHAMMER: c[WCLASS] = 35 + i; break; default: c[WCLASS] = 0; } } c[WCLASS] += c[MOREDAM]; /* now for regeneration abilities based on rings */ c[REGEN] = 1; c[ENERGY] = 0; j = 0; for (k = 25; k > 0; k--) if (iven[k]) { j = k; k = 0; } for (i = 0; i <= j; i++) { switch(iven[i]) { case OPROTRING: c[AC] += ivenarg[i] + 1; break; case ODAMRING: c[WCLASS] += ivenarg[i] + 1; break; case OBELT: c[WCLASS] +=((ivenarg[i] << 1)) + 2; break; case OREGENRING: c[REGEN] += ivenarg[i] + 1; break; case ORINGOFEXTRA: c[REGEN] += 5 *(ivenarg[i] + 1); break; case OENERGYRING: c[ENERGY] += ivenarg[i] + 1; break; } } } /* quit() subroutine to ask if the player really wants to quit */ quit() { register int i, was_on = 1; cursors(); if (!Check_KeySense()) { scbr(); was_on = 0; } strcpy(lastmonst, ""); lprcat("\n\nDo you really want to quit?"); while (1) { i = readchar(); if (i == 'y') { died(300); return; } if ((i == 'n') ||(i == '\33')) { lprcat(" no"); lflush(); return; } lprcat("\n"); setbold(); lprcat("Yes"); resetbold(); lprcat(" or "); setbold(); lprcat("No"); resetbold(); lprcat(" please? Do you want to quit? "); } if (!was_on) sncbr(); } /* function to ask --more-- then the user must enter a space */ more() { lprcat("\n --- press "); standout("space"); lprcat(" to continue --- "); while (readchar() != ' '); } /* function to put something in the players inventory returns 0 if success, 1 if a failure */ take(itm, arg) int itm,arg; { register int i,limit; if ((limit = 15 +(c[LEVEL] >> 1)) > 26) limit = 26; for (i = 0; i < limit; i++) if (iven[i] == 0) { iven[i] = itm; ivenarg[i] = arg; limit = 0; switch(itm) { case OPROTRING: case ODAMRING: case OBELT: limit = 1; break; case ODEXRING: c[DEXTERITY] += ivenarg[i] + 1; limit = 1; break; case OSTRRING: c[STREXTRA] += ivenarg[i] + 1; limit = 1; break; case OCLEVERRING: c[INTELLIGENCE] += ivenarg[i] + 1; limit = 1; break; case OHAMMER: c[DEXTERITY] += 10; c[STREXTRA] += 10; c[INTELLIGENCE] -= 10; limit = 1; break; case OORBOFDRAGON: c[SLAYING]++; break; case OSPIRITSCARAB: c[NEGATESPIRIT]++; break; case OCUBEofUNDEAD: c[CUBEofUNDEAD]++; break; case ONOTHEFT: c[NOTHEFT]++; break; case OSWORDofSLASHING: c[DEXTERITY] += 5; limit = 1; break; }; lprcat("\nYou pick up:"); srcount = 0; show3(i); if (limit) bottomline(); return(0); } lprcat("\nYou can't carry anything else"); return(1); } /* subroutine to drop an object returns 1 if something there already else 0 */ drop_object(k) int k; { int itm; if ((k < 0) ||(k > 25)) return(0); itm = iven[k]; cursors(); if (itm == 0) { lprintf("\nYou don't have item %c! ", k + 'a'); return(1); } if (item[playerx][playery]) { beep(); lprcat("\nThere's something here already"); return(1); } if (playery == MAXY - 1 && playerx == 33) return(1); /* not in entrance */ item[playerx][playery] = itm; iarg[playerx][playery] = ivenarg[k]; srcount = 0; lprcat("\n You drop:"); show3(k); /* show what item you dropped */ know[playerx][playery] = 0; iven[k] = 0; if (c[WIELD] == k) c[WIELD] = -1; if (c[WEAR] == k) c[WEAR] = -1; if (c[SHIELD] == k) c[SHIELD] = -1; adjustcvalues(itm, ivenarg[k]); dropflag = 1; /* say dropped an item so wont ask to pick it up right away */ return(0); } /* function to enchant armor player is currently wearing */ enchantarmor() { register int tmp; if (c[WEAR] < 0) { if (c[SHIELD] < 0) { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; } else { tmp = iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } } tmp = iven[c[WEAR]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[WEAR]]++; bottomline(); } } /* function to enchant a weapon presently being wielded */ enchweapon() { register int tmp; if (c[WIELD] < 0) { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; } tmp = iven[c[WIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[WIELD]]++; if (tmp == OCLEVERRING) c[INTELLIGENCE]++; else if (tmp == OSTRRING) c[STREXTRA]++; else if (tmp == ODEXRING) c[DEXTERITY]++; bottomline(); } } /* routine to tell if player can carry one more thing returns 1 if pockets are full, else 0 */ pocketfull() { register int i,limit; if ((limit = 15 +(c[LEVEL] >> 1)) > 26) limit = 26; for (i = 0; i < limit; i++) if (iven[i] == 0) return(0); return(1); } /* function to return 1 if a monster is next to the player else returns 0 */ nearbymonst() { register int tmp,tmp2; for (tmp = playerx - 1; tmp < playerx + 2; tmp++) for (tmp2 = playery - 1; tmp2 < playery + 2; tmp2++) if (mitem[tmp][tmp2]) return(1); /* if monster nearby */ return(0); } /* function to steal an item from the players pockets returns 1 if steals something else returns 0 */ stealsomething() { register int i,j = 100; while (1) { i = rund(26); if (iven[i]) if (c[WEAR] != i) if (c[WIELD] != i) if (c[SHIELD] != i) { srcount = 0; show3(i); adjustcvalues(iven[i], ivenarg[i]); iven[i] = 0; return(1); } if (--j <= 0) return(0); } } /* function to return 1 is player carrys nothing else return 0 */ emptyhanded() { register int i; for (i = 0; i < 26; i++) if (iven[i]) if (i != c[WIELD]) if (i != c[WEAR]) if (i != c[SHIELD]) return(0); return(1); } /* function to create a gem on a square near the player */ creategem() { register int i,j; switch(rnd(4)) { case 1: i = ODIAMOND; j = 50; break; case 2: i = ORUBY; j = 40; break; case 3: i = OEMERALD; j = 30; break; default: i = OSAPPHIRE; j = 20; break; }; createitem(i, rnd(j) + j / 10); } /* function to change character levels as needed when dropping an object that affects these characteristics */ adjustcvalues(itm, arg) int itm,arg; { register int flag = 0; switch(itm) { case ODEXRING: c[DEXTERITY] -= arg + 1; flag = 1; break; case OSTRRING: c[STREXTRA] -= arg + 1; flag = 1; break; case OCLEVERRING: c[INTELLIGENCE] -= arg + 1; flag = 1; break; case OHAMMER: c[DEXTERITY] -= 10; c[STREXTRA] -= 10; c[INTELLIGENCE] += 10; flag = 1; break; case OSWORDofSLASHING: c[DEXTERITY] -= 5; flag = 1; break; case OORBOFDRAGON: --c[SLAYING]; return; case OSPIRITSCARAB: --c[NEGATESPIRIT]; return; case OCUBEofUNDEAD: --c[CUBEofUNDEAD]; return; case ONOTHEFT: --c[NOTHEFT]; return; case OLANCE: c[LANCEDEATH] = 0; return; case OPOTION: case OSCROLL: return; default: flag = 1; }; if (flag) bottomline(); } /* function to read a string from token input "string" returns a pointer to the string */ gettokstr(str) register char *str; { register int i = 50,j; while ((readchar() != '"') &&(--i > 0)); i = 36; while (--i > 0) { if ((j = readchar()) != '"') *str++ = j; else i = 0; } *str = 0; i = 50; if (j != '"') while ((readchar() != '"') &&(--i > 0));/* if end due to too long, then find closing quote */ } /* function to ask user for a password(no echo) returns 1 if entered correctly, 0 if not */ static char gpwbuf[33]; getpassword() { register int i,j; register char *gpwp; globalref char *password; scbr(); /* system("stty -echo cbreak"); */ gpwp = gpwbuf; lprcat("\nEnter Password: "); lflush(); i = strlen(password); for (j = 0; j < i; j++) *(gpwp++) = readchar(); gpwbuf[i] = 0; sncbr(); /* system("stty echo -cbreak"); */ if (strcmp(gpwbuf, password) != 0) { lprcat("\nSorry\n"); lflush(); return(0); } else return(1); } /* subroutine to get a yes or no response from the user returns y or n */ getyn() { register int i = 0; while (i != 'y' && i != 'n' && i != '\33') i = readchar(); return(i); } /* function to calculate the pack weight of the player returns the number of pounds the player is carrying */ packweight() { register int i,j,k; k = c[GOLD] / 1000; j = 25; while ((iven[j] == 0) &&(j > 0)) --j; for (i = 0; i <= j; i++) switch(iven[i]) { case 0: break; case OSSPLATE: case OPLATEARMOR: k += 40; break; case OPLATE: k += 35; break; case OHAMMER: k += 30; break; case OSPLINT: k += 26; break; case OSWORDofSLASHING: case OCHAIN: case OBATTLEAXE: case O2SWORD: k += 23; break; case OLONGSWORD: case OSWORD: case ORING: case OFLAIL: k += 20; break; case OLANCE: case OSTUDLEATHER: k += 15; break; case OLEATHER: case OSPEAR: k += 8; break; case OORBOFDRAGON: case OBELT: k += 4; break; case OSHIELD: k += 7; break; case OCHEST: k += 30 + ivenarg[i]; break; default: k++; }; return(k); } #ifndef MACRORND /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */ rnd(x) int x; { return((((rand_x = rand_x * 1103515245 + 12345) >> 7) %(x)) + 1); } rund(x) int x; { return((((rand_x = rand_x * 1103515245 + 12345) >> 7) %(x))); } #endif MACRORND SHAR_EOF if test 16893 -ne "`wc -c < 'global.c'`" then echo shar: error transmitting "'global.c'" '(should have been 16893 characters)' fi fi # end of overwriting check echo shar: extracting "'header.h'" '(12521 characters)' if test -f 'header.h' then echo shar: will not over-write existing file "'header.h'" else cat << \SHAR_EOF > 'header.h' /* header.h Larn is copyrighted 1986 by Noah Morgan. */ #define SCORENAME "LARN12.SCR" #define LOGFNAME "LARN12.LOG" #define HELPNAME "LARN12.HLP" #define LEVELSNAME "LARN12.MAZ" #define FORTSNAME "LARN12.FTN" #define PLAYERIDS "LARN12.IDS" #define HOLIFILE "LARN12.HDY" #define MAXLEVEL 11 /* max # levels in the dungeon */ #define MAXVLEVEL 3 /* max # of levels in the temple of the luran */ #define MAXX 67 #define MAXY 17 #define SCORESIZE 10 /* this is the number of people on a scoreboard max */ #define MAXPLEVEL 100 /* maximum player level allowed */ #define MAXMONST 56 /* maximum # monsters in the dungeon */ #define SPNUM 38 /* maximum number of spells in existance */ #define MAXSCROLL 28 /* maximum number of scrolls that are possible */ #define MAXPOTION 35 /* maximum number of potions that are possible */ #define TIMELIMIT 30000 /* the maximum number of moves before the game is called */ #define TAXRATE 1/20 /* the tax rate for the LRS */ #define MAXOBJ 93 /* the maximum number of objects n < MAXOBJ */ /* this is the structure definition of the monster data */ struct monst { char *name; char level; short armorclass; char damage; char attack; char defense; char genocided; char intelligence; /* monsters intelligence -- used to choose movement */ short gold; short hitpoints; unsigned long experience; }; /* this is the structure definition for the items in the dnd store */ struct _itm { short price; char **mem; char obj; char arg; char qty; }; /* this is the structure that holds the entire dungeon specifications */ struct cel { short hitp; /* monster's hit points */ char mitem; /* the monster ID */ char item; /* the object's ID */ short iarg; /* the object's argument */ char know; /* have we been here before */ }; /* this is the structure for maintaining & moving the spheres of annihilation */ struct sphere { struct sphere *p; /* pointer to next structure */ char x,y,lev; /* location of the sphere */ char dir; /* direction sphere is going in */ char lifetime; /* duration of the sphere */ }; /* defines for the character attribute array c[] */ #define STRENGTH 0 /* characters physical strength not due to objects */ #define INTELLIGENCE 1 #define WISDOM 2 #define CONSTITUTION 3 #define DEXTERITY 4 #define CHARISMA 5 #define HPMAX 6 #define HP 7 #define GOLD 8 #define EXPERIENCE 9 #define LEVEL 10 #define REGEN 11 #define WCLASS 12 #define AC 13 #define BANKACCOUNT 14 #define SPELLMAX 15 #define SPELLS 16 #define ENERGY 17 #define ECOUNTER 18 #define MOREDEFENSES 19 #define WEAR 20 #define PROTECTIONTIME 21 #define WIELD 22 #define AMULET 23 #define REGENCOUNTER 24 #define MOREDAM 25 #define DEXCOUNT 26 #define STRCOUNT 27 #define BLINDCOUNT 28 #define CAVELEVEL 29 #define CONFUSE 30 #define ALTPRO 31 #define HERO 32 #define CHARMCOUNT 33 #define INVISIBILITY 34 #define CANCELLATION 35 #define HASTESELF 36 #define EYEOFLARN 37 #define AGGRAVATE 38 #define GLOBE 39 #define TELEFLAG 40 #define SLAYING 41 #define NEGATESPIRIT 42 #define SCAREMONST 43 #define AWARENESS 44 #define HOLDMONST 45 #define TIMESTOP 46 #define HASTEMONST 47 #define CUBEofUNDEAD 48 #define GIANTSTR 49 #define FIRERESISTANCE 50 #define BESSMANN 51 #define NOTHEFT 52 #define HARDGAME 53 #define CPUTIME 54 #define BYTESIN 55 #define BYTESOUT 56 #define MOVESMADE 57 #define MONSTKILLED 58 #define SPELLSCAST 59 #define LANCEDEATH 60 #define SPIRITPRO 61 #define UNDEADPRO 62 #define SHIELD 63 #define STEALTH 64 #define ITCHING 65 #define LAUGHING 66 #define DRAINSTRENGTH 67 #define CLUMSINESS 68 #define INFEEBLEMENT 69 #define HALFDAM 70 #define SEEINVISIBLE 71 #define FILLROOM 72 #define RANDOMWALK 73 #define SPHCAST 74 /* nz if an active sphere of annihilation */ #define WTW 75 /* walk through walls */ #define STREXTRA 76 /* character strength due to objects or enchantments */ #define TMP 77 /* misc scratch space */ #define LIFEPROT 78 /* life protection counter */ /* defines for the objects in the game */ #define OALTAR 1 #define OTHRONE 2 #define OORB 3 #define OPIT 4 #define OSTAIRSUP 5 #define OELEVATORUP 6 #define OFOUNTAIN 7 #define OSTATUE 8 #define OTELEPORTER 9 #define OSCHOOL 10 #define OMIRROR 11 #define ODNDSTORE 12 #define OSTAIRSDOWN 13 #define OELEVATORDOWN 14 #define OBANK2 15 #define OBANK 16 #define ODEADFOUNTAIN 17 #define OMAXGOLD 70 #define OGOLDPILE 18 #define OOPENDOOR 19 #define OCLOSEDDOOR 20 #define OWALL 21 #define OTRAPARROW 66 #define OTRAPARROWIV 67 #define OLARNEYE 22 #define OPLATE 23 #define OCHAIN 24 #define OLEATHER 25 #define ORING 60 #define OSTUDLEATHER 61 #define OSPLINT 62 #define OPLATEARMOR 63 #define OSSPLATE 64 #define OSHIELD 68 #define OELVENCHAIN 92 #define OSWORDofSLASHING 26 #define OHAMMER 27 #define OSWORD 28 #define O2SWORD 29 #define OSPEAR 30 #define ODAGGER 31 #define OBATTLEAXE 57 #define OLONGSWORD 58 #define OFLAIL 59 #define OLANCE 65 #define OVORPAL 90 #define OSLAYER 91 #define ORINGOFEXTRA 32 #define OREGENRING 33 #define OPROTRING 34 #define OENERGYRING 35 #define ODEXRING 36 #define OSTRRING 37 #define OCLEVERRING 38 #define ODAMRING 39 #define OBELT 40 #define OSCROLL 41 #define OPOTION 42 #define OBOOK 43 #define OCHEST 44 #define OAMULET 45 #define OORBOFDRAGON 46 #define OSPIRITSCARAB 47 #define OCUBEofUNDEAD 48 #define ONOTHEFT 49 #define ODIAMOND 50 #define ORUBY 51 #define OEMERALD 52 #define OSAPPHIRE 53 #define OENTRANCE 54 #define OVOLDOWN 55 #define OVOLUP 56 #define OHOME 69 #define OKGOLD 71 #define ODGOLD 72 #define OIVDARTRAP 73 #define ODARTRAP 74 #define OTRAPDOOR 75 #define OIVTRAPDOOR 76 #define OTRADEPOST 77 #define OIVTELETRAP 78 #define ODEADTHRONE 79 #define OANNIHILATION 80 /* sphere of annihilation */ #define OTHRONE2 81 #define OLRS 82 /* Larn Revenue Service */ #define OCOOKIE 83 #define OURN 84 #define OBRASSLAMP 85 #define OHANDofFEAR 86 /* hand of fear */ #define OSPHTAILSMAN 87 /* tailsman of the sphere */ #define OWWAND 88 /* wand of wonder */ #define OPSTAFF 89 /* staff of power */ /* used up to 92 */ /* defines for the monsters as objects */ #define BAT 1 #define GNOME 2 #define HOBGOBLIN 3 #define JACKAL 4 #define KOBOLD 5 #define ORC 6 #define SNAKE 7 #define CENTIPEDE 8 #define JACULI 9 #define TROGLODYTE 10 #define ANT 11 #define EYE 12 #define LEPRECHAUN 13 #define NYMPH 14 #define QUASIT 15 #define RUSTMONSTER 16 #define ZOMBIE 17 #define ASSASSINBUG 18 #define BUGBEAR 19 #define HELLHOUND 20 #define ICELIZARD 21 #define CENTAUR 22 #define TROLL 23 #define YETI 24 #define WHITEDRAGON 25 #define ELF 26 #define CUBE 27 #define METAMORPH 28 #define VORTEX 29 #define ZILLER 30 #define VIOLETFUNGI 31 #define WRAITH 32 #define FORVALAKA 33 #define LAMANOBE 34 #define OSEQUIP 35 #define ROTHE 36 #define XORN 37 #define VAMPIRE 38 #define INVISIBLESTALKER 39 #define POLTERGEIST 40 #define DISENCHANTRESS 41 #define SHAMBLINGMOUND 42 #define YELLOWMOLD 43 #define UMBERHULK 44 #define GNOMEKING 45 #define MIMIC 46 #define WATERLORD 47 #define BRONZEDRAGON 48 #define GREENDRAGON 49 #define PURPLEWORM 50 #define XVART 51 #define SPIRITNAGA 52 #define SILVERDRAGON 53 #define PLATINUMDRAGON 54 #define GREENURCHIN 55 #define REDDRAGON 56 #define DEMONLORD 57 #define DEMONPRINCE 64 #define NULL 0 #define BUFBIG 4096 /* size of the output buffer */ #define MAXIBUF 4096 /* size of the input buffer */ #define LOGNAMESIZE 40 /* max size of the players name */ #define SAVEFILENAMESIZE 128 /* max size of the savefile path */ #ifndef NODEFS globalref char VERSION,SUBVERSION; globalref char *aborted,beenhere[MAXLEVEL+MAXVLEVEL],boldon,cheat,ckpfile[]; globalref char ckpflag; globalref char *class[],course[],diagfile[],fortfile[],helpfile[],holifile[]; globalref char *inbuffer,is_alpha[],is_digit[]; globalref char item[MAXX][MAXY],iven[],know[MAXX][MAXY],larnlevels[],lastmonst[]; globalref char level,*levelname[],logfile[],loginname[],logname[],*lpbuf,*lpend; globalref char *lpnt,moved[MAXX][MAXY],mitem[MAXX][MAXY],monstlevel[]; globalref char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome; globalref char nplt[],nsw[],*objectname[]; globalref char objnamelist[],optsfile[],*potionname[],playerids[],potprob[]; globalref char predostuff,restorflag,savefilename[],scorefile[],scprob[]; globalref char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[]; globalref char *speldescript[],spelknow[],*spelname[],*spelmes[]; globalref char spelweird[MAXMONST+8][SPNUM]; globalref char splev[],stealth[MAXX][MAXY],to_lower[],to_upper[],wizard; globalref short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY]; globalref short iarg[MAXX][MAXY],ivenarg[26],lasthx,lasthy,lastnum; globalref short lastpx,lastpy,nobeep,oldx,oldy,playerx,playery; globalref int dayplay,enable_scroll,srcount,yrepcount,userid,wisid,lfd,fd; globalref long initialtime,outstanding_taxes,skill[],gtime,c[100],cbak[100]; globalref long start_cpu; globalref unsigned long rand_x; globalref struct cel cell[(MAXLEVEL+MAXVLEVEL) * MAXX * MAXY]; globalref struct monst monster[]; globalref struct sphere *spheres; globalref struct _itm itm[90]; extern char *fortune(),*malloc(),*getenv(),*getlogin(),*lgetw(),*lgetl(),*ctime(); #ifndef VT100 extern char *tmcapcnv(),*tgetstr(),*tgoto(); #endif VT100 extern long paytaxes(),lgetc(),lrint(),time(); extern unsigned long readnum(); /* macro to create scroll #'s with probability of occurrence */ #define newscroll() (scprob[rund(81)]) /* macro to return a potion # created with probability of occurrence */ #define newpotion() (potprob[rund(41)]) /* macro to return the + points on created leather armor */ #define newleather() (nlpts[rund(c[HARDGAME]?13:15)]) /* macro to return the + points on chain armor */ #define newchain() (nch[rund(10)]) /* macro to return + points on plate armor */ #define newplate() (nplt[rund(c[HARDGAME]?4:12)]) /* macro to return + points on new daggers */ #define newdagger() (ndgg[rund(13)]) /* macro to return + points on new swords */ #define newsword() (nsw[rund(c[HARDGAME]?6:13)]) /* macro to destroy object at present location */ #define forget() (item[playerx][playery]=know[playerx][playery]=0) /* macro to wipe out a monster at a location */ #define disappear(x,y) (mitem[x][y]=know[x][y]=0) #ifdef VT100 /* macro to turn on bold display for the terminal */ #define setbold() (lprcat(boldon?"\33[1m":"\33[7m")) /* macro to turn off bold display for the terminal */ #define resetbold() (lprcat("\33[m")) /* macro to setup the scrolling region for the terminal */ #define setscroll() (lprcat("\33[20;24r")) /* macro to clear the scrolling region for the terminal */ #define resetscroll() (lprcat("\33[;24r")) /* macro to clear the screen and home the cursor */ #define clear() (lprcat("\33[2J\33[f"), cbak[SPELLS]= -50) #define cltoeoln() lprcat("\33[K") #else VT100 /* defines below are for use in the termcap mode only */ #define ST_START 1 #define ST_END 2 #define BOLD 3 #define END_BOLD 4 #define CLEAR 5 #define CL_LINE 6 #define CL_DOWN 14 #define CURSOR 15 /* macro to turn on bold display for the terminal */ #define setbold() (*lpnt++ = ST_START) /* macro to turn off bold display for the terminal */ #define resetbold() (*lpnt++ = ST_END) /* macro to setup the scrolling region for the terminal */ #define setscroll() enable_scroll=1 /* macro to clear the scrolling region for the terminal */ #define resetscroll() enable_scroll=0 /* macro to clear the screen and home the cursor */ #define clear() (*lpnt++ =CLEAR, cbak[SPELLS]= -50) /* macro to clear to end of line */ #define cltoeoln() (*lpnt++ = CL_LINE) #endif VT100 /* macro to output one byte to the output buffer */ #define lprc(ch) ((lpnt>=lpend)?(*lpnt++ =(ch), lflush()):(*lpnt++ =(ch))) /* macro to seed the random number generator */ #define srand(x) (rand_x=x) #ifdef MACRORND /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */ #define rnd(x) ((((rand_x=rand_x*1103515245+12345)>>7)%(x))+1) #define rund(x) ((((rand_x=rand_x*1103515245+12345)>>7)%(x)) ) #endif MACRORND /* macros for miscellaneous data conversion */ #define min(x,y) (((x)>(y))?(y):(x)) #define max(x,y) (((x)>(y))?(x):(y)) #define isalpha(x) (is_alpha[x]) #define isdigit(x) (is_digit[x]) #define tolower(x) (to_lower[x]) #define toupper(x) (to_upper[x]) #define lcc(x) (to_lower[x]) #define ucc(x) (to_upper[x]) #endif NODEFS SHAR_EOF if test 12521 -ne "`wc -c < 'header.h'`" then echo shar: error transmitting "'header.h'" '(should have been 12521 characters)' fi fi # end of overwriting check echo shar: extracting "'help.c'" '(2367 characters)' if test -f 'help.c' then echo shar: will not over-write existing file "'help.c'" else cat << \SHAR_EOF > 'help.c' /* help.c Larn is copyrighted 1986 by Noah Morgan. */ #include "header.h" /* * help function to display the help info * * format of the .larn.help file * * 1st character of file: # of pages of help available(ascii digit) * page(23 lines) for the introductory message(not counted in above) * pages of help text(23 lines per page) */ help() { register int i,j; #ifndef VT100 char tmbuf[128]; /* intermediate translation buffer when not a VT100 */ #endif VT100 if ((j = openhelp()) < 0) return; /* open the help file and get # pages */ for (i = 0; i < 23; i++) lgetl(); /* skip over intro message */ for (; j > 0; j--) { clear(); for (i = 0; i < 23; i++) #ifdef VT100 lprcat(lgetl()); /* print out each line that we read in */ #else VT100 { tmcapcnv(tmbuf, lgetl()); lprcat(tmbuf); } /* intercept \33's */ #endif VT100 if (j > 1) { lprcat(" ---- Press "); standout("return"); lprcat(" to exit, "); standout("space"); lprcat(" for more help ---- "); i = 0; while ((i != ' ') &&(i != '\n') &&(i != '\33')) i = readchar(); if ((i == '\n') ||(i == '\33')) { lrclose(); setscroll(); drawscreen(); return; } } } lrclose(); retcont(); drawscreen(); } /* * function to display the welcome message and background */ welcome() { register int i; #ifndef VT100 char tmbuf[128]; /* intermediate translation buffer when not a VT100 */ #endif VT100 if (openhelp() < 0) return; /* open the help file */ clear(); for (i = 0; i < 23; i++) #ifdef VT100 lprcat(lgetl()); /* print out each line that we read in */ #else VT100 { tmcapcnv(tmbuf, lgetl()); lprcat(tmbuf); } /* intercept \33's */ #endif VT100 lrclose(); retcont(); /* press return to continue */ } /* * function to say press return to continue and reset scroll when done */ retcont() { cursor(1, 24); lprcat("Press "); standout("return"); lprcat(" to continue: "); while (readchar() != '\n'); setscroll(); } /* * routine to open the help file and return the first character - '0' */ openhelp() { if (lopen(helpfile) < 0) { lprintf("Can't open help file \"%s\" ", helpfile); lflush(); sleep(4); drawscreen(); setscroll(); return(-1); } resetscroll(); return(lgetc() - '0'); } SHAR_EOF if test 2367 -ne "`wc -c < 'help.c'`" then echo shar: error transmitting "'help.c'" '(should have been 2367 characters)' fi fi # end of overwriting check # End of shell archive exit 0