]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/global.c
2 static char rcsid
[] = "$Id: global.c,v 1.2 1993/08/02 17:20:02 mycroft Exp $";
5 /* global.c Larn is copyrighted 1986 by Noah Morgan.
7 * raiselevel() subroutine to raise the player one level
8 * loselevel() subroutine to lower the player by one level
9 * raiseexperience(x) subroutine to increase experience points
10 * loseexperience(x) subroutine to lose experience points
11 * losehp(x) subroutine to remove hit points from the player
12 * losemhp(x) subroutine to remove max # hit points from the player
13 * raisehp(x) subroutine to gain hit points
14 * raisemhp(x) subroutine to gain maximum hit points
15 * losespells(x) subroutine to lose spells
16 * losemspells(x) subroutine to lose maximum spells
17 * raisespells(x) subroutine to gain spells
18 * raisemspells(x) subroutine to gain maximum spells
19 * recalc() function to recalculate the armor class of the player
20 * makemonst(lev) function to return monster number for a randomly selected monster
21 * positionplayer() function to be sure player is not in a wall
22 * quit() subroutine to ask if the player really wants to quit
26 extern int score
[],srcount
,dropflag
;
27 extern int random
;/* the random number seed */
28 extern short playerx
,playery
,lastnum
;
29 extern char cheat
,level
,monstnamelist
[];
30 extern char lastmonst
[],*what
[],*who
[];
32 extern char logname
[],monstlevel
[];
33 extern char sciv
[SCORESIZE
+1][26][2],*potionname
[],*scrollname
[];
40 subroutine to raise the player one level
41 uses the skill[] array to find level boundarys
42 uses c[EXPERIENCE] c[LEVEL]
46 if (c
[LEVEL
] < MAXPLEVEL
) raiseexperience((long)(skill
[c
[LEVEL
]]-c
[EXPERIENCE
]));
55 subroutine to lower the players character level by one
59 if (c
[LEVEL
] > 1) loseexperience((long)(c
[EXPERIENCE
] - skill
[c
[LEVEL
]-1] + 1));
68 subroutine to increase experience points
74 i
=c
[LEVEL
]; c
[EXPERIENCE
]+=x
;
75 while (c
[EXPERIENCE
] >= skill
[c
[LEVEL
]] && (c
[LEVEL
] < MAXPLEVEL
))
77 tmp
= (c
[CONSTITUTION
]-c
[HARDGAME
])>>1;
78 c
[LEVEL
]++; raisemhp((int)(rnd(3)+rnd((tmp
>0)?tmp
:1)));
79 raisemspells((int)rund(3));
80 if (c
[LEVEL
] < 7-c
[HARDGAME
]) raisemhp((int)(c
[CONSTITUTION
]>>2));
85 beep(); lprintf("\nWelcome to level %d",(long)c
[LEVEL
]); /* if we changed levels */
96 subroutine to lose experience points
102 i
=c
[LEVEL
]; c
[EXPERIENCE
]-=x
;
103 if (c
[EXPERIENCE
] < 0) c
[EXPERIENCE
]=0;
104 while (c
[EXPERIENCE
] < skill
[c
[LEVEL
]-1])
106 if (--c
[LEVEL
] <= 1) c
[LEVEL
]=1; /* down one level */
107 tmp
= (c
[CONSTITUTION
]-c
[HARDGAME
])>>1; /* lose hpoints */
108 losemhp((int)rnd((tmp
>0)?tmp
:1)); /* lose hpoints */
109 if (c
[LEVEL
] < 7-c
[HARDGAME
]) losemhp((int)(c
[CONSTITUTION
]>>2));
110 losemspells((int)rund(3)); /* lose spells */
115 beep(); lprintf("\nYou went down to level %d!",(long)c
[LEVEL
]);
127 subroutine to remove hit points from the player
128 warning -- will kill player if hp goes to zero
133 if ((c
[HP
] -= x
) <= 0)
135 beep(); lprcat("\n"); nap(3000); died(lastnum
);
142 c
[HP
] -= x
; if (c
[HP
] < 1) c
[HP
]=1;
143 c
[HPMAX
] -= x
; if (c
[HPMAX
] < 1) c
[HPMAX
]=1;
153 subroutine to gain maximum hit points
158 if ((c
[HP
] += x
) > c
[HPMAX
]) c
[HP
] = c
[HPMAX
];
164 c
[HPMAX
] += x
; c
[HP
] += x
;
174 subroutine to gain maximum spells
179 if ((c
[SPELLS
] += x
) > c
[SPELLMAX
]) c
[SPELLS
] = c
[SPELLMAX
];
185 c
[SPELLMAX
]+=x
; c
[SPELLS
]+=x
;
195 subroutine to lose maximum spells
200 if ((c
[SPELLS
] -= x
) < 0) c
[SPELLS
]=0;
206 if ((c
[SPELLMAX
] -= x
) < 0) c
[SPELLMAX
]=0;
207 if ((c
[SPELLS
] -= x
) < 0) c
[SPELLS
]=0;
214 function to return monster number for a randomly selected monster
215 for the given cave level
221 if (lev
< 1) lev
= 1; if (lev
> 12) lev
= 12;
224 while (tmp
==WATERLORD
) tmp
=rnd((x
=monstlevel
[lev
-1])?x
:1);
225 else while (tmp
==WATERLORD
)
226 tmp
=rnd((x
=monstlevel
[lev
-1]-monstlevel
[lev
-4])?x
:1)+monstlevel
[lev
-4];
228 while (monster
[tmp
].genocided
&& tmp
<MAXMONST
) tmp
++; /* genocided? */
235 function to be sure player is not in a wall
241 while ((item
[playerx
][playery
] || mitem
[playerx
][playery
]) && (try))
242 if (++playerx
>= MAXX
-1)
245 if (++playery
>= MAXY
-1)
246 { playery
= 1; --try; }
248 if (try==0) lprcat("Failure in positionplayer\n");
252 recalc() function to recalculate the armor class of the player
257 c
[AC
] = c
[MOREDEFENSES
];
259 switch(iven
[c
[WEAR
]])
261 case OSHIELD
: c
[AC
] += 2 + ivenarg
[c
[WEAR
]]; break;
262 case OLEATHER
: c
[AC
] += 2 + ivenarg
[c
[WEAR
]]; break;
263 case OSTUDLEATHER
: c
[AC
] += 3 + ivenarg
[c
[WEAR
]]; break;
264 case ORING
: c
[AC
] += 5 + ivenarg
[c
[WEAR
]]; break;
265 case OCHAIN
: c
[AC
] += 6 + ivenarg
[c
[WEAR
]]; break;
266 case OSPLINT
: c
[AC
] += 7 + ivenarg
[c
[WEAR
]]; break;
267 case OPLATE
: c
[AC
] += 9 + ivenarg
[c
[WEAR
]]; break;
268 case OPLATEARMOR
: c
[AC
] += 10 + ivenarg
[c
[WEAR
]]; break;
269 case OSSPLATE
: c
[AC
] += 12 + ivenarg
[c
[WEAR
]]; break;
272 if (c
[SHIELD
] >= 0) if (iven
[c
[SHIELD
]] == OSHIELD
) c
[AC
] += 2 + ivenarg
[c
[SHIELD
]];
273 if (c
[WIELD
] < 0) c
[WCLASS
] = 0; else
275 i
= ivenarg
[c
[WIELD
]];
276 switch(iven
[c
[WIELD
]])
278 case ODAGGER
: c
[WCLASS
] = 3 + i
; break;
279 case OBELT
: c
[WCLASS
] = 7 + i
; break;
280 case OSHIELD
: c
[WCLASS
] = 8 + i
; break;
281 case OSPEAR
: c
[WCLASS
] = 10 + i
; break;
282 case OFLAIL
: c
[WCLASS
] = 14 + i
; break;
283 case OBATTLEAXE
: c
[WCLASS
] = 17 + i
; break;
284 case OLANCE
: c
[WCLASS
] = 19 + i
; break;
285 case OLONGSWORD
: c
[WCLASS
] = 22 + i
; break;
286 case O2SWORD
: c
[WCLASS
] = 26 + i
; break;
287 case OSWORD
: c
[WCLASS
] = 32 + i
; break;
288 case OSWORDofSLASHING
: c
[WCLASS
] = 30 + i
; break;
289 case OHAMMER
: c
[WCLASS
] = 35 + i
; break;
290 default: c
[WCLASS
] = 0;
293 c
[WCLASS
] += c
[MOREDAM
];
295 /* now for regeneration abilities based on rings */
296 c
[REGEN
]=1; c
[ENERGY
]=0;
297 j
=0; for (k
=25; k
>0; k
--) if (iven
[k
]) {j
=k
; k
=0; }
302 case OPROTRING
: c
[AC
] += ivenarg
[i
] + 1; break;
303 case ODAMRING
: c
[WCLASS
] += ivenarg
[i
] + 1; break;
304 case OBELT
: c
[WCLASS
] += ((ivenarg
[i
]<<1)) + 2; break;
306 case OREGENRING
: c
[REGEN
] += ivenarg
[i
] + 1; break;
307 case ORINGOFEXTRA
: c
[REGEN
] += 5 * (ivenarg
[i
]+1); break;
308 case OENERGYRING
: c
[ENERGY
] += ivenarg
[i
] + 1; break;
317 subroutine to ask if the player really wants to quit
322 cursors(); strcpy(lastmonst
,"");
323 lprcat("\n\nDo you really want to quit?");
327 if (i
== 'y') { died(300); return; }
328 if ((i
== 'n') || (i
== '\33')) { lprcat(" no"); lflush(); return; }
329 lprcat("\n"); setbold(); lprcat("Yes"); resetbold(); lprcat(" or ");
330 setbold(); lprcat("No"); resetbold(); lprcat(" please? Do you want to quit? ");
335 function to ask --more-- then the user must enter a space
339 lprcat("\n --- press "); standout("space"); lprcat(" to continue --- ");
340 while (getchar() != ' ');
344 function to put something in the players inventory
345 returns 0 if success, 1 if a failure
350 register int i
,limit
;
352 if ((limit
= 15+(c
[LEVEL
]>>1)) > 26) limit
=26;
353 for (i
=0; i
<limit
; i
++)
356 iven
[i
] = itm
; ivenarg
[i
] = arg
; limit
=0;
359 case OPROTRING
: case ODAMRING
: case OBELT
: limit
=1; break;
360 case ODEXRING
: c
[DEXTERITY
] += ivenarg
[i
]+1; limit
=1; break;
361 case OSTRRING
: c
[STREXTRA
] += ivenarg
[i
]+1; limit
=1; break;
362 case OCLEVERRING
: c
[INTELLIGENCE
] += ivenarg
[i
]+1; limit
=1; break;
363 case OHAMMER
: c
[DEXTERITY
] += 10; c
[STREXTRA
]+=10;
364 c
[INTELLIGENCE
]-=10; limit
=1; break;
366 case OORBOFDRAGON
: c
[SLAYING
]++; break;
367 case OSPIRITSCARAB
: c
[NEGATESPIRIT
]++; break;
368 case OCUBEofUNDEAD
: c
[CUBEofUNDEAD
]++; break;
369 case ONOTHEFT
: c
[NOTHEFT
]++; break;
370 case OSWORDofSLASHING
: c
[DEXTERITY
] +=5; limit
=1; break;
372 lprcat("\nYou pick up:"); srcount
=0; show3(i
);
373 if (limit
) bottomline(); return(0);
375 lprcat("\nYou can't carry anything else"); return(1);
379 subroutine to drop an object returns 1 if something there already else 0
385 if ((k
<0) || (k
>25)) return(0);
386 itm
= iven
[k
]; cursors();
387 if (itm
==0) { lprintf("\nYou don't have item %c! ",k
+'a'); return(1); }
388 if (item
[playerx
][playery
])
389 { beep(); lprcat("\nThere's something here already"); return(1); }
390 if (playery
==MAXY
-1 && playerx
==33) return(1); /* not in entrance */
391 item
[playerx
][playery
] = itm
;
392 iarg
[playerx
][playery
] = ivenarg
[k
];
393 srcount
=0; lprcat("\n You drop:"); show3(k
); /* show what item you dropped*/
394 know
[playerx
][playery
] = 0; iven
[k
]=0;
395 if (c
[WIELD
]==k
) c
[WIELD
]= -1; if (c
[WEAR
]==k
) c
[WEAR
] = -1;
396 if (c
[SHIELD
]==k
) c
[SHIELD
]= -1;
397 adjustcvalues(itm
,ivenarg
[k
]);
398 dropflag
=1; /* say dropped an item so wont ask to pick it up right away */
403 function to enchant armor player is currently wearing
408 if (c
[WEAR
]<0) { if (c
[SHIELD
] < 0)
409 { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
410 else { tmp
=iven
[c
[SHIELD
]]; if (tmp
!= OSCROLL
) if (tmp
!= OPOTION
) { ivenarg
[c
[SHIELD
]]++; bottomline(); } } }
412 if (tmp
!=OSCROLL
) if (tmp
!=OPOTION
) { ivenarg
[c
[WEAR
]]++; bottomline(); }
416 function to enchant a weapon presently being wielded
422 { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
423 tmp
= iven
[c
[WIELD
]];
424 if (tmp
!=OSCROLL
) if (tmp
!=OPOTION
)
425 { ivenarg
[c
[WIELD
]]++;
426 if (tmp
==OCLEVERRING
) c
[INTELLIGENCE
]++; else
427 if (tmp
==OSTRRING
) c
[STREXTRA
]++; else
428 if (tmp
==ODEXRING
) c
[DEXTERITY
]++; bottomline(); }
432 routine to tell if player can carry one more thing
433 returns 1 if pockets are full, else 0
437 register int i
,limit
;
438 if ((limit
= 15+(c
[LEVEL
]>>1)) > 26) limit
=26;
439 for (i
=0; i
<limit
; i
++) if (iven
[i
]==0) return(0);
444 function to return 1 if a monster is next to the player else returns 0
448 register int tmp
,tmp2
;
449 for (tmp
=playerx
-1; tmp
<playerx
+2; tmp
++)
450 for (tmp2
=playery
-1; tmp2
<playery
+2; tmp2
++)
451 if (mitem
[tmp
][tmp2
]) return(1); /* if monster nearby */
456 function to steal an item from the players pockets
457 returns 1 if steals something else returns 0
466 if (iven
[i
]) if (c
[WEAR
]!=i
) if (c
[WIELD
]!=i
) if (c
[SHIELD
]!=i
)
469 adjustcvalues(iven
[i
],ivenarg
[i
]); iven
[i
]=0; return(1);
471 if (--j
<= 0) return(0);
476 function to return 1 is player carrys nothing else return 0
482 if (iven
[i
]) if (i
!=c
[WIELD
]) if (i
!=c
[WEAR
]) if (i
!=c
[SHIELD
]) return(0);
487 function to create a gem on a square near the player
494 case 1: i
=ODIAMOND
; j
=50; break;
495 case 2: i
=ORUBY
; j
=40; break;
496 case 3: i
=OEMERALD
; j
=30; break;
497 default: i
=OSAPPHIRE
; j
=20; break;
499 createitem(i
,rnd(j
)+j
/10);
503 function to change character levels as needed when dropping an object
504 that affects these characteristics
506 adjustcvalues(itm
,arg
)
513 case ODEXRING
: c
[DEXTERITY
] -= arg
+1; flag
=1; break;
514 case OSTRRING
: c
[STREXTRA
] -= arg
+1; flag
=1; break;
515 case OCLEVERRING
: c
[INTELLIGENCE
] -= arg
+1; flag
=1; break;
516 case OHAMMER
: c
[DEXTERITY
] -= 10; c
[STREXTRA
] -= 10;
517 c
[INTELLIGENCE
] += 10; flag
=1; break;
518 case OSWORDofSLASHING
: c
[DEXTERITY
] -= 5; flag
=1; break;
519 case OORBOFDRAGON
: --c
[SLAYING
]; return;
520 case OSPIRITSCARAB
: --c
[NEGATESPIRIT
]; return;
521 case OCUBEofUNDEAD
: --c
[CUBEofUNDEAD
]; return;
522 case ONOTHEFT
: --c
[NOTHEFT
]; return;
523 case OLANCE
: c
[LANCEDEATH
]=0; return;
524 case OPOTION
: case OSCROLL
: return;
528 if (flag
) bottomline();
532 function to read a string from token input "string"
533 returns a pointer to the string
540 while ((getchar() != '"') && (--i
> 0));
544 if ((j
=getchar()) != '"') *str
++ = j
; else i
=0;
548 if (j
!= '"') while ((getchar() != '"') && (--i
> 0)); /* if end due to too long, then find closing quote */
552 function to ask user for a password (no echo)
553 returns 1 if entered correctly, 0 if not
555 static char gpwbuf
[33];
560 extern char *password
;
561 scbr(); /* system("stty -echo cbreak"); */
562 gpwp
= gpwbuf
; lprcat("\nEnter Password: "); lflush();
563 i
= strlen(password
);
564 for (j
=0; j
<i
; j
++) read(0,gpwp
++,1); gpwbuf
[i
]=0;
565 sncbr(); /* system("stty echo -cbreak"); */
566 if (strcmp(gpwbuf
,password
) != 0)
567 { lprcat("\nSorry\n"); lflush(); return(0); }
572 subroutine to get a yes or no response from the user
578 i
=0; while (i
!='y' && i
!='n' && i
!='\33') i
=getchar();
583 function to calculate the pack weight of the player
584 returns the number of pounds the player is carrying
589 k
=c
[GOLD
]/1000; j
=25; while ((iven
[j
]==0) && (j
>0)) --j
;
594 case OSSPLATE
: case OPLATEARMOR
: k
+= 40; break;
595 case OPLATE
: k
+= 35; break;
596 case OHAMMER
: k
+= 30; break;
597 case OSPLINT
: k
+= 26; break;
598 case OSWORDofSLASHING
: case OCHAIN
:
599 case OBATTLEAXE
: case O2SWORD
: k
+= 23; break;
600 case OLONGSWORD
: case OSWORD
:
601 case ORING
: case OFLAIL
: k
+= 20; break;
602 case OLANCE
: case OSTUDLEATHER
: k
+= 15; break;
603 case OLEATHER
: case OSPEAR
: k
+= 8; break;
604 case OORBOFDRAGON
: case OBELT
: k
+= 4; break;
605 case OSHIELD
: k
+= 7; break;
606 case OCHEST
: k
+= 30 + ivenarg
[i
]; break;
613 /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */
617 return((((randx
=randx
*1103515245+12345)>>7)%(x
))+1);
623 return((((randx
=randx
*1103515245+12345)>>7)%(x
)) );