noah@condor.UUCP (Noah Morgan) (08/08/86)
*** REPLACE THIS LINE WITH YOUR MESSAGE *** #! /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: # object.c # regen.c # scores.c # signal.c # tok.c # MANIFEST # This archive created: Wed Aug 6 14:59:47 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'object.c'" '(25376 characters)' if test -f 'object.c' then echo shar: will not over-write existing file "'object.c'" else cat << \SHAR_EOF > 'object.c' /* object.c Larn is copyrighted 1986 by Noah Morgan. */ #include "header.h" /* *************** LOOK_FOR_OBJECT *************** subroutine to look for an object and give the player his options if an object was found. */ lookforobject() { register int i,j; if (c[TIMESTOP]) return; /* can't find objects is time is stopped */ i=item[playerx][playery]; if (i==0) return; showcell(playerx,playery); cursors(); yrepcount=0; switch(i) { case OGOLDPILE: case OMAXGOLD: case OKGOLD: case ODGOLD: lprcat("\n\nYou have found some gold!"); ogold(i); break; case OPOTION: lprcat("\n\nYou have found a magic potion"); i = iarg[playerx][playery]; if (potionname[i][0]) lprintf(" of %s",&potionname[i][1]); opotion(i); break; case OSCROLL: lprcat("\n\nYou have found a magic scroll"); i = iarg[playerx][playery]; if (scrollname[i][0]) lprintf(" of %s",&scrollname[i][1]); oscroll(i); break; case OALTAR: if (nearbymonst()) return; lprcat("\n\nThere is a Holy Altar here!"); oaltar(); break; case OBOOK: lprcat("\n\nYou have found a book."); obook(); break; case OCOOKIE: lprcat("\n\nYou have found a fortune cookie."); ocookie(); break; case OTHRONE: if (nearbymonst()) return; lprintf("\n\nThere is %s here!",objectname[i]); othrone(0); break; case OTHRONE2: if (nearbymonst()) return; lprintf("\n\nThere is %s here!",objectname[i]); othrone(1); break; case ODEADTHRONE: lprintf("\n\nThere is %s here!",objectname[i]); odeadthrone(); break; case OORB: lprcat("\n\nYou have found the Orb!!!!!"); oorb(); break; case OPIT: lprcat("\n\nYou're standing at the top of a pit."); opit(); break; case OSTAIRSUP: lprcat("\n\nThere is a circular staircase here"); ostairs(1); /* up */ break; case OELEVATORUP: lprcat("\n\nYou feel heavy for a moment, but the feeling disappears"); oelevator(1); /* up */ break; case OFOUNTAIN: if (nearbymonst()) return; lprcat("\n\nThere is a fountain here"); ofountain(); break; case OSTATUE: if (nearbymonst()) return; lprcat("\n\nYou are standing in front of a statue"); ostatue(); break; case OCHEST: lprcat("\n\nThere is a chest here"); ochest(); break; case OIVTELETRAP: if (rnd(11)<6) return; item[playerx][playery] = OTELEPORTER; know[playerx][playery] = 1; case OTELEPORTER: lprcat("\nZaaaappp! You've been teleported!\n"); beep(); nap(3000); oteleport(0); break; case OSCHOOL: if (nearbymonst()) return; lprcat("\n\nYou have found the College of Larn."); lprcat("\nDo you (g) go inside, or (i) stay here? "); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') { oschool(); /* the college of larn */ } else lprcat(" stay here"); break; case OMIRROR: if (nearbymonst()) return; lprcat("\n\nThere is a mirror here"); omirror(); break; case OBANK2: case OBANK: if (nearbymonst()) return; if (i==OBANK) lprcat("\n\nYou have found the bank of Larn."); else lprcat("\n\nYou have found a branch office of the bank of Larn."); lprcat("\nDo you (g) go inside, or (i) stay here? "); j=0; while ((j!='g') && (j!='i') && (j!='\33')) j=getchar(); if (j == 'g') { if (i==OBANK) obank(); else obank2(); /* the bank of larn */ } else lprcat(" stay here"); break; case ODEADFOUNTAIN: if (nearbymonst()) return; lprcat("\n\nThere is a dead fountain here"); break; case ODNDSTORE: if (nearbymonst()) return; lprcat("\n\nThere is a DND store here."); lprcat("\nDo you (g) go inside, or (i) stay here? "); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') dndstore(); /* the dnd adventurers store */ else lprcat(" stay here"); break; case OSTAIRSDOWN: lprcat("\n\nThere is a circular staircase here"); ostairs(-1); /* down */ break; case OELEVATORDOWN: lprcat("\n\nYou feel light for a moment, but the feeling disappears"); oelevator(-1); /* down */ break; case OOPENDOOR: lprintf("\n\nYou have found %s",objectname[i]); lprcat("\nDo you (c) close it"); iopts(); i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar(); if ((i=='\33') || (i=='i')) { ignore(); break; } lprcat("close"); forget(); item[playerx][playery]=OCLOSEDDOOR; iarg[playerx][playery]=0; playerx = lastpx; playery = lastpy; break; case OCLOSEDDOOR: lprintf("\n\nYou have found %s",objectname[i]); lprcat("\nDo you (o) try to open it"); iopts(); i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=getchar(); if ((i=='\33') || (i=='i')) { ignore(); playerx = lastpx; playery = lastpy; break; } else { lprcat("open"); if (rnd(11)<7) { switch(iarg[playerx][playery]) { case 6: c[AGGRAVATE] += rnd(400); break; case 7: lprcat("\nYou are jolted by an electric shock "); lastnum=274; losehp(rnd(20)); bottomline(); break; case 8: loselevel(); break; case 9: lprcat("\nYou suddenly feel weaker "); if (c[STRENGTH]>3) c[STRENGTH]--; bottomline(); break; default: break; } playerx = lastpx; playery = lastpy; } else { forget(); item[playerx][playery]=OOPENDOOR; } } break; case OENTRANCE: lprcat("\nYou have found "); lprcat(objectname[OENTRANCE]); lprcat("\nDo you (g) go inside"); iopts(); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') { newcavelevel(1); playerx=33; playery=MAXY-2; item[33][MAXY-1]=know[33][MAXY-1]=mitem[33][MAXY-1]=0; draws(0,MAXX,0,MAXY); bot_linex(); return; } else ignore(); break; case OVOLDOWN: lprcat("\nYou have found "); lprcat(objectname[OVOLDOWN]); lprcat("\nDo you (c) climb down"); iopts(); i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar(); if ((i=='\33') || (i=='i')) { ignore(); break; } if (level!=0) { lprcat("\nThe shaft only extends 5 feet downward!"); return; } if (packweight() > 45+3*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep(); lastnum=275; losehp(30+rnd(20)); bottomhp(); } else lprcat("climb down"); nap(3000); newcavelevel(MAXLEVEL); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) /* put player near volcano shaft */ if (item[j][i]==OVOLUP) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); } draws(0,MAXX,0,MAXY); bot_linex(); return; case OVOLUP: lprcat("\nYou have found "); lprcat(objectname[OVOLUP]); lprcat("\nDo you (c) climb up"); iopts(); i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar(); if ((i=='\33') || (i=='i')) { ignore(); break; } if (level!=11) { lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!"); return; } if (packweight() > 45+5*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep(); lastnum=275; losehp(15+rnd(20)); bottomhp(); return; } lprcat("climb up"); lflush(); nap(3000); newcavelevel(0); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) /* put player near volcano shaft */ if (item[j][i]==OVOLDOWN) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); } draws(0,MAXX,0,MAXY); bot_linex(); return; case OTRAPARROWIV: if (rnd(17)<13) return; /* for an arrow trap */ item[playerx][playery] = OTRAPARROW; know[playerx][playery] = 0; case OTRAPARROW: lprcat("\nYou are hit by an arrow"); beep(); /* for an arrow trap */ lastnum=259; losehp(rnd(10)+level); bottomhp(); return; case OIVDARTRAP: if (rnd(17)<13) return; /* for a dart trap */ item[playerx][playery] = ODARTRAP; know[playerx][playery] = 0; case ODARTRAP: lprcat("\nYou are hit by a dart"); beep(); /* for a dart trap */ lastnum=260; losehp(rnd(5)); if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3; bottomline(); return; case OIVTRAPDOOR: if (rnd(17)<13) return; /* for a trap door */ item[playerx][playery] = OTRAPDOOR; know[playerx][playery] = 1; case OTRAPDOOR: lastnum = 272; /* a trap door */ if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1)) { lprcat("\nYou fell through a bottomless trap door!"); beep(); nap(3000); died(271); } lprcat("\nYou fall through a trap door!"); beep(); /* for a trap door */ losehp(rnd(5+level)); nap(2000); newcavelevel(level+1); draws(0,MAXX,0,MAXY); bot_linex(); return; case OTRADEPOST: if (nearbymonst()) return; lprcat("\nYou have found the Larn trading Post."); lprcat("\nDo you (g) go inside, or (i) stay here? "); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') otradepost(); else lprcat("stay here"); return; case OHOME: if (nearbymonst()) return; lprcat("\nYou have found your way home."); lprcat("\nDo you (g) go inside, or (i) stay here? "); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') ohome(); else lprcat("stay here"); return; case OWALL: break; case OANNIHILATION: died(283); return; /* annihilated by sphere of annihilation */ case OLRS: if (nearbymonst()) return; lprcat("\n\nThere is an LRS office here."); lprcat("\nDo you (g) go inside, or (i) stay here? "); i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar(); if (i == 'g') olrs(); /* the larn revenue service */ else lprcat(" stay here"); break; default: finditem(i); break; }; } /* function to say what object we found and ask if player wants to take it */ finditem(itm) int itm; { int tmp,i; lprintf("\n\nYou have found %s ",objectname[itm]); tmp=iarg[playerx][playery]; switch(itm) { case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: case OSPIRITSCARAB: case OORBOFDRAGON: case OCUBEofUNDEAD: case ONOTHEFT: break; default: if (tmp>0) lprintf("+ %d",(long)tmp); else if (tmp<0) lprintf(" %d",(long)tmp); } lprcat("\nDo you want to (t) take it"); iopts(); i=0; while (i!='t' && i!='i' && i!='\33') i=getchar(); if (i == 't') { lprcat("take"); if (take(itm,tmp)==0) forget(); return; } ignore(); } /* ******* OSTAIRS ******* subroutine to process the stair cases if dir > 0 the up else down */ ostairs(dir) int dir; { register int k; lprcat("\nDo you (s) stay here "); if (dir > 0) lprcat("(u) go up "); else lprcat("(d) go down "); lprcat("or (f) kick stairs? "); while (1) switch(getchar()) { case '\33': case 's': case 'i': lprcat("stay here"); return; case 'f': lprcat("kick stairs"); if (rnd(2) == 1) lprcat("\nI hope you feel better. Showing anger rids you of frustration."); else { k=rnd((level+1)<<1); lprintf("\nYou hurt your foot dumb dumb! You suffer %d hit points",(long)k); lastnum=276; losehp(k); bottomline(); } return; case 'u': lprcat("go up"); if (dir < 0) lprcat("\nThe stairs don't go up!"); else if (level>=2 && level!=11) { k = level; newcavelevel(level-1); draws(0,MAXX,0,MAXY); bot_linex(); } else lprcat("\nThe stairs lead to a dead end!"); return; case 'd': lprcat("go down"); if (dir > 0) lprcat("\nThe stairs don't go down!"); else if (level!=0 && level!=10 && level!=13) { k = level; newcavelevel(level+1); draws(0,MAXX,0,MAXY); bot_linex(); } else lprcat("\nThe stairs lead to a dead end!"); return; }; } /* ********* OTELEPORTER ********* subroutine to handle a teleport trap +/- 1 level maximum */ oteleport(err) int err; { register int tmp; if (err) if (rnd(151)<3) died(264); /* stuck in a rock */ c[TELEFLAG]=1; /* show ?? on bottomline if been teleported */ if (level==0) tmp=0; else if (level < MAXLEVEL) { tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1; if (tmp<1) tmp=1; } else { tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1; if (tmp<MAXLEVEL) tmp=MAXLEVEL; } playerx = rnd(MAXX-2); playery = rnd(MAXY-2); if (level != tmp) newcavelevel(tmp); positionplayer(); draws(0,MAXX,0,MAXY); bot_linex(); } /* ******* OPOTION ******* function to process a potion */ opotion(pot) int pot; { lprcat("\nDo you (d) drink it, (t) take it"); iopts(); while (1) switch(getchar()) { case '\33': case 'i': ignore(); return; case 'd': lprcat("drink\n"); forget(); /* destroy potion */ quaffpotion(pot); return; case 't': lprcat("take\n"); if (take(OPOTION,pot)==0) forget(); return; }; } /* function to drink a potion */ quaffpotion(pot) int pot; { register int i,j,k; if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */ potionname[pot][0] = ' '; switch(pot) { case 9: lprcat("\nYou feel greedy . . ."); nap(2000); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD)) { know[j][i]=1; show1cell(j,i); } showplayer(); return; case 19: lprcat("\nYou feel greedy . . ."); nap(2000); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) { k=item[j][i]; if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD) || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE)) { know[j][i]=1; show1cell(j,i); } } showplayer(); return; case 20: c[HP] = c[HPMAX]; break; /* instant healing */ case 1: lprcat("\nYou feel better"); if (c[HP] == c[HPMAX]) raisemhp(1); else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX]; break; case 2: lprcat("\nSuddenly, you feel much more skillful!"); raiselevel(); raisemhp(1); return; case 3: lprcat("\nYou feel strange for a moment"); c[rund(6)]++; break; case 4: lprcat("\nYou feel more self confident!"); c[WISDOM] += rnd(2); break; case 5: lprcat("\nWow! You feel great!"); if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++; break; case 6: lprcat("\nYour charm went up by one!"); c[CHARISMA]++; break; case 8: lprcat("\nYour intelligence went up by one!"); c[INTELLIGENCE]++; break; case 10: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) if (mitem[j][i]) { know[j][i]=1; show1cell(j,i); } /* monster detection */ return; case 12: lprcat("\nThis potion has no taste to it"); return; case 15: lprcat("\nWOW!!! You feel Super-fantastic!!!"); if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11; c[HERO] += 250; break; case 16: lprcat("\nYou have a greater intestinal constitude!"); c[CONSTITUTION]++; break; case 17: lprcat("\nYou now have incredibly bulging muscles!!!"); if (c[GIANTSTR]==0) c[STREXTRA] += 21; c[GIANTSTR] += 700; break; case 18: lprcat("\nYou feel a chill run up your spine!"); c[FIRERESISTANCE] += 1000; break; case 0: lprcat("\nYou fall asleep. . ."); i=rnd(11)-(c[CONSTITUTION]>>2)+2; while(--i>0) { parse2(); nap(1000); } cursors(); lprcat("\nYou woke up!"); return; case 7: lprcat("\nYou become dizzy!"); if (--c[STRENGTH] < 3) c[STRENGTH]=3; break; case 11: lprcat("\nYou stagger for a moment . ."); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=0; nap(2000); draws(0,MAXX,0,MAXY); /* potion of forgetfulness */ return; case 13: lprcat("\nYou can't see anything!"); /* blindness */ c[BLINDCOUNT]+=500; return; case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return; case 21: lprcat("\nYou don't seem to be affected"); return; /* cure dianthroritis */ case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */ c[HALFDAM] += 200 + rnd(200); return; case 23: lprcat("\nYou feel your vision sharpen"); /* see invisible */ c[SEEINVISIBLE] += rnd(1000)+400; monstnamelist[INVISIBLESTALKER] = 'I'; return; }; bottomline(); /* show new stats */ return; } /* ******* OSCROLL ******* function to process a magic scroll */ oscroll(typ) int typ; { lprcat("\nDo you "); if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts(); while (1) switch(getchar()) { case '\33': case 'i': ignore(); return; case 'r': if (c[BLINDCOUNT]) break; lprcat("read"); forget(); if (typ==2 || typ==15) { show1cell(playerx,playery); cursors(); } /* destroy it */ read_scroll(typ); return; case 't': lprcat("take"); if (take(OSCROLL,typ)==0) forget(); /* destroy it */ return; }; } /* data for the function to read a scroll */ static int xh,yh,yl,xl; static char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING, LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM }; static char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT, INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP }; char time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT, STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION, HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST, FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE, ITCHING,CLUMSINESS, WTW }; /* * function to adjust time when time warping and taking courses in school */ adjtime(tim) register long tim; { register int j; for (j=0; j<26; j++) /* adjust time related parameters */ if (c[time_change[j]]) if ((c[time_change[j]] -= tim) < 1) c[time_change[j]]=1; regen(); } /* function to read a scroll */ read_scroll(typ) int typ; { register int i,j; if (typ<0 || typ>=MAXSCROLL) return; /* be sure we are within bounds */ scrollname[typ][0] = ' '; switch(typ) { case 0: lprcat("\nYour armor glows for a moment"); enchantarmor(); return; case 1: lprcat("\nYour weapon glows for a moment"); enchweapon(); return; /* enchant weapon */ case 2: lprcat("\nYou have been granted enlightenment!"); yh = min(playery+7,MAXY); xh = min(playerx+25,MAXX); yl = max(playery-7,0); xl = max(playerx-25,0); for (i=yl; i<yh; i++) for (j=xl; j<xh; j++) know[j][i]=1; nap(2000); draws(xl,xh,yl,yh); return; case 3: lprcat("\nThis scroll seems to be blank"); return; case 4: createmonster(makemonst(level+1)); return; /* this one creates a monster */ case 5: something(level); /* create artifact */ return; case 6: c[AGGRAVATE]+=800; return; /* aggravate monsters */ case 7: gtime += (i = rnd(1000) - 850); /* time warp */ if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100)); else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100)); adjtime((long)i); /* adjust time for time warping */ return; case 8: oteleport(0); return; /* teleportation */ case 9: c[AWARENESS] += 1800; return; /* expanded awareness */ case 10: c[HASTEMONST] += rnd(55)+12; return; /* haste monster */ case 11: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) if (mitem[j][i]) hitp[j][i] = monster[mitem[j][i]].hitpoints; return; /* monster healing */ case 12: c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */ case 13: c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */ case 14: c[STEALTH] += 250 + rnd(250); bottomline(); return; /* stealth */ case 15: lprcat("\nYou have been granted enlightenment!"); /* magic mapping */ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=1; nap(2000); draws(0,MAXX,0,MAXY); return; case 16: c[HOLDMONST] += 30; bottomline(); return; /* hold monster */ case 17: for (i=0; i<26; i++) /* gem perfection */ switch(iven[i]) { case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: j = ivenarg[i]; j &= 255; j <<= 1; if (j > 255) j=255; /* double value */ ivenarg[i] = j; break; } break; case 18: for (i=0; i<11; i++) c[exten[i]] <<= 1; /* spell extension */ break; case 19: for (i=0; i<26; i++) /* identify */ { if (iven[i]==OPOTION) potionname[ivenarg[i]][0] = ' '; if (iven[i]==OSCROLL) scrollname[ivenarg[i]][0] = ' '; } break; case 20: for (i=0; i<10; i++) /* remove curse */ if (c[curse[i]]) c[curse[i]] = 1; break; case 21: annihilate(); break; /* scroll of annihilation */ case 22: godirect(22,150,"The ray hits the %s",0,' '); /* pulverization */ break; case 23: c[LIFEPROT]++; break; /* life protection */ }; } oorb() { } opit() { register int i; if (rnd(101)<81) if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5) if (level==MAXLEVEL-1) obottomless(); else if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else { if (rnd(101)<20) { i=0; lprcat("\nYou fell into a pit! Your fall is cushioned by an unknown force\n"); } else { i = rnd(level*3+3); lprintf("\nYou fell into a pit! You suffer %d hit points damage",(long)i); lastnum=261; /* if he dies scoreboard will say so */ } losehp(i); nap(2000); newcavelevel(level+1); draws(0,MAXX,0,MAXY); } } obottomless() { lprcat("\nYou fell into a bottomless pit!"); beep(); nap(3000); died(262); } oelevator(dir) int dir; { #ifdef lint int x; x=dir; dir=x; #endif lint } ostatue() { } omirror() { } obook() { lprcat("\nDo you "); if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts(); while (1) switch(getchar()) { case '\33': case 'i': ignore(); return; case 'r': if (c[BLINDCOUNT]) break; lprcat("read"); /* no more book */ readbook(iarg[playerx][playery]); forget(); return; case 't': lprcat("take"); if (take(OBOOK,iarg[playerx][playery])==0) forget(); /* no more book */ return; }; } /* function to read a book */ readbook(lev) register int lev; { register int i,tmp; if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else i = rnd((tmp=splev[lev]-9)?tmp:1) + 9; spelknow[i]=1; lprintf("\nSpell \"%s\": %s\n%s",spelcode[i],spelname[i],speldescript[i]); if (rnd(10)==4) { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); } } ocookie() { char *p; lprcat("\nDo you (e) eat it, (t) take it"); iopts(); while (1) switch(getchar()) { case '\33': case 'i': ignore(); return; case 'e': lprcat("eat\nThe cookie tasted good."); forget(); /* no more cookie */ if (c[BLINDCOUNT]) return; if (!(p=fortune(fortfile))) return; lprcat(" A message inside the cookie reads:\n"); lprcat(p); return; case 't': lprcat("take"); if (take(OCOOKIE,0)==0) forget(); /* no more book */ return; }; } /* routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 100* the argument */ ogold(arg) int arg; { register long i; i = iarg[playerx][playery]; if (arg==OMAXGOLD) i *= 100; else if (arg==OKGOLD) i *= 1000; else if (arg==ODGOLD) i *= 10; lprintf("\nIt is worth %d!",(long)i); c[GOLD] += i; bottomgold(); item[playerx][playery] = know[playerx][playery] = 0; /* destroy gold */ } ohome() { register int i; nosignal = 1; /* disable signals */ for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21) { iven[i]=0; /* remove the potion of cure dianthroritis from inventory */ clear(); lprcat("Congratulations. You found a potion of cure dianthroritis.\n"); lprcat("\nFrankly, No one thought you could do it. Boy! Did you surprise them!\n"); if (gtime>TIMELIMIT) { lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n"); lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n"); nap(5000); died(269); } else { lprcat("\nThe doctor is now administering the potion, and in a few moments\n"); lprcat("Your daughter should be well on her way to recovery.\n"); nap(6000); lprcat("\nThe potion is"); nap(3000); lprcat(" working! The doctor thinks that\n"); lprcat("your daughter will recover in a few days. Congratulations!\n"); beep(); nap(5000); died(263); } } while (1) { clear(); lprintf("Welcome home %s. Latest word from the doctor is not good.\n",logname); if (gtime>TIMELIMIT) { lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n"); lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n"); nap(5000); died(269); } lprcat("\nThe diagnosis is confirmed as dianthroritis. He guesses that\n"); lprintf("your daughter has only %d mobuls left in this world. It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100)); lprintf("%s, to find the only hope for your daughter, the very rare\n",logname); lprcat("potion of cure dianthroritis. It is rumored that only deep in the\n"); lprcat("depths of the caves can this potion be found.\n\n\n"); lprcat("\n ----- press "); standout("return"); lprcat(" to continue, "); standout("escape"); lprcat(" to leave ----- "); i=getchar(); while (i!='\33' && i!='\n') i=getchar(); if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; } } } /* routine to save program space */ iopts() { lprcat(", or (i) ignore it? "); } ignore() { lprcat("ignore\n"); } SHAR_EOF if test 25376 -ne "`wc -c < 'object.c'`" then echo shar: error transmitting "'object.c'" '(should have been 25376 characters)' fi fi echo shar: extracting "'regen.c'" '(3323 characters)' if test -f 'regen.c' then echo shar: will not over-write existing file "'regen.c'" else cat << \SHAR_EOF > 'regen.c' /* regen.c Larn is copyrighted 1986 by Noah Morgan. */ #include "header.h" /* ******* REGEN() ******* regen() subroutine to regenerate player hp and spells */ regen() { register int i,flag; register long *d; d = c; #ifdef EXTRA d[MOVESMADE]++; #endif if (d[TIMESTOP]) { if(--d[TIMESTOP]<=0) bottomline(); return; } /* for stop time spell */ flag=0; if (d[STRENGTH]<3) { d[STRENGTH]=3; flag=1; } if ((d[HASTESELF]==0) || ((d[HASTESELF] & 1) == 0)) gtime++; if (d[HP] != d[HPMAX]) if (d[REGENCOUNTER]-- <= 0) /* regenerate hit points */ { d[REGENCOUNTER] = 22 + (d[HARDGAME]<<1) - d[LEVEL]; if ((d[HP] += d[REGEN]) > d[HPMAX]) d[HP] = d[HPMAX]; bottomhp(); } if (d[SPELLS] < d[SPELLMAX]) /* regenerate spells */ if (d[ECOUNTER]-- <= 0) { d[ECOUNTER] = 100+4*(d[HARDGAME]-d[LEVEL]-d[ENERGY]); d[SPELLS]++; bottomspell(); } if (d[HERO]) if (--d[HERO]<=0) { for (i=0; i<6; i++) d[i] -= 10; flag=1; } if (d[ALTPRO]) if (--d[ALTPRO]<=0) { d[MOREDEFENSES]-=3; flag=1; } if (d[PROTECTIONTIME]) if (--d[PROTECTIONTIME]<=0) { d[MOREDEFENSES]-=2; flag=1; } if (d[DEXCOUNT]) if (--d[DEXCOUNT]<=0) { d[DEXTERITY]-=3; flag=1; } if (d[STRCOUNT]) if (--d[STRCOUNT]<=0) { d[STREXTRA]-=3; flag=1; } if (d[BLINDCOUNT]) if (--d[BLINDCOUNT]<=0) { cursors(); lprcat("\nThe blindness lifts "); beep(); } if (d[CONFUSE]) if (--d[CONFUSE]<=0) { cursors(); lprcat("\nYou regain your senses"); beep(); } if (d[GIANTSTR]) if (--d[GIANTSTR]<=0) { d[STREXTRA] -= 20; flag=1; } if (d[CHARMCOUNT]) if ((--d[CHARMCOUNT]) <= 0) flag=1; if (d[INVISIBILITY]) if ((--d[INVISIBILITY]) <= 0) flag=1; if (d[CANCELLATION]) if ((--d[CANCELLATION]) <= 0) flag=1; if (d[WTW]) if ((--d[WTW]) <= 0) flag=1; if (d[HASTESELF]) if ((--d[HASTESELF]) <= 0) flag=1; if (d[AGGRAVATE]) --d[AGGRAVATE]; if (d[SCAREMONST]) if ((--d[SCAREMONST]) <= 0) flag=1; if (d[STEALTH]) if ((--d[STEALTH]) <= 0) flag=1; if (d[AWARENESS]) --d[AWARENESS]; if (d[HOLDMONST]) if ((--d[HOLDMONST]) <= 0) flag=1; if (d[HASTEMONST]) --d[HASTEMONST]; if (d[FIRERESISTANCE]) if ((--d[FIRERESISTANCE]) <= 0) flag=1; if (d[GLOBE]) if (--d[GLOBE]<=0) { d[MOREDEFENSES]-=10; flag=1; } if (d[SPIRITPRO]) if (--d[SPIRITPRO] <= 0) flag=1; if (d[UNDEADPRO]) if (--d[UNDEADPRO] <= 0) flag=1; if (d[HALFDAM]) if (--d[HALFDAM]<=0) { cursors(); lprcat("\nYou now feel better "); beep(); } if (d[SEEINVISIBLE]) if (--d[SEEINVISIBLE]<=0) { monstnamelist[INVISIBLESTALKER] = ' '; cursors(); lprcat("\nYou feel your vision return to normal"); beep(); } if (d[ITCHING]) { if (d[ITCHING]>1) if ((d[WEAR]!= -1) || (d[SHIELD]!= -1)) if (rnd(100)<50) { d[WEAR]=d[SHIELD]= -1; cursors(); lprcat("\nThe hysteria of itching forces you to remove your armor!"); beep(); recalc(); bottomline(); } if (--d[ITCHING]<=0) { cursors(); lprcat("\nYou now feel the irritation subside!"); beep(); } } if (d[CLUMSINESS]) { if (d[WIELD] != -1) if (d[CLUMSINESS]>1) if (item[playerx][playery]==0) /* only if nothing there */ if (rnd(100)<33) /* drop your weapon due to clumsiness */ drop_object((int)d[WIELD]); if (--d[CLUMSINESS]<=0) { cursors(); lprcat("\nYou now feel less awkward!"); beep(); } } if (flag) bottomline(); } SHAR_EOF if test 3323 -ne "`wc -c < 'regen.c'`" then echo shar: error transmitting "'regen.c'" '(should have been 3323 characters)' fi fi echo shar: extracting "'scores.c'" '(21238 characters)' if test -f 'scores.c' then echo shar: will not over-write existing file "'scores.c'" else cat << \SHAR_EOF > 'scores.c' /* scores.c Larn is copyrighted 1986 by Noah Morgan. * * Functions in this file are: * * readboard() Function to read in the scoreboard into a static buffer * writeboard() Function to write the scoreboard from readboard()'s buffer * makeboard() Function to create a new scoreboard (wipe out old one) * hashewon() Function to return 1 if player has won a game before, else 0 * long paytaxes(x) Function to pay taxes if any are due * winshou() Subroutine to print out the winning scoreboard * shou(x) Subroutine to print out the non-winners scoreboard * showscores() Function to show the scoreboard on the terminal * showallscores() Function to show scores and the iven lists that go with them * sortboard() Function to sort the scoreboard * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard * new1sub(score,i,whoo,taxes) Subroutine to put player into a * new2sub(score,i,whoo,whyded) Subroutine to put player into a * died(x) Subroutine to record who played larn, and what the score was * diedsub(x) Subroutine to print out a line showing player when he is killed * diedlog() Subroutine to read a log file and print it out in ascii format * getplid(name) Function to get players id # from id file * */ #include <sys/types.h> #include <sys/times.h> #include <sys/stat.h> #include "header.h" struct scofmt /* This is the structure for the scoreboard */ { long score; /* the score of the player */ long suid; /* the user id number of the player */ short what; /* the number of the monster that killed player */ short level; /* the level player was on when he died */ short hardlev; /* the level of difficulty player played at */ short order; /* the relative ordering place of this entry */ char who[40]; /* the name of the character */ char sciv[26][2]; /* this is the inventory list of the character */ }; struct wscofmt /* This is the structure for the winning scoreboard */ { long score; /* the score of the player */ long timeused; /* the time used in mobuls to win the game */ long taxes; /* taxes he owes to LRS */ long suid; /* the user id number of the player */ short hardlev; /* the level of difficulty player played at */ short order; /* the relative ordering place of this entry */ char who[40]; /* the name of the character */ }; struct log_fmt /* 102 bytes struct for the log file */ { long score; /* the players score */ long diedtime; /* time when game was over */ short cavelev; /* level in caves */ short diff; /* difficulty player played at */ #ifdef EXTRA long elapsedtime; /* real time of game in seconds */ long bytout; /* bytes input and output */ long bytin; long moves; /* number of moves made by player */ short ac; /* armor class of player */ short hp,hpmax; /* players hitpoints */ short cputime; /* cpu time needed in seconds */ short killed,spused;/* monsters killed and spells cast */ short usage; /* usage of the cpu in % */ short lev; /* player level */ #endif char who[12]; /* player name */ char what[46]; /* what happened to player */ }; static struct scofmt sco[SCORESIZE]; /* the structure for the scoreboard */ static struct wscofmt winr[SCORESIZE]; /* struct for the winning scoreboard */ static struct log_fmt logg; /* structure for the log file */ static char *whydead[] = { "quit", "suspended", "self - annihilated", "shot by an arrow", "hit by a dart", "fell into a pit", "fell into a bottomless pit", "a winner", "trapped in solid rock", "killed by a missing save file", "killed by an old save file", "caught by the greedy cheater checker trap", "killed by a protected save file","killed his family and committed suicide", "erased by a wayward finger", "fell through a bottomless trap door", "fell through a trap door", "drank some poisonous water", "fried by an electric shock", "slipped on a volcano shaft", "killed by a stupid act of frustration", "attacked by a revolting demon", "hit by his own magic", "demolished by an unseen attacker", "fell into the dreadful sleep", "killed by an exploding chest", /*26*/ "killed by a missing maze data file", "annihilated in a sphere", "died a post mortem death","wasted by a malloc() failure" }; /* * readboard() Function to read in the scoreboard into a static buffer * * returns -1 if unable to read in the scoreboard, returns 0 if all is OK */ readboard() { if (lopen(scorefile)<0) { lprcat("Can't read scoreboard\n"); lflush(); return(-1); } lrfill((char*)sco,sizeof(sco)); lrfill((char*)winr,sizeof(winr)); lrclose(); lcreat((char*)0); return(0); } /* * writeboard() Function to write the scoreboard from readboard()'s buffer * * returns -1 if unable to write the scoreboard, returns 0 if all is OK */ writeboard() { set_score_output(); if (lcreat(scorefile)<0) { lprcat("Can't write scoreboard\n"); lflush(); return(-1); } lwrite((char*)sco,sizeof(sco)); lwrite((char*)winr,sizeof(winr)); lwclose(); lcreat((char*)0); return(0); } /* * makeboard() Function to create a new scoreboard (wipe out old one) * * returns -1 if unable to write the scoreboard, returns 0 if all is OK */ makeboard() { register int i; for (i=0; i<SCORESIZE; i++) { winr[i].taxes = winr[i].score = sco[i].score = 0; winr[i].order = sco[i].order = i; } if (writeboard()) return(-1); chmod(scorefile,0666); return(0); } /* * hashewon() Function to return 1 if player has won a game before, else 0 * * This function also sets c[HARDGAME] to appropriate value -- 0 if not a * winner, otherwise the next level of difficulty listed in the winners * scoreboard. This function also sets outstanding_taxes to the value in * the winners scoreboard. */ hashewon() { register int i; c[HARDGAME] = 0; if (readboard() < 0) return(0); /* can't find scoreboard */ for (i=0; i<SCORESIZE; i++) /* search through winners scoreboard */ if (winr[i].suid == userid) if (winr[i].score > 0) { c[HARDGAME]=winr[i].hardlev+1; outstanding_taxes=winr[i].taxes; return(1); } return(0); } /* * long paytaxes(x) Function to pay taxes if any are due * * Enter with the amount (in gp) to pay on the taxes. * Returns amount actually paid. */ long paytaxes(x) long x; { register int i; register long amt; if (x<0) return(0L); if (readboard()<0) return(0L); for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid) /* look for players winning entry */ if (winr[i].score>0) /* search for a winning entry for the player */ { amt = winr[i].taxes; if (x < amt) amt=x; /* don't overpay taxes (Ughhhhh) */ winr[i].taxes -= amt; outstanding_taxes -= amt; if (writeboard()<0) return(0); return(amt); } return(0L); /* couldn't find user on winning scoreboard */ } /* * winshou() Subroutine to print out the winning scoreboard * * Returns the number of players on scoreboard that were shown */ winshou() { register struct wscofmt *p; register int i,j,count; for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */ if (winr[i].score != 0) { j++; break; } if (j) { lprcat("\n Score Difficulty Time Needed Larn Winners List\n"); for (i=0; i<SCORESIZE; i++) /* this loop is needed to print out the */ for (j=0; j<SCORESIZE; j++) /* winners in order */ { p = &winr[j]; /* pointer to the scoreboard entry */ if (p->order == i) { if (p->score) { count++; lprintf("%10d %2d %5d Mobuls %s \n", (long)p->score,(long)p->hardlev,(long)p->timeused,p->who); } break; } } } return(count); /* return number of people on scoreboard */ } /* * shou(x) Subroutine to print out the non-winners scoreboard * int x; * * Enter with 0 to list the scores, enter with 1 to list inventories too * Returns the number of players on scoreboard that were shown */ shou(x) int x; { register int i,j,n,k; int count; for (count=j=i=0; i<SCORESIZE; i++) /* is the scoreboard empty? */ if (sco[i].score!= 0) { j++; break; } if (j) { lprcat("\n Score Difficulty Larn Visitor Log\n"); for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */ for (j=0; j<SCORESIZE; j++) if (sco[j].order == i) { if (sco[j].score) { count++; lprintf("%10d %2d %s ", (long)sco[j].score,(long)sco[j].hardlev,sco[j].who); if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name); else lprintf("%s",whydead[sco[j].what - 256]); if (x != 263) lprintf(" on %s",levelname[sco[j].level]); if (x) { for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; } for (k=1; k<99; k++) for (n=0; n<26; n++) if (k==iven[n]) { srcount=0; show3(n); } lprcat("\n\n"); } else lprc('\n'); } j=SCORESIZE; } } return(count); /* return the number of players just shown */ } /* * showscores() Function to show the scoreboard on the terminal * * Returns nothing of value */ static char esb[] = "The scoreboard is empty.\n"; showscores() { register int i,j; lflush(); lcreat((char*)0); if (readboard()<0) return; i=winshou(); j=shou(0); if (i+j == 0) lprcat(esb); else lprc('\n'); lflush(); } /* * showallscores() Function to show scores and the iven lists that go with them * * Returns nothing of value */ showallscores() { register int i,j; lflush(); lcreat((char*)0); if (readboard()<0) return; c[WEAR] = c[WIELD] = c[SHIELD] = -1; /* not wielding or wearing anything */ for (i=0; i<MAXPOTION; i++) potionname[i][0]=' '; for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' '; i=winshou(); j=shou(1); if (i+j==0) lprcat(esb); else lprc('\n'); lflush(); } /* * sortboard() Function to sort the scoreboard * * Returns 0 if no sorting done, else returns 1 */ sortboard() { register int i,j,pos; long jdat; for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1; pos=0; while (pos < SCORESIZE) { jdat=0; for (i=0; i<SCORESIZE; i++) if ((sco[i].order < 0) && (sco[i].score >= jdat)) { j=i; jdat=sco[i].score; } sco[j].order = pos++; } pos=0; while (pos < SCORESIZE) { jdat=0; for (i=0; i<SCORESIZE; i++) if ((winr[i].order < 0) && (winr[i].score >= jdat)) { j=i; jdat=winr[i].score; } winr[j].order = pos++; } return(1); } /* * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard * int score, winner, whyded; * char *whoo; * * Enter with the total score in gp in score, players name in whoo, * died() reason # in whyded, and TRUE/FALSE in winner if a winner * ex. newscore(1000, "player 1", 32, 0); */ newscore(score, whoo, whyded, winner) long score; int winner, whyded; char *whoo; { register int i; long taxes; if (readboard() < 0) return; /* do the scoreboard */ /* if a winner then delete all non-winning scores */ if (cheat) winner=0; /* if he cheated, don't let him win */ if (winner) { for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0; taxes = score*TAXRATE; score += 100000*c[HARDGAME]; /* bonus for winning */ /* if he has a slot on the winning scoreboard update it if greater score */ for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid) { new1sub(score,i,whoo,taxes); return; } /* he had no entry. look for last entry and see if he has a greater score */ for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1) { new1sub(score,i,whoo,taxes); return; } } else if (!cheat) /* for not winning scoreboard */ { /* if he has a slot on the scoreboard update it if greater score */ for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) { new2sub(score,i,whoo,whyded); return; } /* he had no entry. look for last entry and see if he has a greater score */ for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1) { new2sub(score,i,whoo,whyded); return; } } } /* * new1sub(score,i,whoo,taxes) Subroutine to put player into a * int score,i,whyded,taxes; winning scoreboard entry if his score * char *whoo; is high enough * * Enter with the total score in gp in score, players name in whoo, * died() reason # in whyded, and TRUE/FALSE in winner if a winner * slot in scoreboard in i, and the tax bill in taxes. * Returns nothing of value */ new1sub(score,i,whoo,taxes) long score,taxes; int i; char *whoo; { register struct wscofmt *p; p = &winr[i]; p->taxes += taxes; if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) { strcpy(p->who,whoo); p->score=score; p->hardlev=c[HARDGAME]; p->suid=userid; p->timeused=gtime/100; } } /* * new2sub(score,i,whoo,whyded) Subroutine to put player into a * int score,i,whyded,taxes; non-winning scoreboard entry if his * char *whoo; score is high enough * * Enter with the total score in gp in score, players name in whoo, * died() reason # in whyded, and slot in scoreboard in i. * Returns nothing of value */ new2sub(score,i,whoo,whyded) long score; int i,whyded; char *whoo; { register int j; register struct scofmt *p; p = &sco[i]; if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) { strcpy(p->who,whoo); p->score=score; p->what=whyded; p->hardlev=c[HARDGAME]; p->suid=userid; p->level=level; for (j=0; j<26; j++) { p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; } } } /* * died(x) Subroutine to record who played larn, and what the score was * int x; * * if x < 0 then don't show scores * died() never returns! (unless c[LIFEPROT] and a reincarnatable death!) * * < 256 killed by the monster number * 256 quit * 257 suspended * 258 self - annihilated * 259 shot by an arrow * 260 hit by a dart * 261 fell into a pit * 262 fell into a bottomless pit * 263 a winner * 264 trapped in solid rock * 265 killed by a missing save file * 266 killed by an old save file * 267 caught by the greedy cheater checker trap * 268 killed by a protected save file * 269 killed his family and killed himself * 270 erased by a wayward finger * 271 fell through a bottomless trap door * 272 fell through a trap door * 273 drank some poisonous water * 274 fried by an electric shock * 275 slipped on a volcano shaft * 276 killed by a stupid act of frustration * 277 attacked by a revolting demon * 278 hit by his own magic * 279 demolished by an unseen attacker * 280 fell into the dreadful sleep * 281 killed by an exploding chest * 282 killed by a missing maze data file * 283 killed by a sphere of annihilation * 284 died a post mortem death * 285 malloc() failure * 300 quick quit -- don't put on scoreboard */ static int scorerror; died(x) int x; { register int f,win; char ch,*mod; long zzz,i; struct tms cputime; if (c[LIFEPROT]>0) /* if life protection */ { switch((x>0) ? x : -x) { case 256: case 257: case 262: case 263: case 265: case 266: case 267: case 268: case 269: case 271: case 282: case 284: case 285: case 300: goto invalid; /* can't be saved */ }; --c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION]; cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep(); lflush(); sleep(4); return; /* only case where died() returns */ } invalid: clearvt100(); lflush(); f=0; if (ckpflag) unlink(ckpfile); /* remove checkpoint file if used */ if (x<0) { f++; x = -x; } /* if we are not to display the scores */ if ((x == 300) || (x == 257)) exit(); /* for quick exit or saved game */ if (x == 263) win = 1; else win = 0; c[GOLD] += c[BANKACCOUNT]; c[BANKACCOUNT] = 0; /* now enter the player at the end of the scoreboard */ newscore(c[GOLD], logname, x, win); diedsub(x); /* print out the score line */ lflush(); set_score_output(); if ((wizard == 0) && (c[GOLD] > 0)) /* wizards can't score */ { if (lappend(logfile)<0) /* append to file */ { if (lcreat(logfile)<0) /* and can't create new log file */ { lcreat((char*)0); lprcat("\nCan't open record file: I can't post your score.\n"); sncbr(); resetscroll(); lflush(); exit(); } chmod(logfile,0666); } strcpy(logg.who,loginname); logg.score = c[GOLD]; logg.diff = c[HARDGAME]; if (x < 256) { ch = *monster[x].name; if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') mod="an"; else mod="a"; sprintf(logg.what,"killed by %s %s",mod,monster[x].name); } else sprintf(logg.what,"%s",whydead[x - 256]); logg.cavelev=level; time(&zzz); /* get cpu time -- write out score info */ logg.diedtime=zzz; #ifdef EXTRA times(&cputime); /* get cpu time -- write out score info */ logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME]; logg.lev=c[LEVEL]; logg.ac=c[AC]; logg.hpmax=c[HPMAX]; logg.hp=c[HP]; logg.elapsedtime=(zzz-initialtime+59)/60; logg.usage=(10000*i)/(zzz-initialtime); logg.bytin=c[BYTESIN]; logg.bytout=c[BYTESOUT]; logg.moves=c[MOVESMADE]; logg.spused=c[SPELLSCAST]; logg.killed=c[MONSTKILLED]; #endif lwrite((char*)&logg,sizeof(struct log_fmt)); lwclose(); /* now for the scoreboard maintenance -- not for a suspended game */ if (x != 257) { if (sortboard()) scorerror = writeboard(); } } if ((x==256) || (x==257) || (f != 0)) exit(); if (scorerror == 0) showscores(); /* if we updated the scoreboard */ if (x == 263) mailbill(); exit(); } /* * diedsub(x) Subroutine to print out the line showing the player when he is killed * int x; */ diedsub(x) int x; { register char ch,*mod; lprintf("Score: %d, Diff: %d, %s ",(long)c[GOLD],(long)c[HARDGAME],logname); if (x < 256) { ch = *monster[x].name; if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') mod="an"; else mod="a"; lprintf("killed by %s %s",mod,monster[x].name); } else lprintf("%s",whydead[x - 256]); if (x != 263) lprintf(" on %s\n",levelname[level]); else lprc('\n'); } /* * diedlog() Subroutine to read a log file and print it out in ascii format */ diedlog() { register int n; register char *p; struct stat stbuf; lcreat((char*)0); if (lopen(logfile)<0) { lprintf("Can't locate log file <%s>\n",logfile); return; } if (fstat(fd,&stbuf) < 0) { lprintf("Can't stat log file <%s>\n",logfile); return; } for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n) { lrfill((char*)&logg,sizeof(struct log_fmt)); p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0; lprintf("Score: %d, Diff: %d, %s %s on %d at %s",(long)(logg.score),(long)(logg.diff),logg.who,logg.what,(long)(logg.cavelev),p+4); #ifdef EXTRA if (logg.moves<=0) logg.moves=1; lprintf(" Experience Level: %d, AC: %d, HP: %d/%d, Elapsed Time: %d minutes\n",(long)(logg.lev),(long)(logg.ac),(long)(logg.hp),(long)(logg.hpmax),(long)(logg.elapsedtime)); lprintf(" CPU time used: %d seconds, Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100)); lprintf(" BYTES in: %d, out: %d, moves: %d, deaths: %d, spells cast: %d\n",(long)(logg.bytin),(long)(logg.bytout),(long)(logg.moves),(long)(logg.killed),(long)(logg.spused)); lprintf(" out bytes per move: %d, time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves)); #endif } lflush(); lrclose(); return; } #ifndef UIDSCORE /* * getplid(name) Function to get players id # from id file * * Enter with the name of the players character in name. * Returns the id # of the players character, or -1 if failure. * This routine will try to find the name in the id file, if its not there, * it will try to make a new entry in the file. Only returns -1 if can't * find him in the file, and can't make a new entry in the file. * Format of playerids file: * Id # in ascii \n character name \n */ static int havepid= -1; /* playerid # if previously done */ getplid(nam) char *nam; { int fd7,high=999,no; register char *p,*p2; char name[80]; if (havepid != -1) return(havepid); /* already did it */ lflush(); /* flush any pending I/O */ sprintf(name,"%s\n",nam); /* append a \n to name */ if (lopen(playerids) < 0) /* no file, make it */ { if ((fd7=creat(playerids,0666)) < 0) return(-1); /* can't make it */ close(fd7); goto addone; /* now append new playerid record to file */ } for (;;) /* now search for the name in the player id file */ { p = lgetl(); if (p==NULL) break; /* EOF? */ no = atoi(p); /* the id # */ p2= lgetl(); if (p2==NULL) break; /* EOF? */ if (no>high) high=no; /* accumulate highest id # */ if (strcmp(p2,name)==0) /* we found him */ { return(no); /* his id number */ } } lrclose(); /* if we get here, we didn't find him in the file -- put him there */ addone: if (lappend(playerids) < 0) return(-1); /* can't open file for append */ lprintf("%d\n%s",(long)++high,name); /* new id # and name */ lwclose(); lcreat((char*)0); /* re-open terminal channel */ return(high); } #endif UIDSCORE SHAR_EOF if test 21238 -ne "`wc -c < 'scores.c'`" then echo shar: error transmitting "'scores.c'" '(should have been 21238 characters)' fi fi echo shar: extracting "'signal.c'" '(4780 characters)' if test -f 'signal.c' then echo shar: will not over-write existing file "'signal.c'" else cat << \SHAR_EOF > 'signal.c' #include <signal.h> #include "header.h" /* "Larn is copyrighted 1986 by Noah Morgan.\n" */ #define BIT(a) (1<<((a)-1)) extern char savefilename[],wizard,predostuff,nosignal; static s2choose() /* text to be displayed if ^C during intro screen */ { cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold(); lprcat(" to continue: "); lflush(); } static cntlc() /* what to do for a ^C */ { if (nosignal) return; /* don't do anything if inhibited */ signal(SIGQUIT,SIG_IGN); signal(SIGINT,SIG_IGN); quit(); if (predostuff==1) s2choose(); else showplayer(); lflush(); signal(SIGQUIT,cntlc); signal(SIGINT,cntlc); } /* * subroutine to save the game if a hangup signal */ static sgam() { savegame(savefilename); wizard=1; died(-257); /* hangup signal */ } #ifdef SIGTSTP static tstop() /* control Y */ { if (nosignal) return; /* nothing if inhibited */ lcreat((char*)0); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL); #ifdef SIGVTALRM /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/ sigsetmask(sigblock(0)& ~BIT(SIGTSTP)); #endif kill(getpid(),SIGTSTP); setupvt100(); signal(SIGTSTP,tstop); if (predostuff==1) s2choose(); else drawscreen(); showplayer(); lflush(); } #endif SIGTSTP /* * subroutine to issue the needed signal traps called from main() */ static sigill() { sigpanic(SIGILL); } static sigtrap() { sigpanic(SIGTRAP); } static sigiot() { sigpanic(SIGIOT); } static sigemt() { sigpanic(SIGEMT); } static sigfpe() { sigpanic(SIGFPE); } static sigbus() { sigpanic(SIGBUS); } static sigsegv() { sigpanic(SIGSEGV); } static sigsys() { sigpanic(SIGSYS); } static sigpipe() { sigpanic(SIGPIPE); } static sigterm() { sigpanic(SIGTERM); } sigsetup() { signal(SIGQUIT, cntlc); signal(SIGINT, cntlc); signal(SIGKILL, SIG_IGN); signal(SIGHUP, sgam); signal(SIGILL, sigill); signal(SIGTRAP, sigtrap); signal(SIGIOT, sigiot); signal(SIGEMT, sigemt); signal(SIGFPE, sigfpe); signal(SIGBUS, sigbus); signal(SIGSEGV, sigsegv); signal(SIGSYS, sigsys); signal(SIGPIPE, sigpipe); signal(SIGTERM, sigterm); #ifdef SIGTSTP signal(SIGTSTP,tstop); signal(SIGSTOP,tstop); #endif SIGTSTP } #ifdef BSD /* for BSD UNIX? */ static char *signame[NSIG] = { "", "SIGHUP", /* 1 hangup */ "SIGINT", /* 2 interrupt */ "SIGQUIT", /* 3 quit */ "SIGILL", /* 4 illegal instruction (not reset when caught) */ "SIGTRAP", /* 5 trace trap (not reset when caught) */ "SIGIOT", /* 6 IOT instruction */ "SIGEMT", /* 7 EMT instruction */ "SIGFPE", /* 8 floating point exception */ "SIGKILL", /* 9 kill (cannot be caught or ignored) */ "SIGBUS", /* 10 bus error */ "SIGSEGV", /* 11 segmentation violation */ "SIGSYS", /* 12 bad argument to system call */ "SIGPIPE", /* 13 write on a pipe with no one to read it */ "SIGALRM", /* 14 alarm clock */ "SIGTERM", /* 15 software termination signal from kill */ "SIGURG", /* 16 urgent condition on IO channel */ "SIGSTOP", /* 17 sendable stop signal not from tty */ "SIGTSTP", /* 18 stop signal from tty */ "SIGCONT", /* 19 continue a stopped process */ "SIGCHLD", /* 20 to parent on child stop or exit */ "SIGTTIN", /* 21 to readers pgrp upon background tty read */ "SIGTTOU", /* 22 like TTIN for output if (tp->t_local<OSTOP) */ "SIGIO", /* 23 input/output possible signal */ "SIGXCPU", /* 24 exceeded CPU time limit */ "SIGXFSZ", /* 25 exceeded file size limit */ "SIGVTALRM",/* 26 virtual time alarm */ "SIGPROF", /* 27 profiling time alarm */ "","","","" }; #else BSD /* for system V? */ static char *signame[NSIG] = { "", "SIGHUP", /* 1 hangup */ "SIGINT", /* 2 interrupt */ "SIGQUIT", /* 3 quit */ "SIGILL", /* 4 illegal instruction (not reset when caught) */ "SIGTRAP", /* 5 trace trap (not reset when caught) */ "SIGIOT", /* 6 IOT instruction */ "SIGEMT", /* 7 EMT instruction */ "SIGFPE", /* 8 floating point exception */ "SIGKILL", /* 9 kill (cannot be caught or ignored) */ "SIGBUS", /* 10 bus error */ "SIGSEGV", /* 11 segmentation violation */ "SIGSYS", /* 12 bad argument to system call */ "SIGPIPE", /* 13 write on a pipe with no one to read it */ "SIGALRM", /* 14 alarm clock */ "SIGTERM", /* 15 software termination signal from kill */ "SIGUSR1", /* 16 user defines signal 1 */ "SIGUSR2", /* 17 user defines signal 2 */ "SIGCLD", /* 18 child death */ "SIGPWR", /* 19 power fail */ "","","","","","","","","","","","" }; #endif BSD /* * routine to process a fatal error signal */ static sigpanic(sig) int sig; { char buf[128]; signal(sig,SIG_DFL); sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]); write(2,buf,strlen(buf)); sleep(2); sncbr(); savegame(savefilename); kill(getpid(),sig); /* this will terminate us */ } SHAR_EOF if test 4780 -ne "`wc -c < 'signal.c'`" then echo shar: error transmitting "'signal.c'" '(should have been 4780 characters)' fi fi echo shar: extracting "'tok.c'" '(5637 characters)' if test -f 'tok.c' then echo shar: will not over-write existing file "'tok.c'" else cat << \SHAR_EOF > 'tok.c' /* tok.c Larn is copyrighted 1986 by Noah Morgan. */ #include <sys/types.h> #ifdef SYSV #include <fcntl.h> #include <termio.h> #else SYSV #include <sys/ioctl.h> #endif SYSV #include "header.h" static char lastok=0; int yrepcount=0,dayplay=0; #ifndef FLUSHNO #define FLUSHNO 5 #endif FLUSHNO static int flushno=FLUSHNO; /* input queue flushing threshold */ #define MAXUM 52 /* maximum number of user re-named monsters */ #define MAXMNAME 40 /* max length of a monster re-name */ static char usermonster[MAXUM][MAXMNAME]; /* the user named monster name goes here */ static char usermpoint=0; /* the user monster pointer */ /* lexical analyzer for larn */ yylex() { char cc; int ic; if (hit2flag) { hit2flag=0; yrepcount=0; return(' '); } if (yrepcount>0) { --yrepcount; return(lastok); } else yrepcount=0; if (yrepcount==0) { bottomdo(); showplayer(); } /* show where the player is */ lflush(); while (1) { c[BYTESIN]++; if (ckpflag) if ((c[BYTESIN] % 400) == 0) /* check for periodic checkpointing */ { #ifndef DOCHECKPOINTS savegame(ckpfile); #else wait(0); /* wait for other forks to finish */ if (fork() == 0) { savegame(ckpfile); exit(); } #endif #ifdef TIMECHECK if (dayplay==0) if (playable()) { cursor(1,19); lprcat("\nSorry, but it is now time for work. Your game has been saved.\n"); beep(); lflush(); savegame(savefilename); wizard=nomove=1; sleep(4); died(-257); } #endif TIMECHECK } do /* if keyboard input buffer is too big, flush some of it */ { ioctl(0,FIONREAD,&ic); if (ic>flushno) read(0,&cc,1); } while (ic>flushno); if (read(0,&cc,1) != 1) return(lastok = -1); if (cc == 'Y'-64) /* control Y -- shell escape */ { resetscroll(); clear(); /* scrolling region, home, clear, no attributes */ if ((ic=fork())==0) /* child */ { execl("/bin/csh",0); exit(); } wait(0); if (ic<0) /* error */ { write(2,"Can't fork off a shell!\n",25); sleep(2); } setscroll(); return(lastok = 'L'-64); /* redisplay screen */ } if ((cc <= '9') && (cc >= '0')) { yrepcount = yrepcount*10 + cc - '0'; } else { if (yrepcount>0) --yrepcount; return(lastok = cc); } } } /* * flushall() Function to flush all type-ahead in the input buffer */ flushall() { char cc; int ic; for (;;) /* if keyboard input buffer is too big, flush some of it */ { ioctl(0,FIONREAD,&ic); if (ic<=0) return; while (ic>0) { read(0,&cc,1); --ic; } /* gobble up the byte */ } } /* function to set the desired hardness enter with hard= -1 for default hardness, else any desired hardness */ sethard(hard) int hard; { register int j,k,i; j=c[HARDGAME]; hashewon(); if (restorflag==0) /* don't set c[HARDGAME] if restoring game */ { if (hard >= 0) c[HARDGAME]= hard; } else c[HARDGAME]=j; /* set c[HARDGAME] to proper value if restoring game */ if (k=c[HARDGAME]) for (j=0; j<=MAXMONST+8; j++) { i = ((6+k)*monster[j].hitpoints+1)/6; monster[j].hitpoints = (i<0) ? 32767 : i; i = ((6+k)*monster[j].damage+1)/5; monster[j].damage = (i>127) ? 127 : i; i = (10*monster[j].gold)/(10+k); monster[j].gold = (i>32767) ? 32767 : i; i = monster[j].armorclass - k; monster[j].armorclass = (i< -127) ? -127 : i; i = (7*monster[j].experience)/(7+k) + 1; monster[j].experience = (i<=0) ? 1 : i; } } /* function to read and process the larn options file */ readopts() { register char *i; register int j,k; int flag; flag=1; /* set to 0 if he specifies a name for his character */ if (lopen(optsfile) < 0) { strcpy(logname,loginname); return; /* user name if no character name */ } i = " "; while (*i) { if ((i=(char *)lgetw()) == 0) break; /* check for EOF */ while ((*i==' ') || (*i=='\t')) i++; /* eat leading whitespace */ switch(*i) { case 'b': if (strcmp(i,"bold-objects") == 0) boldon=1; break; case 'e': if (strcmp(i,"enable-checkpointing") == 0) ckpflag=1; break; case 'i': if (strcmp(i,"inverse-objects") == 0) boldon=0; break; case 'f': if (strcmp(i,"female") == 0) sex=0; /* male or female */ break; case 'm': if (strcmp(i,"monster:")== 0) /* name favorite monster */ { if ((i=lgetw())==0) break; if (strlen(i)>=MAXMNAME) i[MAXMNAME-1]=0; strcpy(usermonster[usermpoint],i); if (usermpoint >= MAXUM) break; /* defined all of em */ if (isalpha(j=usermonster[usermpoint][0])) { for (k=1; k<MAXMONST+8; k++) /* find monster */ if (monstnamelist[k] == j) { monster[k].name = &usermonster[usermpoint++][0]; break; } } } else if (strcmp(i,"male") == 0) sex=1; break; case 'n': if (strcmp(i,"name:") == 0) /* defining players name */ { if ((i=lgetw())==0) break; if (strlen(i)>=LOGNAMESIZE) i[LOGNAMESIZE-1]=0; strcpy(logname,i); flag=0; } else if (strcmp(i,"no-introduction") == 0) nowelcome=1; else if (strcmp(i,"no-beep") == 0) nobeep=1; break; case 'p': if (strcmp(i,"process-name:")== 0) { if ((i=lgetw())==0) break; if (strlen(i)>=PSNAMESIZE) i[PSNAMESIZE-1]=0; strcpy(psname,i); } else if (strcmp(i,"play-day-play") == 0) dayplay=1; break; case 's': if (strcmp(i,"savefile:") == 0) /* defining savefilename */ { if ((i=lgetw())==0) break; if (strlen(i)>=SAVEFILENAMESIZE) /* avoid overflow */ i[SAVEFILENAMESIZE-1]=0; strcpy(savefilename,i); flag=0; } break; }; } if (flag) strcpy(logname,loginname); } SHAR_EOF if test 5637 -ne "`wc -c < 'tok.c'`" then echo shar: error transmitting "'tok.c'" '(should have been 5637 characters)' fi fi echo shar: extracting "'MANIFEST'" '(1097 characters)' if test -f 'MANIFEST' then echo shar: will not over-write existing file "'MANIFEST'" else cat << \SHAR_EOF > 'MANIFEST' File Name Kit Number -------------- ---------- .holidays 6 .larn.help.uue 6 .larnmaze 6 .larnopts 3 .lfortune 4 Fixed.Bugs 1 MANIFEST 5 Make.lint 1 Makefile 1 README 1 bill.c 1 config.c 1 create.c 1 data.c 2 diag.c 1 display.c 2 fortune.c 1 global.c 2 header.h 3 help.c 1 io.c 3 main.c 3 monster.c 4 moreobj.c 4 movem.c 4 nap.c 2 object.c 5 regen.c 5 savelev.c 1 scores.c 5 signal.c 5 store.c 6 tok.c 5 SHAR_EOF if test 1097 -ne "`wc -c < 'MANIFEST'`" then echo shar: error transmitting "'MANIFEST'" '(should have been 1097 characters)' fi fi exit 0 # End of shell archive