v07i007: ularn - ultra-larn, an enhancement of the larn adventure game, Part07/08

9 views
Skip to first unread message

Bill Randle

unread,
Jul 6, 1989, 10:05:32 AM7/6/89
to
Submitted-by: "Philip A. Cordier" <ph...@sco.COM>
Posting-number: Volume 7, Issue 7
Archive-name: ularn/Part07

#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 7 (of 8)."
# Contents: Ufortune diag.c display.c fortune.c moreobj.c movem.c
# savelev.c
# Wrapped by billr@saab on Thu Jun 29 08:10:22 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Ufortune' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ufortune'\"
else
echo shar: Extracting \"'Ufortune'\" \(1437 characters\)
sed "s/^X//" >'Ufortune' <<'END_OF_FILE'
Xgem value = gem * 2 ^ perfection
Xsitting down can have unexpected results
Xdon't pry into the affairs of others
Xdrinking can be hazardous to your health
Xbeware of the gusher!
Xsome monsters are greedy
Xnymphs have light fingers
Xtry kissing a disenchantress!
Xhammers and brains don't mix
Xwhat does a potion of cure dianthroritis taste like?
Xhit point gain/loss when raising a level depends on constitution
Xask the genie
Xbe sure to pay your taxes
Xare monsters afraid of something?
Xsome dragons can fly
Xdos thou strive for perfection?
Xpatience is a virtue, unless your daughter dies
Xwhat can the Eye of Larn see for its guardian?
Xa level 25 player casts like crazy!
Xenergy rings affect spell regeneration
Xdifficulty affects regeneration
Xcontrol of the pesty spirits is most helpful
Xdon't fall into a bottomless pit
Xwatch out for trap doors
Xdexterity allows you to carry more
Xyou can get 2 points of WC for the price of one
Xnever enter the dungeon naked! the monsters will laugh at you!
Xdid someone put itching powder in your armor?
Xtake the express
Xavoid opening doors. you never know whats on the other side.
Xthe greatest weapon in the game has not the highest Weapon Class
Xyou can't buy the most powerful scroll
Xidentify things before you use them
Xthere's more than one way through a wall
XTry Dealer McDope's for all your recreational needs!
Xwho is tougher than a demon prince?
XSlayer has a grudge
Xwonderful wands prevent you from falling
END_OF_FILE
if test 1437 -ne `wc -c <'Ufortune'`; then
echo shar: \"'Ufortune'\" unpacked with wrong size!
fi
# end of 'Ufortune'
fi
if test -f 'diag.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'diag.c'\"
else
echo shar: Extracting \"'diag.c'\" \(12096 characters\)
sed "s/^X//" >'diag.c' <<'END_OF_FILE'
X/* diag.c */
X#include "header.h"
X
Xextern long int initialtime;
Xextern int rmst,maxitm,lasttime;
Xextern char nosignal;
X
Xchar *cdef[] = {
X "STRENGTH", "INTELLIGENCE", "WISDOM", "CONSTITUTION", "DEXTERITY",
X "CHARISMA", "HPMAX", "HP", "GOLD", "EXPERIENCE",
X "LEVEL", "REGEN", "WCLASS", "AC", "BANKACCOUNT",
X "SPELLMAX", "SPELLS", "ENERGY", "ECOUNTER", "MOREDEFENSES",
X "WEAR", "PROTECTIONTIME", "WIELD", "AMULET", "REGENCOUNTER",
X "MOREDAM", "DEXCOUNT", "STRCOUNT", "BLINDCOUNT", "CAVELEVEL",
X "CONFUSE", "ALTPRO", "HERO", "CHARMCOUNT", "INVISIBILITY",
X "CANCELLATION", "HASTESELF", "EYEOFLARN", "AGGRAVATE ", "GLOBE",
X "TELEFLAG", "SLAYING", "NEGATESPIRIT", "SCAREMONST ", "AWARENESS",
X "HOLDMONST", "TIMESTOP", "HASTEMONST", "CUBEofUNDEAD", "GIANTSTR",
X "FIRERESISTANCE", "BESSMANN", "NOTHEFT", "HARDGAME", "",
X "", "", "", "", "",
X "LANCEDEATH", "SPIRITPRO", "UNDEADPRO", "SHIELD ", "STEALTH",
X "ITCHING", "LAUGHING", "DRAINSTRENGTH", "CLUMSINESS", "INFEEBLEMENT",
X "HALFDAM", "SEEINVISIBLE", "FILLROOM", "", "SPHCAST",
X "WTW", "STREXTRA", "TMP", "LIFEPROT", "ORB",
X "ELVUP", "ELVDOWN", "HAND", "CUBEUNDEAD", "DRAGSLAY",
X "NEGATE", "URN", "LAMP", "TALISMAN", "WAND",
X "STAFF", "DEVICE", "SLASH", "ELVEN", "VORP",
X "SLAY", "PAD", "COKED", "", "" };
X
Xchar *ivendef[] = {
X "",
X "OALTAR", "OTHRONE", "OORB", "OPIT", "OSTAIRSUP",
X "OELEVATORUP", "OFOUNTAIN", "OSTATUE", "OTELEPORTER", "OSCHOOL",
X "OMIRROR", "ODNDSTORE", "OSTAIRSDOWN", "OELEVATORDOWN", "OBANK2",
X "OBANK", "ODEADFOUNTAIN", "OGOLDPILE", "OOPENDOOR", "OCLOSEDDOOR",
X "OWALL", "OTRAPARROW", "OTRAPARROWIV", "OLARNEYE", "OPLATE",
X "OCHAIN", "OLEATHER", "ORING", "OSTUDLEATHER", "OSPLINT",
X "OPLATEARMOR", "OSSPLATE", "OSHIELD", "OSWORDofSLASHING", "OHAMMER",
X "OSWORD", "O2SWORD", "OSPEAR", "ODAGGER", "OBATTLEAXE",
X "OLONGSWORD", "OFLAIL", "OLANCE", "ORINGOFEXTRA", "OREGENRING",
X "OPROTRING", "OENERGYRING", "ODEXRING", "OSTRRING", "OCLEVERRING",
X "ODAMRING", "OBELT", "OSCROLL", "OPOTION", "OBOOK",
X "OCHEST", "OAMULET", "OORBOFDRAGON", "OSPIRITSCARAB", "OCUBEofUNDEAD",
X "ONOTHEFT", "ODIAMOND", "ORUBY", "OEMERALD", "OSAPPHIRE",
X "OENTRANCE", "OVOLDOWN", "OVOLUP", "OHOME", "OMAXGOLD",
X "OKGOLD", "ODGOLD", "OIVDARTRAP", "ODARTRAP", "OTRAPDOOR",
X "OIVTRAPDOOR", "OTRADEPOST", "OIVTELETRAP", "ODEADTHRONE", "OANNIHILATION",
X "OTHRONE2", "OLRS", "OCOOKIE", "OURN", "OBRASSLAMP",
X "OHANDofFEAR", "OSPHTALISMAN", "OWWAND", "OPSTAFF", "OVORPAL",
X "OSLAYER", "OELVENCHAIN", "OSPEED", "OACID", "OHASH",
X "OSHROOMS", "OCOKE", "OPAD", "" };
X
X
X/*
X ***************************
X DIAG -- dungeon diagnostics
X ***************************
X
X print out data for debugging
X */
X
XFILE *dfile;
X
Xdiag()
X{
X register int i, j;
X
X if ((dfile = fopen(diagfile, "w")) == NULL) {
X return(0);
X }
X lprcat("\nDiagnosing . . .\n");
X lflush();
X
X fprintf(dfile,"\n-------- Beginning of DIAG diagnostics ---------\n\n");
X
X fprintf(dfile, "Hit points: %2ld(%2ld)\n", c[HP], c[HPMAX]);
X
X fprintf(dfile, "gold: %ld Experience: %ld Character level: %d Level in caverns: %ld\n",
X (long) c[GOLD],
X (long) c[EXPERIENCE],
X (long) c[LEVEL],
X level);
X
X fprintf(dfile, "\nFor the c[] array:\n");
X fflush(dfile);
X
X for( j=0; j<100; j++)
X fprintf(dfile, "c[%d]\t%-20s\t= %ld\n", j, cdef[j], c[j]);
X fprintf(dfile, "\n\n");
X fflush(dfile);
X
X fprintf(dfile, "Inventory\n");
X for (j=0; j<26; j++) {
X fprintf (dfile, "iven[%d] %-12s = %d",
X j, ivendef[iven[j]], iven[j] );
X fprintf (dfile, "\t%s", objectname[iven[j]] );
X fprintf (dfile, "\t+ %d\n", ivenarg[j] );
X }
X
X fprintf(dfile, "\nHere are the maps:\n\n");
X monstnamelist[DEMONLORD] = '1';
X monstnamelist[DEMONLORD+1] = '2';
X monstnamelist[DEMONLORD+2] = '3';
X monstnamelist[DEMONLORD+3] = '4';
X monstnamelist[DEMONLORD+4] = '5';
X monstnamelist[DEMONLORD+5] = '6';
X monstnamelist[DEMONLORD+6] = '7';
X monstnamelist[DEMONPRINCE] = '9';
X monstnamelist[LUCIFER] = '0';
X i = level;
X for (j = 0; j <= MAXLEVEL+MAXVLEVEL-1; j++) {
X newcavelevel(j);
X fprintf(dfile, "\n-------------------------------------------------------------------\n");
X fprintf(dfile, "Map %s level %d\n",
X levelname[level], level);
X fprintf(dfile, "-------------------------------------------------------------------\n");
X diagdrawscreen();
X fflush(dfile);
X }
X level = i;
X getlevel();
X
X fprintf(dfile, "\n\nNow for the monster data:\n\n");
X fprintf(dfile, "\nTotal types of monsters: %d\n\n", MAXMONST + 8);
X fprintf(dfile, " Monster Name LEV AC DAM ATT DEF GOLD HP EXP\n");
X fprintf(dfile, "-----------------------------------------------------------------\n");
X fflush(dfile);
X
X for (i = 0; i <= MAXMONST + 8; i++) {
X fprintf(dfile, "%19s %2d %3d ",
X monster[i].name,
X monster[i].level,
X monster[i].armorclass);
X fprintf(dfile, " %3d %3d %3d ",
X monster[i].damage,
X monster[i].attack,
X monster[i].defense);
X fprintf(dfile, "%6d %3d %6ld\n",
X monster[i].gold,
X monster[i].hitpoints,
X (long) monster[i].experience);
X fflush(dfile);
X }
X
X fprintf(dfile, "\nAvailable potions:\n\n");
X for (i = 0; i < MAXPOTION; i++)
X fprintf(dfile, "%20s\n", &potionname[i][1]);
X fflush(dfile);
X
X fprintf(dfile, "\nAvailable scrolls:\n\n");
X for (i = 0; i < MAXSCROLL; i++)
X fprintf(dfile, "%20s\n", &scrollname[i][1]);
X fflush(dfile);
X
X fprintf(dfile, "\nSpell list:\n\n");
X fprintf(dfile, "spell# name description\n");
X fprintf(dfile, "-------------------------------------------------\n\n");
X
X for (j = 0; j < SPNUM; j++) {
X fprintf(dfile, "%-10s", spelcode[j]);
X fprintf(dfile," %21s\n", spelname[j]);
X fprintf(dfile,"%s\n", speldescript[j]);
X }
X fflush(dfile);
X
X fprintf(dfile, "\nObject list\n\n");
X fprintf(dfile, "\nj \tObject \tName\n");
X fprintf(dfile, "---------------------------------\n");
X for (j = 0; j < MAXOBJ; j++)
X fprintf(dfile, "%d \t%c \t%s\n",
X j,
X objnamelist[j],
X objectname[j] );
X fflush(dfile);
X
X fprintf(dfile,"\n-------- End of DIAG diagnostics ---------\n");
X fflush(dfile);
X fclose(dfile);
X
X lprcat("\nDone Diagnosing.\n");
X lflush();
X return(0);
X}
X
X
X/*
X draw the whole screen
X */
Xdiagdrawscreen()
X{
X register int i, j, k;
X
X /* east west walls of this line */
X for (i = 0; i < MAXY; i++) {
X for (j = 0; j < MAXX; j++)
X if (k = mitem[j][i])
X fprintf(dfile, "%c", monstnamelist[k]);
X else
X fprintf(dfile, "%c", objnamelist[item[j][i]]);
X fprintf(dfile, "\n");
X }
X}
X/*
X to save the game in a file
X */
Xstatic long int zzz=0;
Xsavegame(fname)
Xchar *fname;
X{
X register int i,k;
X register struct sphere *sp;
X struct stat statbuf;
X
X nosignal=1;
X lflush();
X savelevel();
X ointerest();
X if (lcreat(fname) < 0) {
X lcreat((char*)0);
X lprintf("\nCan't open file <%s> to save game\n",fname);
X nosignal=0;
X return(-1);
X }
X
X set_score_output();
X lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X if (beenhere[k])
X lwrite((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X lwrite((char*)&c[0],100*sizeof(long));
X lprint((long)gtime);
X lprc(level);
X lprc(playerx);
X lprc(playery);
X lwrite((char*)iven,26);
X lwrite((char*)ivenarg,26*sizeof(short));
X lwrite((char*)char_class,20);
X for (k=0; k<MAXSCROLL; k++) lprc(scrollname[k][0]);
X for (k=0; k<MAXPOTION; k++) lprc(potionname[k][0]);
X lwrite((char*)spelknow,SPNUM);
X lprc(wizard);
X lprc(rmst); /* random monster generation counter */
X for (i=0; i<90; i++) lprc(itm[i].qty);
X lwrite((char*)course,25);
X lprc(cheat);
X
X /* genocide info */
X for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided);
X
X /* save spheres of annihilation */
X for (sp=spheres; sp; sp=sp->p)
X lwrite((char*)sp,sizeof(struct sphere));
X
X time(&zzz);
X lprint((long)(zzz-initialtime));
X lwrite((char*)&zzz,sizeof(long));
X
X if (fstat(lfd,&statbuf)< 0) lprint(0L);
X else
X lprint((long)statbuf.st_ino); /* inode # */
X
X lwclose();
X lastmonst[0] = 0;
X lcreat((char*)0);
X nosignal=0;
X return(0);
X}
X
Xrestoregame(fname)
Xchar *fname;
X{
X register int i,k;
X register struct sphere *sp,*sp2;
X struct stat filetimes;
X
X cursors();
X lprcat("\nRestoring . . .");
X lflush();
X if (lopen(fname) <= 0) {
X lcreat((char*)0);
X lprintf("\nCan't open file <%s> to restore game\n",fname);
X nap(2000);
X c[GOLD]=c[BANKACCOUNT]=0;
X died(-265);
X return;
X }
X
X lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X if (beenhere[k])
X lrfill((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X
X lrfill((char*)&c[0],100*sizeof(long));
X gtime = lrint();
X level = c[CAVELEVEL] = lgetc();
X
X playerx = lgetc();
X playery = lgetc();
X
X lrfill((char*)iven,26);
X lrfill((char*)ivenarg,26*sizeof(short));
X lrfill((char*)char_class,20);
X
X for (k=0; k<MAXSCROLL; k++) scrollname[k][0] = lgetc();
X for (k=0; k<MAXPOTION; k++) potionname[k][0] = lgetc();
X
X lrfill((char*)spelknow,SPNUM);
X
X wizard = lgetc();
X rmst = lgetc(); /* random monster creation flag */
X
X for (i=0; i<90; i++)
X itm[i].qty = lgetc();
X
X lrfill((char*)course,25);
X cheat = lgetc();
X
X /* genocide info */
X for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc();
X
X for (sp=0,i=0; i<c[SPHCAST]; i++) {
X sp2 = sp;
X sp = (struct sphere *)malloc(sizeof(struct sphere));
X if (sp==0) {
X fprintf(stderr, "Can't malloc() for sphere space\n");
X break;
X }
X /* get spheres of annihilation */
X lrfill((char*)sp,sizeof(struct sphere));
X sp->p=0; /* null out pointer */
X if (i==0) spheres=sp; /* beginning of list */
X else sp2->p = sp;
X }
X
X
X time(&zzz);
X initialtime = zzz-lrint();
X
X fstat(fd,&filetimes);/*get the creation and modification time of file*/
X
X lrfill((char*)&zzz,sizeof(long));
X
X zzz += 6;
X if (filetimes.st_ctime > zzz)
X fsorry(); /*file create time */
X else if (filetimes.st_mtime > zzz)
X fsorry(); /* file modify time*/
X
X
X if (c[HP]<0) {
X died(284);
X return;
X } /* died a post mortem death */
X
X oldx = oldy = 0;
X
X i = lrint(); /* inode # */
X if (i && (filetimes.st_ino!=i))
X fsorry(); /* different inode number, file was copied */
X
X lrclose();
X
X if (strcmp(fname,ckpfile) == 0) {
X if (lappend(fname) < 0)
X fcheat();
X else {
X lprc(' ');
X lwclose();
X }
X lcreat((char*)0);
X }
X else if (unlink(fname) < 0)
X fcheat(); /* can't unlink save file */
X
X /* for the greedy cheater checker */
X /* for (k=0; k<6; k++) if (c[k]>99) greedy();
X if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy(); */
X if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) {
X long tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
X c[EXPERIENCE] = skill[24];
X raiseexperience((long)tmp);
X }
X getlevel();
X lasttime=gtime;
X
X for (k=0; k<26; k++)
X if (iven[k] == OLARNEYE) {
X monstnamelist[DEMONLORD] = '1';
X monstnamelist[DEMONLORD+1] = '2';
X monstnamelist[DEMONLORD+2] = '3';
X monstnamelist[DEMONLORD+3] = '4';
X monstnamelist[DEMONLORD+4] = '5';
X monstnamelist[DEMONLORD+5] = '6';
X monstnamelist[DEMONLORD+6] = '7';
X monstnamelist[DEMONPRINCE] = '9';
X monstnamelist[LUCIFER] = '0';
X break;
X }
X}
X
X/*
X subroutine to not allow greedy cheaters
X */
Xgreedy()
X{
X if (wizard) return;
X
Xlprcat("\n\nI am so sorry, but your character is a little TOO good! Since this\n");
Xlprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
Xlprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
X lprcat("to continue.\n");
X nap(5000);
X c[GOLD]=c[BANKACCOUNT]=0;
X died(-267);
X return;
X}
X
X/*
X subroutine to not allow altered save files and terminate the attempted
X restart
X */
Xfsorry()
X{
X if(cheat) return;
Xlprcat("\nSorry, but your savefile has been altered.\n");
Xlprcat("However, seeing as I am a good sport, I will let you play.\n");
Xlprcat("Be advised though, you won't be placed on the scoreboard.");
X cheat = 1;
X nap(4000);
X}
X
X/*
X subroutine to not allow game if save file can't be deleted
X */
Xfcheat()
X{
X if (wizard) return;
X if(cheat) return;
X
Xlprcat("\nSorry, but your savefile can't be deleted. This can only mean\n");
Xlprcat("that you tried to CHEAT by protecting the directory the savefile\n");
Xlprcat("is in. Since this is unfair to the rest of the Ularn community, I\n");
Xlprcat("cannot let you play this game.\n");
X nap(5000);
X c[GOLD]=c[BANKACCOUNT]=0;
X died(-268);
X return;
X}
END_OF_FILE
if test 12096 -ne `wc -c <'diag.c'`; then
echo shar: \"'diag.c'\" unpacked with wrong size!
fi
# end of 'diag.c'
fi
if test -f 'display.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'display.c'\"
else
echo shar: Extracting \"'display.c'\" \(12888 characters\)
sed "s/^X//" >'display.c' <<'END_OF_FILE'
X/* display.c */
X#include "header.h"
X
X#define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
X
Xstatic int minx,maxx,miny,maxy,k,m;
Xstatic char bot1f=0,bot2f=0,bot3f=0;
Xchar always=0;
X
X/*
X bottomline()
X
X for the bottom line of the display
X */
Xbottomline()
X{
X recalc();
X bot1f=1;
X}
Xbottomhp()
X{
X bot2f=1;
X}
Xbottomspell()
X{
X bot3f=1;
X}
Xbottomdo()
X{
X if (bot1f) {
X bot3f=bot1f=bot2f=0;
X bot_linex();
X return;
X }
X if (bot2f) {
X bot2f=0;
X bot_hpx();
X }
X if (bot3f) {
X bot3f=0;
X bot_spellx();
X }
X}
X
Xbot_linex()
X{
X register int i;
X if (cbak[SPELLS] <= -50 || (always)) {
X cursor( 1,18);
X if (c[SPELLMAX]>99)
X lprintf("Spells:%3d(%3d)", c[SPELLS],c[SPELLMAX]);
X else
X lprintf("Spells:%3d(%2d) ",c[SPELLS],c[SPELLMAX]);
X lprintf(" AC: %-3d WC: %-3d Level",c[AC],c[WCLASS]);
X if (c[LEVEL]>99)
X lprintf("%3d",c[LEVEL]);
X else
X lprintf(" %-2d",c[LEVEL]);
X lprintf(" Exp: %-9d %s\n",c[EXPERIENCE],class[c[LEVEL]-1]);
X lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
X c[HP],c[HPMAX],c[STRENGTH]+c[STREXTRA],
X c[INTELLIGENCE]);
X lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
X c[WISDOM],c[CONSTITUTION],c[DEXTERITY],c[CHARISMA]);
X
X if ((level==0) || (wizard))
X c[TELEFLAG]=0;
X if (c[TELEFLAG])
X lprcat(" ?");
X else
X lprcat(levelname[level]);
X lprintf(" Gold: %-6d",c[GOLD]);
X always=1;
X botside();
X c[TMP] = c[STRENGTH]+c[STREXTRA];
X for (i=0; i<100; i++) cbak[i]=c[i];
X return;
X }
X
X botsub(makecode(SPELLS,8,18),"%3d");
X if (c[SPELLMAX]>99)
X botsub(makecode(SPELLMAX,12,18),"%3d)");
X else
X botsub(makecode(SPELLMAX,12,18),"%2d) ");
X botsub(makecode(HP,5,19),"%3d");
X botsub(makecode(HPMAX,9,19),"%3d");
X botsub(makecode(AC,21,18),"%-3d");
X botsub(makecode(WCLASS,30,18),"%-3d");
X botsub(makecode(EXPERIENCE,49,18),"%-9d");
X if (c[LEVEL] != cbak[LEVEL]) {
X cursor(59,18);
X lprcat(class[c[LEVEL]-1]);
X }
X if (c[LEVEL]>99)
X botsub(makecode(LEVEL,40,18),"%3d");
X else
X botsub(makecode(LEVEL,40,18)," %-2d");
X c[TMP] = c[STRENGTH]+c[STREXTRA];
X botsub(makecode(TMP,18,19),"%-2d");
X botsub(makecode(INTELLIGENCE,25,19),"%-2d");
X botsub(makecode(WISDOM,32,19),"%-2d");
X botsub(makecode(CONSTITUTION,39,19),"%-2d");
X botsub(makecode(DEXTERITY,46,19),"%-2d");
X botsub(makecode(CHARISMA,53,19),"%-2d");
X if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG])) {
X if ((level==0) || (wizard)) c[TELEFLAG]=0;
X cbak[TELEFLAG] = c[TELEFLAG];
X cbak[CAVELEVEL] = level;
X cursor(59,19);
X if (c[TELEFLAG])
X lprcat(" ?");
X else
X lprcat(levelname[level]);
X }
X botsub(makecode(GOLD,69,19),"%-6d");
X botside();
X}
X
X/*
X special subroutine to update only the gold number on the bottomlines
X called from ogold()
X */
Xbottomgold()
X{
X botsub(makecode(GOLD,69,19),"%-6d");
X}
X
X/*
X special routine to update hp and level fields on bottom lines
X called in monster.c hitplayer() and spattack()
X */
Xbot_hpx()
X{
X if (c[EXPERIENCE] != cbak[EXPERIENCE]) {
X recalc();
X bot_linex();
X }
X else botsub(makecode(HP,5,19),"%3d");
X}
X
X/*
X special routine to update number of spells called from regen()
X */
Xbot_spellx()
X{
X botsub(makecode(SPELLS,9,18),"%2d");
X}
X
X/*
X common subroutine for a more economical bottomline()
X */
Xstatic struct bot_side_def
X{
X int typ;
X char *string;
X}
Xbot_data[] =
X{
X STEALTH,"stealth",
X UNDEADPRO,"undead pro",
X SPIRITPRO,"spirit pro",
X CHARMCOUNT,"Charm",
X TIMESTOP,"Time Stop",
X HOLDMONST,"Hold Monst",
X GIANTSTR,"Giant Str",
X FIRERESISTANCE,"Fire Resit",
X DEXCOUNT,"Dexterity",
X STRCOUNT,"Strength",
X SCAREMONST,"Scare",
X HASTESELF,"Haste Self",
X CANCELLATION,"Cancel",
X INVISIBILITY,"Invisible",
X ALTPRO,"Protect 3",
X PROTECTIONTIME,"Protect 2",
X WTW,"Wall-Walk"
X};
X
Xbotside()
X{
X register int i,idx;
X
X for (i=0; i<17; i++) {
X idx = bot_data[i].typ;
X if ((always) || (c[idx] != cbak[idx])) {
X if ((always) || (cbak[idx] == 0)) {
X if (c[idx]) {
X cursor(70,i+1);
X lprcat(bot_data[i].string);
X }
X }
X else
X if (c[idx]==0) {
X cursor(70,i+1);
X lprcat(" ");
X }
X cbak[idx]=c[idx];
X }
X }
X always=0;
X}
X
Xbotsub(idx,str)
Xregister int idx;
Xchar *str;
X{
X register int x,y;
X
X y = idx & 0xff;
X x = (idx>>8) & 0xff;
X idx >>= 16;
X if (c[idx] != cbak[idx]) {
X cbak[idx]=c[idx];
X cursor(x,y);
X lprintf(str,c[idx]);
X }
X}
X
X/*
X * subroutine to draw only a section of the screen
X * only the top section of the screen is updated. If entire lines are being
X * drawn, then they will be cleared first.
X */
Xint d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
Xdraws(xmin,xmax,ymin,ymax)
Xint xmin,xmax,ymin,ymax;
X{
X register int i,idx;
X if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
X {
X if (ymin==0) cl_up(79,ymax);
X else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
X xmin = -1;
X }
X d_xmin=xmin;
X d_xmax=xmax;
X d_ymin=ymin;
X d_ymax=ymax; /* for limited screen drawing */
X drawscreen();
X if (xmin<=0 && xmax==MAXX) {
X/* draw stuff on right side of screen as needed*/
X for (i=ymin; i<ymax; i++) {
X idx = bot_data[i].typ;
X if (c[idx]) {
X cursor(70,i+1);
X lprcat(bot_data[i].string);
X }
X cbak[idx]=c[idx];
X }
X }
X}
X
X/*
X drawscreen()
X
X subroutine to redraw the whole screen as the player knows it
X */
Xchar screen[MAXX][MAXY],d_flag; /* template for the screen */
Xdrawscreen()
X{
X register int i,j,k;
X
X int lastx,lasty; /* variables used to optimize the object printing */
X if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY) {
X d_flag=1;
X clear(); /* clear the screen */
X }
X else {
X d_flag=0;
X cursor(1,1);
X }
X if (d_xmin<0)
X d_xmin=0; /* d_xmin=-1 means display all without bottomline */
X
X for (i=d_ymin; i<d_ymax; i++)
X for (j=d_xmin; j<d_xmax; j++)
X if (know[j][i]==0) screen[j][i] = ' ';
X else
X if (k=mitem[j][i]) {
X if (k==MIMIC)
X screen[j][i] =
X monstnamelist[rund(MAXMONST)];
X else
X screen[j][i] = monstnamelist[k];
X }
X else
X if ((k=item[j][i])==OWALL)
X screen[j][i] = '#';
X else screen[j][i] = ' ';
X
X for (i=d_ymin; i<d_ymax; i++) {
X j=d_xmin;
X while ((screen[j][i]==' ') && (j<d_xmax)) j++;
X if (j >= d_xmax)
X m=d_xmin; /* don't search backwards if blank line */
X else { /* search backwards for end of line */
X m=d_xmax-1;
X while ((screen[m][i]==' ') && (m>d_xmin)) --m;
X if (j<=m) cursor(j+1,i+1);
X else continue;
X }
X while (j <= m) {
X if (j <= m-3) {
X for (k=j; k<=j+3; k++)
X if (screen[k][i] != ' ')
X k=1000;
X if (k < 1000) {
X while(screen[j][i]==' ' && j<=m)
X j++;
X cursor(j+1,i+1);
X }
X }
X lprc(screen[j++][i]);
X }
X }
X if (boldon) setbold(); /* print out only bold objects now */
X
X for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
X for (j=d_xmin; j<d_xmax; j++) {
X if (k=item[j][i])
X if (k != OWALL)
X if ((know[j][i]) && (mitem[j][i]==0))
X if (objnamelist[k]!=' ') {
X if (lasty!=i+1 || lastx!=j)
X cursor(lastx=j+1,lasty=i+1);
X else lastx++;
X lprc(objnamelist[k]);
X }
X }
X
X if (boldon) resetbold();
X if (d_flag) {
X always=1;
X botside();
X always=1;
X bot_linex();
X }
X oldx=99;
X /* for limited screen drawing */
X d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY;
X}
X
X/*
X showcell(x,y)
X
X subroutine to display a cell location on the screen
X */
Xshowcell(x,y)
Xint x,y;
X{
X register int i,j,k,m;
X
X if (c[BLINDCOUNT]) return; /* see nothing if blind */
X if (c[AWARENESS]) {
X minx = x-3;
X maxx = x+3;
X miny = y-3;
X maxy = y+3;
X }
X else {
X minx = x-1;
X maxx = x+1;
X miny = y-1;
X maxy = y+1;
X }
X
X if (minx < 0) minx=0;
X if (maxx > MAXX-1) maxx = MAXX-1;
X if (miny < 0) miny=0;
X if (maxy > MAXY-1) maxy = MAXY-1;
X
X for (j=miny; j<=maxy; j++)
X for (m=minx; m<=maxx; m++)
X if (know[m][j]==0) {
X cursor(m+1,j+1);
X x=maxx;
X while (know[x][j]) --x;
X for (i=m; i<=x; i++) {
X if ((k=mitem[i][j]) != 0) {
X if (k==MIMIC)
X lprc(monstnamelist[rund(MAXMONST)]);
X else
X lprc(monstnamelist[k]);
X }
X else switch(k=item[i][j]) {
X case 0:
X case OWALL:
X case OIVTELETRAP:
X case OTRAPARROWIV:
X case OIVDARTRAP:
X case OIVTRAPDOOR:
X lprc(objnamelist[k]);
X break;
X
X default:
X if (boldon) setbold();
X lprc(objnamelist[k]);
X if (boldon) resetbold();
X };
X know[i][j]=1;
X }
X m = maxx;
X }
X}
X
X/*
X this routine shows only the spot that is given it. the spaces around
X these coordinated are not shown
X used in godirect() in monster.c for missile weapons display
X */
Xshow1cell(x,y)
Xint x,y;
X{
X if (c[BLINDCOUNT]) return; /* see nothing if blind */
X cursor(x+1,y+1);
X if ((k=mitem[x][y]) != 0) {
X if (k==MIMIC)
X lprc(monstnamelist[rund(MAXMONST)]);
X else
X lprc(monstnamelist[k]);
X }
X else switch(k=item[x][y]) {
X case OWALL:
X case 0:
X case OIVTELETRAP:
X case OTRAPARROWIV:
X case OIVDARTRAP:
X case OIVTRAPDOOR:
X lprc(objnamelist[k]);
X break;
X
X default:
X if (boldon) setbold();
X lprc(objnamelist[k]);
X if (boldon) resetbold();
X };
X know[x][y]|=1; /* we end up knowing about it */
X}
X
X/*
X showplayer()
X
X subroutine to show where the player is on the screen
X cursor values start from 1 up
X */
Xshowplayer()
X{
X cursor(playerx+1,playery+1);
X oldx=playerx;
X oldy=playery;
X}
X
X/*
X moveplayer(dir)
X
X subroutine to move the player from one room to another
X returns 0 if can't move in that direction or hit a monster or on an object
X else returns 1
X nomove is set to 1 to stop the next move (inadvertent monsters hitting
X players when walking into walls) if player walks off screen or into wall
X */
Xshort diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
Xshort diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
X
Xmoveplayer(dir)
Xint dir; /* from = present room # direction = [1-north]
X [2-east] [3-south] [4-west] [5-northeast]
X [6-northwest] [7-southeast] [8-southwest]
X if direction=0, don't move--just show where he is */
X{
X register int k,m,i,j;
X
X if (c[CONFUSE])
X if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
X k = playerx + diroffx[dir];
X m = playery + diroffy[dir];
X
X if (k<0 || k>=MAXX || m<0 || m>=MAXY) {
X nomove=1;
X return(yrepcount = 0);
X }
X
X i = item[k][m];
X j = mitem[k][m];
X
X /* hit a wall */
X if (i==OWALL && c[WTW]==0) {
X nomove=1;
X return(yrepcount = 0);
X }
X
X if (k==33 && m==MAXY-1 && level==1) {
X newcavelevel(0);
X for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
X if (item[k][m]==OENTRANCE) {
X playerx=k;
X playery=m;
X positionplayer();
X drawscreen();
X return(0);
X }
X }
X if (j>0) {
X hitmonster(k,m);
X return(yrepcount = 0);
X } /* hit a monster*/
X
X lastpx = playerx;
X lastpy = playery;
X playerx = k;
X playery = m;
X
X if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP
X && i!=OIVTRAPDOOR)
X return(yrepcount = 0);
X else return(1);
X}
X
X/*
X * function to show what magic items have been discovered thus far
X * enter with -1 for just spells, 99 gives all spells in game (for when
X * genie asks you what you want). anything else will give scrolls & potions
X */
Xstatic int lincount,count;
X
Xseemagic(arg)
Xint arg;
X{
X register int i,number;
X count = lincount = 0;
X nosignal=1;
X
X if (arg == 99) {
X number = (SPNUM+2)/3 + 4; /* # lines needed to display */
X cl_up(79,number);
X cursor(1,1);
X lprcat("Availible spells are:\n\n");
X for (i=0; i<SPNUM; i++) {
X lprintf("%s %-20s ",spelcode[i],spelname[i]);
X seepage();
X }
X seepage();
X more();
X nosignal=0;
X draws(0,MAXX,0,number);
X return;
X }
X if (arg== -1) /* if display spells while casting one */
X {
X for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
X number = (number+2)/3 + 4; /* # lines needed to display */
X cl_up(79,number);
X cursor(1,1);
X }
X else {
X resetscroll();
X clear();
X }
X
X lprcat("The magic spells you have discovered thus far:\n\n");
X for (i=0; i<SPNUM; i++)
X if (spelknow[i]) {
X lprintf("%s %-20s ",spelcode[i],spelname[i]);
X seepage();
X }
X
X if (arg== -1) {
X seepage();
X more();
X nosignal=0;
X draws(0,MAXX,0,number);
X return;
X }
X
X lincount += 3;
X if (count!=0) {
X count=2;
X seepage();
X }
X
X lprcat("\nThe magic scrolls you have found to date are:\n\n");
X count=0;
X for (i=0; i<MAXSCROLL; i++)
X if (scrollname[i][0])
X if (scrollname[i][1]!=' ') {
X lprintf("%-26s",&scrollname[i][1]);
X seepage();
X }
X
X lincount += 3;
X if (count!=0) {
X count=2;
X seepage();
X }
X
X lprcat("\nThe magic potions you have found to date are:\n\n");
X count=0;
X for (i=0; i<MAXPOTION; i++)
X if (potionname[i][0])
X if (potionname[i][1]!=' ') {
X lprintf("%-26s",&potionname[i][1]);
X seepage();
X }
X
X if (lincount!=0) more();
X nosignal=0;
X setscroll();
X drawscreen();
X}
X
X/*
X * subroutine to paginate the seemagic function
X */
Xseepage()
X{
X if (++count==3) {
X lincount++;
X count=0;
X lprc('\n');
X if (lincount>17) {
X lincount=0;
X more();
X clear();
X }
X }
X}
END_OF_FILE
if test 12888 -ne `wc -c <'display.c'`; then
echo shar: \"'display.c'\" unpacked with wrong size!
fi
# end of 'display.c'
fi
if test -f 'fortune.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fortune.c'\"
else
echo shar: Extracting \"'fortune.c'\" \(1731 characters\)
sed "s/^X//" >'fortune.c' <<'END_OF_FILE'
X/* fortune.c */
X#include "header.h"
X/*
X * function to return a random fortune from the fortune file
X */
Xstatic char *base=0; /* pointer to the fortune text */
Xstatic char **flines=0; /* array of pointers to each fortune */
Xstatic int fd=0; /* true if we have load the fortune info */
Xstatic int nlines=0; /* # lines in fortune database */
X
Xchar *fortune(file)
Xchar *file;
X{
X register char *p;
X register int lines,tmp;
X struct stat stat;
X char *malloc();
X
X if (fd==0) {
X if ((fd=open(file,O_RDONLY)) < 0) /* open the file */
X return(0); /* can't find file */
X
X /* find out how big fortune file is and get memory for it */
X stat.st_size = 16384;
X if ((fstat(fd,&stat) < 0) || ((base=malloc(1+stat.st_size)) == 0))
X {
X close(fd);
X fd= -1;
X free((char*)base);
X return(0); /* can't stat file */
X }
X
X /* read in the entire fortune file */
X if (read(fd,base,stat.st_size) != stat.st_size) {
X close(fd);
X fd= -1;
X free((char*)base);
X return(0); /* can't read file */
X }
X close(fd);
X base[stat.st_size]=0; /* final NULL termination */
X
X /* count up all the lines (and NULL terminate) to know memory needs */
X for (p=base,lines=0; p<base+stat.st_size; p++) /* count lines */
X if (*p == '\n') *p=0,lines++;
X nlines = lines;
X
X /* get memory for array of pointers to each fortune */
X if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0) {
X free((char*)base);
X fd= -1;
X return(0); /* malloc() failure */
X }
X
X /* now assign each pointer to a line */
X for (p=base,tmp=0; tmp<nlines; tmp++) {
X flines[tmp]=p;
X while (*p++); /* advance to next line */
X }
X }
X
X if (fd > 2) /* if we have a database to look at */
X return(flines[rund((nlines<=0)?1:nlines)]);
X else
X return(0);
X}
END_OF_FILE
if test 1731 -ne `wc -c <'fortune.c'`; then
echo shar: \"'fortune.c'\" unpacked with wrong size!
fi
# end of 'fortune.c'
fi
if test -f 'moreobj.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'moreobj.c'\"
else
echo shar: Extracting \"'moreobj.c'\" \(9356 characters\)
sed "s/^X//" >'moreobj.c' <<'END_OF_FILE'
X/* moreobj.c
X *
X * Routines in this file:
X *
X * oaltar()
X * othrone()
X * ochest()
X * ofountain()
X */
X#include "header.h"
X
X/*
X * ******
X * OALTAR
X * ******
X *
X * subroutine to process an altar object
X */
Xoaltar()
X{
X unsigned long k;
X
X lprcat("\nDo you (p) pray (d) desecrate");
X iopts();
X while (1) {
X while (1) switch(getcharacter()) {
X case 'p':
X lprcat(" pray\nDo you (m) give money or (j) just pray? ");
X while (1) switch(getcharacter()) {
X case 'j':
X if (rnd(100)<75)
X lprcat("\nnothing happens");
X else if (rnd(13)<4) ohear();
X else if (rnd(43) <= 10) {
X if (c[WEAR])
X lprcat("\nYou feel your armor vibrate for a moment");
X enchantarmor();
X return;
X }
X else if (rnd(43) <= 10) {
X if (c[WIELD])
X lprcat("\nYou feel your weapon vibrate for a moment");
X enchweapon();
X return;
X }
X else createmonster(makemonst(level+2));
X return;
X
X case 'm':
Xdonate:
X cursor(1,24);
X cltoeoln();
X cursor(1,23);
X cltoeoln();
X lprcat("how much do you donate? ");
X k = readnum(c[GOLD]);
X if (c[GOLD] < k) {
X lprcat("You don't have that much!");
X nap(1001);
X goto donate;
X }
X if ( (k==0 || (k<(c[GOLD]/10)) )
X && rnd(60)<30) {
Xlprcat("Cheapskate! The Gods are insulted at such a meager offering!");
X forget();
X createmonster(DEMONPRINCE);
X c[AGGRAVATE] += 1500;
X return;
X }
X c[GOLD] -= k;
X if (k < c[GOLD]/10 || k<rnd(50)) {
X createmonster(makemonst(level+2));
X c[AGGRAVATE] += 500;
X }
X else if (rnd(101) > 50) {
X ohear();
X return;
X }
X else if (rnd(43) >= 33) {
X if (c[WEAR])
X lprcat("You feel your armor vibrate for a moment");
X enchantarmor();
X enchantarmor();
X return;
X }
X else if (rnd(43) >= 33) {
X if (c[WIELD])
X lprcat("You feel your weapon vibrate for a moment");
X enchweapon();
X enchweapon();
X return;
X }
X else lprcat("Thank You.");
X bottomline();
X return;
X } /* end case j or m */
X
X case 'd':
X lprcat(" desecrate");
X if (rnd(100)<60) {
X createmonster(makemonst(level+3)+8);
X c[AGGRAVATE] += 2500;
X }
X else if(rnd(100)<5) raiselevel();
X else if (rnd(101)<30) {
X lprcat("\nThe altar crumbles into a pile of dust before your eyes");
X forget(); /*remember to destroy the altar*/
X }
X else lprcat("\nnothing happens");
X return;
X
X case 'i':
X case '\33':
X ignore();
X if (rnd(100)<30) {
X createmonster(makemonst(level+2));
X c[AGGRAVATE] += rnd(450);
X }
X else lprcat("\nnothing happens");
X return;
X } /* end pray, des, ignore */
X }
X} /* end oaltar */
X
X/*
X function to cast a +3 protection on the player
X */
Xohear()
X{
X lprcat("You have been heard!");
X if (c[ALTPRO]==0) c[MOREDEFENSES]+=5;
X c[ALTPRO] += 800; /* protection field */
X bottomline();
X}
X
X/*
X *******
X OTHRONE
X *******
X
X subroutine to process a throne object
X */
Xothrone(arg)
Xint arg;
X{
X register int i,k;
X
X lprcat("\nDo you (p) pry off jewels, (s) sit down");
X iopts();
X while (1) {
X while (1) switch(getcharacter()) {
X case 'p':
X lprcat(" pry off");
X k=rnd(101);
X if (k<25) {
X for (i=0; i<rnd(4); i++)
X creategem(); /*gems pop off the throne*/
X item[playerx][playery]=ODEADTHRONE;
X know[playerx][playery]=0;
X }
X else if (k<40 && arg==0) {
X createmonster(GNOMEKING);
X item[playerx][playery]=OTHRONE2;
X know[playerx][playery]=0;
X }
X else lprcat("\nnothing happens");
X return;
X
X case 's':
X lprcat(" sit down");
X k=rnd(101);
X if (k<30 && arg==0) {
X createmonster(GNOMEKING);
X item[playerx][playery]=OTHRONE2;
X know[playerx][playery]=0;
X }
X else if (k<35) {
X lprcat("\nZaaaappp! You've been teleported!\n");
X beep();
X oteleport(0);
X }
X else lprcat("\nnothing happens");
X return;
X
X case 'i':
X case '\33':
X ignore();
X return;
X };
X }
X}
X
Xodeadthrone()
X{
X register int k;
X
X lprcat("\nDo you (s) sit down");
X iopts();
X while (1) {
X while (1) switch(getcharacter()) {
X case 's':
X lprcat(" sit down");
X k=rnd(101);
X if (k<15) raiselevel();
X else if (k<35) {
X lprcat("\nZaaaappp! You've been teleported!\n");
X beep();
X oteleport(0);
X }
X else lprcat("\nnothing happens");
X return;
X
X case 'i':
X case '\33':
X ignore();
X return;
X };
X }
X}
X
X/*
X ******
X OCHEST
X ******
X
X subroutine to process a chest object
X */
Xochest()
X{
X register int i,k;
X
X lprcat("\nDo you (t) take it, (o) try to open it");
X iopts();
X while (1) {
X while (1) switch(getcharacter()) {
X case 'o':
X lprcat(" open it");
X k=rnd(101);
X if (k<40) {
X lprcat("\nThe chest explodes as you open it");
X beep();
X i = rnd(10);
X lastnum=281; /* in case he dies */
X lprintf("\nYou suffer %d hit points damage!",(long)i);
X checkloss(i);
X switch(rnd(10)) {
X case 1:
X c[ITCHING]+= rnd(1000)+100;
X lprcat("\nYou feel an irritation spread over your skin!");
X beep();
X break;
X
X case 2:
X c[CLUMSINESS]+= rnd(1600)+200;
X lprcat("\nYou begin to lose hand to eye coordination!");
X beep();
X break;
X
X case 3:
X c[HALFDAM]+= rnd(1600)+200;
X lprcat("\nYou suddenly feel sick and BARF all over your shoes!");
X beep();
X break;
X };
X item[playerx][playery]=know[playerx][playery]=0;
X if (rnd(100)<69)
X creategem(); /* gems from the chest */
X dropgold(rnd(110*iarg[playerx][playery]+200));
X for (i=0; i<rnd(4); i++)
X something(iarg[playerx][playery]+2);
X }
X else lprcat("\nnothing happens");
X return;
X
X case 't':
X lprcat(" take");
X if (take(OCHEST,iarg[playerx][playery])==0)
X item[playerx][playery]=know[playerx][playery]=0;
X return;
X
X case 'i':
X case '\33':
X ignore();
X return;
X };
X }
X}
X
X/*
X *********
X OFOUNTAIN
X *********
X */
X
Xofountain()
X{
X register int x;
X
X cursors();
X lprcat("\nDo you (d) drink, (w) wash yourself");
X iopts();
X while (1) switch(getcharacter()) {
X case 'd':
X lprcat("drink");
X if (rnd(1501)<4) {
X lprcat("\nOops! You seem to have caught the dreadful sleep!");
X beep();
X lflush();
X sleep(3);
X died(280);
X return;
X }
X x = rnd(100);
X if (x==1) raiselevel();
X else if (x < 11) {
X x=rnd((level<<2)+2);
Xlprintf("\nBleah! The water tasted like stale gatorade! You suffer %d hit points!", (long)x);
X lastnum=273;
X losehp(x);
X bottomline();
X cursors();
X }
X else if (x<14) {
X c[HALFDAM] += 200+rnd(200);
X lprcat("\nThe water makes you vomit");
X }
X else if (x<17)
X quaffpotion(17); /* giant strength */
X else if (x < 45)
X lprcat("\nnothing seems to have happened");
X else if (rnd(3) != 2)
X fntchange(1); /*change char levels upward*/
X else
X fntchange(-1); /*change char levels downward*/
X if (rnd(12)<3) {
X lprcat("\nThe fountains bubbling slowly quiets");
X /* dead fountain */
X item[playerx][playery]=ODEADFOUNTAIN;
X know[playerx][playery]=0;
X }
X return;
X
X case '\33':
X case 'i':
X ignore();
X return;
X case 'w':
X lprcat("wash yourself");
X if (rnd(100) < 11) {
X x=rnd((level<<2)+2);
Xlprintf("\nOh no! The water burns like acid! You suffer %d hit points!",(long)x);
X lastnum=273;
X losehp(x);
X bottomline();
X cursors();
X }
X else if (rnd(100) < 29)
X lprcat("\nYou are now clean!");
X else if (rnd(100) < 31)
X lprcat("\nThis water needs soap! The dirt didn't come off!");
X else if (rnd(100) < 34)
X createmonster(WATERLORD);
X else lprcat("\nnothing seems to have happened");
X return;
X }
X}
X
X/*
X a subroutine to raise or lower character levels
X if how > 0 they are raised if how < 0 they are lowered
X */
Xfntchange(how)
Xint how;
X{
X register long j;
X
X lprc('\n');
X switch(rnd(9))
X {
X case 1:
X lprcat("Your strength");
X fch(how,&c[0]);
X break;
X case 2:
X lprcat("Your intelligence");
X fch(how,&c[1]);
X break;
X case 3:
X lprcat("Your wisdom");
X fch(how,&c[2]);
X break;
X case 4:
X lprcat("Your constitution");
X fch(how,&c[3]);
X break;
X case 5:
X lprcat("Your dexterity");
X fch(how,&c[4]);
X break;
X case 6:
X lprcat("Your charm");
X fch(how,&c[5]);
X break;
X case 7:
X j=rnd(level+1);
X if (how < 0) {
X lprintf("You lose %d hit point",(long)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X losemhp((int)j);
X }
X else {
X lprintf("You gain %d hit point",(long)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X raisemhp((int)j);
X }
X bottomline();
X break;
X case 8:
X j=rnd(level+1);
X if (how > 0) {
X lprintf("You just gained %d spell",(long)j);
X raisemspells((int)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X }
X else {
X lprintf("You just lost %d spell",(long)j);
X losemspells((int)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X }
X bottomline();
X break;
X case 9:
X j = 5*rnd((level+1)*(level+1));
X if (how < 0) {
X lprintf("You just lost %d experience point",(long)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X loseexperience((long)j);
X }
X else {
X lprintf("You just gained %d experience point",(long)j);
X if (j>1) lprcat("s!");
X else lprc('!');
X raiseexperience((long)j);
X }
X break;
X }
X cursors();
X}
X
X/*
X ***
X FCH
X ***
X
X subroutine to process an up/down of a character attribute for ofountain
X */
Xfch(how,x)
Xint how;
Xlong *x;
X{
X if (how < 0) {
X lprcat(" went down by one!");
X --(*x);
X }
X else {
X lprcat(" went up by one!");
X (*x)++;
X }
X bottomline();
X}
END_OF_FILE
if test 9356 -ne `wc -c <'moreobj.c'`; then
echo shar: \"'moreobj.c'\" unpacked with wrong size!
fi
# end of 'moreobj.c'
fi
if test -f 'movem.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'movem.c'\"
else
echo shar: Extracting \"'movem.c'\" \(11283 characters\)
sed "s/^X//" >'movem.c' <<'END_OF_FILE'
X/*
X * movem.c (move monster) Larn is copyrighted 1986 by Noah Morgan.
X *
X * Here are the functions in this file:
X *
X * movemonst() Routine to move the monsters toward the player
X * Function to move a monster at (x,y) -- must determine where
X * movemt(x,y)
X * Function to actually perform the monster movement
X * mmove(x,y,xd,yd)
X * Function to look for and move spheres of annihilation
X * movsphere()
X */
X#include "header.h"
X
X/*
X * movemonst() Routine to move the monsters toward the player
X *
X * This routine has the responsibility to determine which monsters are to
X * move, and call movemt() to do the move.
X * Returns no value.
X */
Xstatic short w1[9],w1x[9],w1y[9];
Xstatic int tmp1,tmp2,tmp3,tmp4,distance;
Xmovemonst()
X{
X register int i,j;
X if (c[TIMESTOP]) return; /* no action if time is stopped */
X if (c[HASTESELF]) if ((c[HASTESELF]&1)==0) return;
X if (spheres) movsphere(); /* move the spheres of annihilation if any */
X if (c[HOLDMONST]) return; /* no action if monsters are held */
X
X if (c[AGGRAVATE]) /* determine window of monsters to move */
X {
X tmp1=playery-5;
X tmp2=playery+6;
X tmp3=playerx-10;
X tmp4=playerx+11;
X distance=40; /* depth of intelligent monster movement */
X }
X else
X {
X tmp1=playery-3;
X tmp2=playery+4;
X tmp3=playerx-5;
X tmp4=playerx+6;
X distance=17; /* depth of intelligent monster movement */
X }
X
X if (level == 0) /* if on outside level monsters can move in perimeter */
X {
X if (tmp1 < 0) tmp1=0;
X if (tmp2 > MAXY) tmp2=MAXY;
X if (tmp3 < 0) tmp3=0;
X if (tmp4 > MAXX) tmp4=MAXX;
X }
X else /* if in a dungeon monsters can't be on the perimeter (wall there) */
X {
X if (tmp1 < 1) tmp1=1;
X if (tmp2 > MAXY-1) tmp2=MAXY-1;
X if (tmp3 < 1) tmp3=1;
X if (tmp4 > MAXX-1) tmp4=MAXX-1;
X }
X
X for (j=tmp1; j<tmp2; j++) /* now reset monster moved flags */
X for (i=tmp3; i<tmp4; i++)
X moved[i][j] = 0;
X moved[lasthx][lasthy]=0;
X
X if (c[AGGRAVATE] || !c[STEALTH]) /* who gets moved? split for efficiency */
X {
X for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
X for (i=tmp3; i<tmp4; i++)
X if (mitem[i][j]) /* if there is a monster to move */
X if (moved[i][j]==0) /* if it has not already been moved */
X movemt(i,j); /* go and move the monster */
X }
X else /* not aggravated and not stealth */
X {
X for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
X for (i=tmp3; i<tmp4; i++)
X if (mitem[i][j]) /* if there is a monster to move */
X if (moved[i][j]==0) /* if it has not already been moved */
X if (stealth[i][j]) /* if it is asleep due to stealth */
X movemt(i,j); /* go and move the monster */
X }
X
X if (mitem[lasthx][lasthy]) /* now move monster last hit by player if not already moved */
X {
X if (moved[lasthx][lasthy]==0) /* if it has not already been moved */
X {
X movemt(lasthx,lasthy);
X lasthx = w1x[0];
X lasthy = w1y[0];
X }
X }
X}
X
X/*
X * Function to move a monster at (x,y) -- must determine where
X * movemt(x,y)
X * int x,y;
X *
X * This routine is responsible for determining where one monster at (x,y)
X * will move to. Enter with the monsters coordinates in (x,y).
X * Returns no value.
X */
Xstatic int tmpitem,xl,xh,yl,yh;
X
Xmovemt(i,j)
Xint i,j;
X{
X register int k,m,z,tmp,xtmp,ytmp,monst;
X switch(monst=mitem[i][j]) /* for half speed monsters */
X {
X case TROGLODYTE:
X case HOBGOBLIN:
X case METAMORPH:
X case XVART:
X case INVISIBLESTALKER:
X case ICELIZARD:
X if ((gtime & 1) == 1) return;
X };
X /* choose destination randomly if scared */
X tmp=0;
X {
X register int i, j;
X for (i=0; i<26; i++)
X if (iven[i]==OHANDofFEAR){
X tmp=1;
X break;
X }
X }
X if (c[SCAREMONST]){
X if (tmp==1) tmp=2;
X }
X else if ((tmp==1) && (rnd(10) > 4)) tmp=0;
X
X if ((monst > DEMONLORD)||(monst == PLATINUMDRAGON)) {
X tmp = (tmp==1) ? 0 : (rnd(10) > 5);
X }
X if (tmp) {
X if ((xl = i+rnd(3)-2) < 0) xl=0;
X if (xl >= MAXX) xl=MAXX-1;
X if ((yl = j+rnd(3)-2) < 0) yl=0;
X if (yl >= MAXY) yl=MAXY-1;
X if ((tmp=item[xl][yl]) != OWALL)
X if (mitem[xl][yl] == 0)
X if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
X if (tmp != OCLOSEDDOOR)
X mmove(i,j,xl,yl);
X return;
X }
X
X if (monster[monst].intelligence > 10-c[HARDGAME]) /* if smart monster */
X /* intelligent movement here -- first setup screen array */
X {
X xl=tmp3-2;
X yl=tmp1-2;
X xh=tmp4+2;
X yh=tmp2+2;
X vxy(&xl,&yl);
X vxy(&xh,&yh);
X for (k=yl; k<yh; k++)
X for (m=xl; m<xh; m++)
X {
X if (monst>=DEMONPRINCE)
X screen[m][k]=0;
X else
X switch(item[m][k])
X {
X case OWALL:
X case OELEVATORUP:
X case OELEVATORDOWN:
X case OPIT:
X case OTRAPARROW:
X case ODARTRAP:
X case OCLOSEDDOOR:
X case OTRAPDOOR:
X case OTELEPORTER:
Xsmm:
X screen[m][k]=127;
X break;
X case OMIRROR:
X if (mitem[m][k]==VAMPIRE) goto smm;
X default:
X screen[m][k]=0;
X break;
X };
X }
X screen[playerx][playery]=1;
X
X /* now perform proximity ripple from playerx,playery to monster */
X xl=tmp3-1;
X yl=tmp1-1;
X xh=tmp4+1;
X yh=tmp2+1;
X vxy(&xl,&yl);
X vxy(&xh,&yh);
X for (tmp=1; tmp<distance; tmp++) /* only up to 20 squares away */
X for (k=yl; k<yh; k++)
X for (m=xl; m<xh; m++)
X if (screen[m][k]==tmp) /* if find proximity n advance it */
X for (z=1; z<9; z++) /* go around in a circle */
X {
X if (screen[xtmp=m+diroffx[z]][ytmp=k+diroffy[z]]==0)
X screen[xtmp][ytmp]=tmp+1;
X if (xtmp==i && ytmp==j) goto out;
X }
X
Xout:
X if (tmp<distance) /* did find connectivity */
X /* now select lowest value around playerx,playery */
X for (z=1; z<9; z++) /* go around in a circle */
X if (screen[xl=i+diroffx[z]][yl=j+diroffy[z]]==tmp)
X if (!mitem[xl][yl]) {
X mmove(i,j,w1x[0]=xl,w1y[0]=yl);
X return;
X }
X }
X
X /* dumb monsters move here */
X xl=i-1;
X yl=j-1;
X xh=i+2;
X yh=j+2;
X if (i<playerx) xl++;
X else if (i>playerx) --xh;
X if (j<playery) yl++;
X else if (j>playery) --yh;
X for (k=0; k<9; k++) w1[k] = 10000;
X
X for (k=xl; k<xh; k++)
X for (m=yl; m<yh; m++) /* for each square compute distance to player */
X {
X tmp = k-i+4+3*(m-j);
X tmpitem = item[k][m];
X if (tmpitem!=OWALL || (k==playerx && m==playery))
X if (mitem[k][m]==0)
X if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
X if (tmpitem!=OCLOSEDDOOR)
X {
X w1[tmp] = (playerx-k)*(playerx-k)+(playery-m)*(playery-m);
X w1x[tmp] = k;
X w1y[tmp] = m;
X }
X }
X
X tmp = 0;
X for (k=1; k<9; k++) if (w1[tmp] > w1[k]) tmp=k;
X
X if (w1[tmp] < 10000)
X if ((i!=w1x[tmp]) || (j!=w1y[tmp]))
X mmove(i,j,w1x[tmp],w1y[tmp]);
X}
X
X/*
X * Function to actually perform the monster movement
X * mmove(x,y,xd,yd)
X * int x,y,xd,yd;
X *
X * Enter with the from coordinates in (x,y) and the destination coordinates
X * in (xd,yd).
X */
Xmmove(aa,bb,cc,dd)
Xint aa,bb,cc,dd;
X{
X register int tmp,i,x,flag;
X char *who,*p;
X
X flag=0; /* set to 1 if monster hit by arrow trap */
X if ((cc==playerx) && (dd==playery)) {
X hitplayer(aa,bb);
X moved[aa][bb] = 1;
X return;
X }
X i=item[cc][dd];
X if ((i==OPIT) || (i==OTRAPDOOR))
X switch(mitem[aa][bb]) {
X case SPIRITNAGA:
X case PLATINUMDRAGON:
X case WRAITH:
X case VAMPIRE:
X case SILVERDRAGON:
X case POLTERGEIST:
X case DEMONLORD:
X case DEMONLORD+1:
X case DEMONLORD+2:
X case DEMONLORD+3:
X case DEMONLORD+4:
X case DEMONLORD+5:
X case DEMONLORD+6:
X case DEMONPRINCE:
X case LUCIFER:
X break;
X
X default:
X mitem[aa][bb]=0; /* fell in a pit or trapdoor */
X };
X tmp = mitem[cc][dd] = mitem[aa][bb];
X if (i==OANNIHILATION)
X if (tmp>=DEMONLORD) /* demons dispel spheres */
X {
X flag=0;
X for (x=0;x<26;x++)
X if(iven[x]==OSPHTALISMAN) flag++;
X if (flag==0
X || (flag && tmp == LUCIFER && (rnd(10) > 7))) {
X cursors();
X lprintf("\nThe %s dispels the sphere!",
X monster[tmp].name);
X rmsphere(cc,dd); /* delete the sphere */
X }
X else i=tmp=mitem[cc][dd]=0;
X }
X else i=tmp=mitem[cc][dd]=0;
X
X stealth[cc][dd]=1;
X flag=0;
X
X if ((hitp[cc][dd] = hitp[aa][bb]) < 0) hitp[cc][dd]=1;
X
X if (tmp==LEMMING) {
X if (rnd(100)<=9) {
X mitem[aa][bb] = LEMMING;
X know[aa][bb]=1;
X }
X else mitem[aa][bb] = 0;
X }
X else mitem[aa][bb] = 0;
X
X moved[cc][dd] = 1;
X
X if (tmp == LEPRECHAUN)/* leprechaun takes gold */
X switch(i) {
X case OGOLDPILE:
X case OMAXGOLD:
X case OKGOLD:
X case ODGOLD:
X case ODIAMOND:
X case ORUBY:
X case OEMERALD:
X case OSAPPHIRE:
X item[cc][dd] = 0;
X };
X
X if (tmp == TROLL) /* if a troll regenerate him */
X if ((gtime & 1) == 0)
X if (monster[tmp].hitpoints > hitp[cc][dd]) hitp[cc][dd]++;
X
X if (i==OTRAPARROW) /* arrow hits monster */
X {
X who = "An arrow";
X if ((hitp[cc][dd] -= rnd(10)+level) <= 0) {
X mitem[cc][dd]=0;
X flag=2;
X }
X else flag=1;
X }
X
X if (i==ODARTRAP) /* dart hits monster */
X {
X who = "A dart";
X if ((hitp[cc][dd] -= rnd(6)) <= 0) {
X mitem[cc][dd]=0;
X flag=2;
X }
X else flag=1;
X }
X
X if (tmp < DEMONLORD)
X if (i==OTELEPORTER) /* monster hits teleport trap */
X {
X flag=3;
X fillmonst(mitem[cc][dd]);
X mitem[cc][dd]=0;
X }
X
X if (tmp < DEMONLORD)
X if ((i==OELEVATORUP) || (i==OELEVATORDOWN)) {
X mitem[cc][dd]=0;
X flag=4;
X }
X
X if (c[BLINDCOUNT]) return;
X /* if blind don't show where monsters are */
X if (know[cc][dd] & 1) {
X p=0;
X if (flag) cursors();
X switch(flag) {
X case 1:
X p="\n%s hits the %s";
X break;
X case 2:
X p="\n%s hits and kills the %s";
X break;
X case 3:
X p="\nThe %s%s gets teleported";
X who="";
X break;
X case 4:
X p="\nThe %s%s is carried away by an elevator!";
X who="";
X break;
X };
X if (p) {
X lprintf(p,who,monster[tmp].name);
X beep();
X }
X }
X
X if (know[aa][bb] & 1) show1cell(aa,bb);
X if (know[cc][dd] & 1) show1cell(cc,dd);
X}
X
X/*
X * movsphere() Function to look for and move spheres of annihilation
X *
X * This function works on the sphere linked list, first duplicating the list
X * (the act of moving changes the list), then processing each sphere in order
X * to move it. They eat anything in their way, including stairs, volcanic
X * shafts, potions, etc, except for upper level demons, who can dispel
X * spheres.
X * No value is returned.
X */
X#define SPHMAX 20 /* maximum number of spheres movsphere can handle */
Xmovsphere()
X{
X register int x,y,dir,len;
X register struct sphere *sp,*sp2;
X struct sphere sph[SPHMAX];
X
X /* first duplicate sphere list */
X /* look through sphere list */
X for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p)
X /* only if this level */
X if (sp2->lev == level) {
X sph[x] = *sp2;
X sph[x++].p = 0; /* copy the struct */
X if (x>1)
X sph[x-2].p = &sph[x-1]; /* link pointers */
X }
X if (x) sp= sph; /* if any spheres, point to them */
X else return; /* no spheres */
X
X /* look through sphere list */
X for (sp=sph; sp; sp=sp->p) {
X x = sp->x;
X y = sp->y;
X if (item[x][y]!=OANNIHILATION) continue;/* not really there */
X
X /* has sphere run out of gas? */
X if (--(sp->lifetime) < 0) {
X rmsphere(x,y); /* delete sphere */
X continue;
X }
X /* time to move the sphere */
X switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) {
X case 1:
X case 2: /* change direction to a random one */
X sp->dir = rnd(8);
X default: /* move in normal direction */
X dir = sp->dir;
X len = sp->lifetime;
X rmsphere(x,y);
X newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
X };
X }
X}
END_OF_FILE
if test 11283 -ne `wc -c <'movem.c'`; then
echo shar: \"'movem.c'\" unpacked with wrong size!
fi
# end of 'movem.c'
fi
if test -f 'savelev.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'savelev.c'\"
else
echo shar: Extracting \"'savelev.c'\" \(1169 characters\)
sed "s/^X//" >'savelev.c' <<'END_OF_FILE'
X/* savelev.c */
X#include "header.h"
X
Xextern struct cel *cell;
X
X/*
X * routine to save the present level into storage
X */
Xsavelevel()
X{
X struct cel *pcel;
X char *pitem,*pknow,*pmitem;
X short *phitp,*piarg;
X struct cel *pecel;
X
X pcel = &cell[level*MAXX*MAXY]; /* pointer to this level's cells */
X
X /* pointer to past end of this level's cells */
X pecel = pcel + MAXX*MAXY;
X
X pitem=item[0];
X piarg=iarg[0];
X pknow=know[0];
X pmitem=mitem[0];
X phitp=hitp[0];
X while (pcel < pecel) {
X pcel->mitem = *pmitem++;
X pcel->hitp = *phitp++;
X pcel->item = *pitem++;
X pcel->know = *pknow++;
X pcel++->iarg = *piarg++;
X }
X}
X
X/*
X * routine to restore a level from storage
X */
Xgetlevel()
X{
X struct cel *pcel;
X char *pitem,*pknow,*pmitem;
X short *phitp,*piarg;
X struct cel *pecel;
X
X pcel = &cell[level*MAXX*MAXY]; /* pointer to this level's cells */
X
X /* pointer to past end of this level's cells */
X pecel = pcel + MAXX*MAXY;
X
X pitem=item[0];
X piarg=iarg[0];
X pknow=know[0];
X pmitem=mitem[0];
X phitp=hitp[0];
X while (pcel < pecel) {
X *pmitem++ = pcel->mitem;
X *phitp++ = pcel->hitp;
X *pitem++ = pcel->item;
X *pknow++ = pcel->know;
X *piarg++ = pcel++->iarg;
X }
X}
END_OF_FILE
if test 1169 -ne `wc -c <'savelev.c'`; then
echo shar: \"'savelev.c'\" unpacked with wrong size!
fi
# end of 'savelev.c'
fi
echo shar: End of archive 7 \(of 8\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 8 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0

Reply all
Reply to author
Forward
0 new messages