#ifndef lint static char rcsid[] = "$NetBSD: global.c,v 1.4 1995/04/24 12:23:52 cgd Exp $"; #endif /* not lint */ /* global.c Larn is copyrighted 1986 by Noah Morgan. * * raiselevel() subroutine to raise the player one level * loselevel() subroutine to lower the player by one level * raiseexperience(x) subroutine to increase experience points * loseexperience(x) subroutine to lose experience points * losehp(x) subroutine to remove hit points from the player * losemhp(x) subroutine to remove max # hit points from the player * raisehp(x) subroutine to gain hit points * raisemhp(x) subroutine to gain maximum hit points * losespells(x) subroutine to lose spells * losemspells(x) subroutine to lose maximum spells * raisespells(x) subroutine to gain spells * raisemspells(x) subroutine to gain maximum spells * recalc() function to recalculate the armor class of the player * makemonst(lev) function to return monster number for a randomly selected monster * positionplayer() function to be sure player is not in a wall * quit() subroutine to ask if the player really wants to quit */ #include "header.h" #include extern int score[],srcount,dropflag; extern int random;/* the random number seed */ extern short playerx,playery,lastnum,level; extern char cheat,monstnamelist[]; extern char lastmonst[],*what[],*who[]; extern char winner[]; extern char logname[],monstlevel[]; extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[]; /* *********** RAISE LEVEL *********** raiselevel() subroutine to raise the player one level uses the skill[] array to find level boundarys uses c[EXPERIENCE] c[LEVEL] */ raiselevel() { if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE])); } /* *********** LOOSE LEVEL *********** loselevel() subroutine to lower the players character level by one */ loselevel() { if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1)); } /* **************** RAISE EXPERIENCE **************** raiseexperience(x) subroutine to increase experience points */ raiseexperience(x) register long x; { register int i,tmp; i=c[LEVEL]; c[EXPERIENCE]+=x; while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL)) { tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1))); raisemspells((int)rund(3)); if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2)); } if (c[LEVEL] != i) { cursors(); beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]); /* if we changed levels */ } bottomline(); } /* **************** LOOSE EXPERIENCE **************** loseexperience(x) subroutine to lose experience points */ loseexperience(x) register long x; { register int i,tmp; i=c[LEVEL]; c[EXPERIENCE]-=x; if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0; while (c[EXPERIENCE] < skill[c[LEVEL]-1]) { if (--c[LEVEL] <= 1) c[LEVEL]=1; /* down one level */ tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */ losemhp((int)rnd((tmp>0)?tmp:1)); /* lose hpoints */ if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2)); losemspells((int)rund(3)); /* lose spells */ } if (i!=c[LEVEL]) { cursors(); beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]); } bottomline(); } /* ******** LOOSE HP ******** losehp(x) losemhp(x) subroutine to remove hit points from the player warning -- will kill player if hp goes to zero */ losehp(x) register int x; { if ((c[HP] -= x) <= 0) { beep(); lprcat("\n"); nap(3000); died(lastnum); } } losemhp(x) register int x; { c[HP] -= x; if (c[HP] < 1) c[HP]=1; c[HPMAX] -= x; if (c[HPMAX] < 1) c[HPMAX]=1; } /* ******** RAISE HP ******** raisehp(x) raisemhp(x) subroutine to gain maximum hit points */ raisehp(x) register int x; { if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX]; } raisemhp(x) register int x; { c[HPMAX] += x; c[HP] += x; } /* ************ RAISE SPELLS ************ raisespells(x) raisemspells(x) subroutine to gain maximum spells */ raisespells(x) register int x; { if ((c[SPELLS] += x) > c[SPELLMAX]) c[SPELLS] = c[SPELLMAX]; } raisemspells(x) register int x; { c[SPELLMAX]+=x; c[SPELLS]+=x; } /* ************ LOOSE SPELLS ************ losespells(x) losemspells(x) subroutine to lose maximum spells */ losespells(x) register int x; { if ((c[SPELLS] -= x) < 0) c[SPELLS]=0; } losemspells(x) register int x; { if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0; if ((c[SPELLS] -= x) < 0) c[SPELLS]=0; } /* makemonst(lev) int lev; function to return monster number for a randomly selected monster for the given cave level */ makemonst(lev) register int lev; { register int tmp,x; if (lev < 1) lev = 1; if (lev > 12) lev = 12; tmp=WATERLORD; if (lev < 5) while (tmp==WATERLORD) tmp=rnd((x=monstlevel[lev-1])?x:1); else while (tmp==WATERLORD) tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4]; while (monster[tmp].genocided && tmp= MAXX-1) { playerx = 1; if (++playery >= MAXY-1) { playery = 1; --try; } } if (try==0) lprcat("Failure in positionplayer\n"); } /* recalc() function to recalculate the armor class of the player */ recalc() { register int i,j,k; c[AC] = c[MOREDEFENSES]; if (c[WEAR] >= 0) switch(iven[c[WEAR]]) { case OSHIELD: c[AC] += 2 + ivenarg[c[WEAR]]; break; case OLEATHER: c[AC] += 2 + ivenarg[c[WEAR]]; break; case OSTUDLEATHER: c[AC] += 3 + ivenarg[c[WEAR]]; break; case ORING: c[AC] += 5 + ivenarg[c[WEAR]]; break; case OCHAIN: c[AC] += 6 + ivenarg[c[WEAR]]; break; case OSPLINT: c[AC] += 7 + ivenarg[c[WEAR]]; break; case OPLATE: c[AC] += 9 + ivenarg[c[WEAR]]; break; case OPLATEARMOR: c[AC] += 10 + ivenarg[c[WEAR]]; break; case OSSPLATE: c[AC] += 12 + ivenarg[c[WEAR]]; break; } if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]]; if (c[WIELD] < 0) c[WCLASS] = 0; else { i = ivenarg[c[WIELD]]; switch(iven[c[WIELD]]) { case ODAGGER: c[WCLASS] = 3 + i; break; case OBELT: c[WCLASS] = 7 + i; break; case OSHIELD: c[WCLASS] = 8 + i; break; case OSPEAR: c[WCLASS] = 10 + i; break; case OFLAIL: c[WCLASS] = 14 + i; break; case OBATTLEAXE: c[WCLASS] = 17 + i; break; case OLANCE: c[WCLASS] = 19 + i; break; case OLONGSWORD: c[WCLASS] = 22 + i; break; case O2SWORD: c[WCLASS] = 26 + i; break; case OSWORD: c[WCLASS] = 32 + i; break; case OSWORDofSLASHING: c[WCLASS] = 30 + i; break; case OHAMMER: c[WCLASS] = 35 + i; break; default: c[WCLASS] = 0; } } c[WCLASS] += c[MOREDAM]; /* now for regeneration abilities based on rings */ c[REGEN]=1; c[ENERGY]=0; j=0; for (k=25; k>0; k--) if (iven[k]) {j=k; k=0; } for (i=0; i<=j; i++) { switch(iven[i]) { case OPROTRING: c[AC] += ivenarg[i] + 1; break; case ODAMRING: c[WCLASS] += ivenarg[i] + 1; break; case OBELT: c[WCLASS] += ((ivenarg[i]<<1)) + 2; break; case OREGENRING: c[REGEN] += ivenarg[i] + 1; break; case ORINGOFEXTRA: c[REGEN] += 5 * (ivenarg[i]+1); break; case OENERGYRING: c[ENERGY] += ivenarg[i] + 1; break; } } } /* quit() subroutine to ask if the player really wants to quit */ quit() { register int i; cursors(); strcpy(lastmonst,""); lprcat("\n\nDo you really want to quit?"); while (1) { i=getchar(); if (i == 'y') { died(300); return; } if ((i == 'n') || (i == '\33')) { lprcat(" no"); lflush(); return; } lprcat("\n"); setbold(); lprcat("Yes"); resetbold(); lprcat(" or "); setbold(); lprcat("No"); resetbold(); lprcat(" please? Do you want to quit? "); } } /* function to ask --more-- then the user must enter a space */ more() { lprcat("\n --- press "); standout("space"); lprcat(" to continue --- "); while (getchar() != ' '); } /* function to put something in the players inventory returns 0 if success, 1 if a failure */ take(itm,arg) int itm,arg; { register int i,limit; /* cursors(); */ if ((limit = 15+(c[LEVEL]>>1)) > 26) limit=26; for (i=0; i25)) return(0); itm = iven[k]; cursors(); if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); } if (item[playerx][playery]) { beep(); lprcat("\nThere's something here already"); return(1); } if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */ item[playerx][playery] = itm; iarg[playerx][playery] = ivenarg[k]; srcount=0; lprcat("\n You drop:"); show3(k); /* show what item you dropped*/ know[playerx][playery] = 0; iven[k]=0; if (c[WIELD]==k) c[WIELD]= -1; if (c[WEAR]==k) c[WEAR] = -1; if (c[SHIELD]==k) c[SHIELD]= -1; adjustcvalues(itm,ivenarg[k]); dropflag=1; /* say dropped an item so wont ask to pick it up right away */ return(0); } /* function to enchant armor player is currently wearing */ enchantarmor() { register int tmp; if (c[WEAR]<0) { if (c[SHIELD] < 0) { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; } else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } } tmp = iven[c[WEAR]]; if (tmp!=OSCROLL) if (tmp!=OPOTION) { ivenarg[c[WEAR]]++; bottomline(); } } /* function to enchant a weapon presently being wielded */ enchweapon() { register int tmp; if (c[WIELD]<0) { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; } tmp = iven[c[WIELD]]; if (tmp!=OSCROLL) if (tmp!=OPOTION) { ivenarg[c[WIELD]]++; if (tmp==OCLEVERRING) c[INTELLIGENCE]++; else if (tmp==OSTRRING) c[STREXTRA]++; else if (tmp==ODEXRING) c[DEXTERITY]++; bottomline(); } } /* routine to tell if player can carry one more thing returns 1 if pockets are full, else 0 */ pocketfull() { register int i,limit; if ((limit = 15+(c[LEVEL]>>1)) > 26) limit=26; for (i=0; i 0)); i=36; while (--i > 0) { if ((j=getchar()) != '"') *str++ = j; else i=0; } *str = 0; i=50; if (j != '"') while ((getchar() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */ } /* function to ask user for a password (no echo) returns 1 if entered correctly, 0 if not */ static char gpwbuf[33]; getpassword() { register int i,j; register char *gpwp; extern char *password; scbr(); /* system("stty -echo cbreak"); */ gpwp = gpwbuf; lprcat("\nEnter Password: "); lflush(); i = strlen(password); for (j=0; j0)) --j; for (i=0; i<=j; i++) switch(iven[i]) { case 0: break; case OSSPLATE: case OPLATEARMOR: k += 40; break; case OPLATE: k += 35; break; case OHAMMER: k += 30; break; case OSPLINT: k += 26; break; case OSWORDofSLASHING: case OCHAIN: case OBATTLEAXE: case O2SWORD: k += 23; break; case OLONGSWORD: case OSWORD: case ORING: case OFLAIL: k += 20; break; case OLANCE: case OSTUDLEATHER: k += 15; break; case OLEATHER: case OSPEAR: k += 8; break; case OORBOFDRAGON: case OBELT: k += 4; break; case OSHIELD: k += 7; break; case OCHEST: k += 30 + ivenarg[i]; break; default: k++; }; return(k); } #ifndef MACRORND /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */ rnd(x) int x; { return((((randx=randx*1103515245+12345)>>7)%(x))+1); } rund(x) int x; { return((((randx=randx*1103515245+12345)>>7)%(x)) ); } #endif MACRORND