]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/global.c
2 static char rcsid
[] = "$NetBSD: global.c,v 1.4 1995/04/24 12:23:52 cgd 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
27 extern int score
[],srcount
,dropflag
;
28 extern int random
;/* the random number seed */
29 extern short playerx
,playery
,lastnum
;
30 extern char cheat
,level
,monstnamelist
[];
31 extern char lastmonst
[],*what
[],*who
[];
33 extern char logname
[],monstlevel
[];
34 extern char sciv
[SCORESIZE
+1][26][2],*potionname
[],*scrollname
[];
41 subroutine to raise the player one level
42 uses the skill[] array to find level boundarys
43 uses c[EXPERIENCE] c[LEVEL]
47 if (c
[LEVEL
] < MAXPLEVEL
) raiseexperience((long)(skill
[c
[LEVEL
]]-c
[EXPERIENCE
]));
56 subroutine to lower the players character level by one
60 if (c
[LEVEL
] > 1) loseexperience((long)(c
[EXPERIENCE
] - skill
[c
[LEVEL
]-1] + 1));
69 subroutine to increase experience points
75 i
=c
[LEVEL
]; c
[EXPERIENCE
]+=x
;
76 while (c
[EXPERIENCE
] >= skill
[c
[LEVEL
]] && (c
[LEVEL
] < MAXPLEVEL
))
78 tmp
= (c
[CONSTITUTION
]-c
[HARDGAME
])>>1;
79 c
[LEVEL
]++; raisemhp((int)(rnd(3)+rnd((tmp
>0)?tmp
:1)));
80 raisemspells((int)rund(3));
81 if (c
[LEVEL
] < 7-c
[HARDGAME
]) raisemhp((int)(c
[CONSTITUTION
]>>2));
86 beep(); lprintf("\nWelcome to level %d",(long)c
[LEVEL
]); /* if we changed levels */
97 subroutine to lose experience points
103 i
=c
[LEVEL
]; c
[EXPERIENCE
]-=x
;
104 if (c
[EXPERIENCE
] < 0) c
[EXPERIENCE
]=0;
105 while (c
[EXPERIENCE
] < skill
[c
[LEVEL
]-1])
107 if (--c
[LEVEL
] <= 1) c
[LEVEL
]=1; /* down one level */
108 tmp
= (c
[CONSTITUTION
]-c
[HARDGAME
])>>1; /* lose hpoints */
109 losemhp((int)rnd((tmp
>0)?tmp
:1)); /* lose hpoints */
110 if (c
[LEVEL
] < 7-c
[HARDGAME
]) losemhp((int)(c
[CONSTITUTION
]>>2));
111 losemspells((int)rund(3)); /* lose spells */
116 beep(); lprintf("\nYou went down to level %d!",(long)c
[LEVEL
]);
128 subroutine to remove hit points from the player
129 warning -- will kill player if hp goes to zero
134 if ((c
[HP
] -= x
) <= 0)
136 beep(); lprcat("\n"); nap(3000); died(lastnum
);
143 c
[HP
] -= x
; if (c
[HP
] < 1) c
[HP
]=1;
144 c
[HPMAX
] -= x
; if (c
[HPMAX
] < 1) c
[HPMAX
]=1;
154 subroutine to gain maximum hit points
159 if ((c
[HP
] += x
) > c
[HPMAX
]) c
[HP
] = c
[HPMAX
];
165 c
[HPMAX
] += x
; c
[HP
] += x
;
175 subroutine to gain maximum spells
180 if ((c
[SPELLS
] += x
) > c
[SPELLMAX
]) c
[SPELLS
] = c
[SPELLMAX
];
186 c
[SPELLMAX
]+=x
; c
[SPELLS
]+=x
;
196 subroutine to lose maximum spells
201 if ((c
[SPELLS
] -= x
) < 0) c
[SPELLS
]=0;
207 if ((c
[SPELLMAX
] -= x
) < 0) c
[SPELLMAX
]=0;
208 if ((c
[SPELLS
] -= x
) < 0) c
[SPELLS
]=0;
215 function to return monster number for a randomly selected monster
216 for the given cave level
222 if (lev
< 1) lev
= 1; if (lev
> 12) lev
= 12;
225 while (tmp
==WATERLORD
) tmp
=rnd((x
=monstlevel
[lev
-1])?x
:1);
226 else while (tmp
==WATERLORD
)
227 tmp
=rnd((x
=monstlevel
[lev
-1]-monstlevel
[lev
-4])?x
:1)+monstlevel
[lev
-4];
229 while (monster
[tmp
].genocided
&& tmp
<MAXMONST
) tmp
++; /* genocided? */
236 function to be sure player is not in a wall
242 while ((item
[playerx
][playery
] || mitem
[playerx
][playery
]) && (try))
243 if (++playerx
>= MAXX
-1)
246 if (++playery
>= MAXY
-1)
247 { playery
= 1; --try; }
249 if (try==0) lprcat("Failure in positionplayer\n");
253 recalc() function to recalculate the armor class of the player
258 c
[AC
] = c
[MOREDEFENSES
];
260 switch(iven
[c
[WEAR
]])
262 case OSHIELD
: c
[AC
] += 2 + ivenarg
[c
[WEAR
]]; break;
263 case OLEATHER
: c
[AC
] += 2 + ivenarg
[c
[WEAR
]]; break;
264 case OSTUDLEATHER
: c
[AC
] += 3 + ivenarg
[c
[WEAR
]]; break;
265 case ORING
: c
[AC
] += 5 + ivenarg
[c
[WEAR
]]; break;
266 case OCHAIN
: c
[AC
] += 6 + ivenarg
[c
[WEAR
]]; break;
267 case OSPLINT
: c
[AC
] += 7 + ivenarg
[c
[WEAR
]]; break;
268 case OPLATE
: c
[AC
] += 9 + ivenarg
[c
[WEAR
]]; break;
269 case OPLATEARMOR
: c
[AC
] += 10 + ivenarg
[c
[WEAR
]]; break;
270 case OSSPLATE
: c
[AC
] += 12 + ivenarg
[c
[WEAR
]]; break;
273 if (c
[SHIELD
] >= 0) if (iven
[c
[SHIELD
]] == OSHIELD
) c
[AC
] += 2 + ivenarg
[c
[SHIELD
]];
274 if (c
[WIELD
] < 0) c
[WCLASS
] = 0; else
276 i
= ivenarg
[c
[WIELD
]];
277 switch(iven
[c
[WIELD
]])
279 case ODAGGER
: c
[WCLASS
] = 3 + i
; break;
280 case OBELT
: c
[WCLASS
] = 7 + i
; break;
281 case OSHIELD
: c
[WCLASS
] = 8 + i
; break;
282 case OSPEAR
: c
[WCLASS
] = 10 + i
; break;
283 case OFLAIL
: c
[WCLASS
] = 14 + i
; break;
284 case OBATTLEAXE
: c
[WCLASS
] = 17 + i
; break;
285 case OLANCE
: c
[WCLASS
] = 19 + i
; break;
286 case OLONGSWORD
: c
[WCLASS
] = 22 + i
; break;
287 case O2SWORD
: c
[WCLASS
] = 26 + i
; break;
288 case OSWORD
: c
[WCLASS
] = 32 + i
; break;
289 case OSWORDofSLASHING
: c
[WCLASS
] = 30 + i
; break;
290 case OHAMMER
: c
[WCLASS
] = 35 + i
; break;
291 default: c
[WCLASS
] = 0;
294 c
[WCLASS
] += c
[MOREDAM
];
296 /* now for regeneration abilities based on rings */
297 c
[REGEN
]=1; c
[ENERGY
]=0;
298 j
=0; for (k
=25; k
>0; k
--) if (iven
[k
]) {j
=k
; k
=0; }
303 case OPROTRING
: c
[AC
] += ivenarg
[i
] + 1; break;
304 case ODAMRING
: c
[WCLASS
] += ivenarg
[i
] + 1; break;
305 case OBELT
: c
[WCLASS
] += ((ivenarg
[i
]<<1)) + 2; break;
307 case OREGENRING
: c
[REGEN
] += ivenarg
[i
] + 1; break;
308 case ORINGOFEXTRA
: c
[REGEN
] += 5 * (ivenarg
[i
]+1); break;
309 case OENERGYRING
: c
[ENERGY
] += ivenarg
[i
] + 1; break;
318 subroutine to ask if the player really wants to quit
323 cursors(); strcpy(lastmonst
,"");
324 lprcat("\n\nDo you really want to quit?");
328 if (i
== 'y') { died(300); return; }
329 if ((i
== 'n') || (i
== '\33')) { lprcat(" no"); lflush(); return; }
330 lprcat("\n"); setbold(); lprcat("Yes"); resetbold(); lprcat(" or ");
331 setbold(); lprcat("No"); resetbold(); lprcat(" please? Do you want to quit? ");
336 function to ask --more-- then the user must enter a space
340 lprcat("\n --- press "); standout("space"); lprcat(" to continue --- ");
341 while (getchar() != ' ');
345 function to put something in the players inventory
346 returns 0 if success, 1 if a failure
351 register int i
,limit
;
353 if ((limit
= 15+(c
[LEVEL
]>>1)) > 26) limit
=26;
354 for (i
=0; i
<limit
; i
++)
357 iven
[i
] = itm
; ivenarg
[i
] = arg
; limit
=0;
360 case OPROTRING
: case ODAMRING
: case OBELT
: limit
=1; break;
361 case ODEXRING
: c
[DEXTERITY
] += ivenarg
[i
]+1; limit
=1; break;
362 case OSTRRING
: c
[STREXTRA
] += ivenarg
[i
]+1; limit
=1; break;
363 case OCLEVERRING
: c
[INTELLIGENCE
] += ivenarg
[i
]+1; limit
=1; break;
364 case OHAMMER
: c
[DEXTERITY
] += 10; c
[STREXTRA
]+=10;
365 c
[INTELLIGENCE
]-=10; limit
=1; break;
367 case OORBOFDRAGON
: c
[SLAYING
]++; break;
368 case OSPIRITSCARAB
: c
[NEGATESPIRIT
]++; break;
369 case OCUBEofUNDEAD
: c
[CUBEofUNDEAD
]++; break;
370 case ONOTHEFT
: c
[NOTHEFT
]++; break;
371 case OSWORDofSLASHING
: c
[DEXTERITY
] +=5; limit
=1; break;
373 lprcat("\nYou pick up:"); srcount
=0; show3(i
);
374 if (limit
) bottomline(); return(0);
376 lprcat("\nYou can't carry anything else"); return(1);
380 subroutine to drop an object returns 1 if something there already else 0
386 if ((k
<0) || (k
>25)) return(0);
387 itm
= iven
[k
]; cursors();
388 if (itm
==0) { lprintf("\nYou don't have item %c! ",k
+'a'); return(1); }
389 if (item
[playerx
][playery
])
390 { beep(); lprcat("\nThere's something here already"); return(1); }
391 if (playery
==MAXY
-1 && playerx
==33) return(1); /* not in entrance */
392 item
[playerx
][playery
] = itm
;
393 iarg
[playerx
][playery
] = ivenarg
[k
];
394 srcount
=0; lprcat("\n You drop:"); show3(k
); /* show what item you dropped*/
395 know
[playerx
][playery
] = 0; iven
[k
]=0;
396 if (c
[WIELD
]==k
) c
[WIELD
]= -1; if (c
[WEAR
]==k
) c
[WEAR
] = -1;
397 if (c
[SHIELD
]==k
) c
[SHIELD
]= -1;
398 adjustcvalues(itm
,ivenarg
[k
]);
399 dropflag
=1; /* say dropped an item so wont ask to pick it up right away */
404 function to enchant armor player is currently wearing
409 if (c
[WEAR
]<0) { if (c
[SHIELD
] < 0)
410 { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
411 else { tmp
=iven
[c
[SHIELD
]]; if (tmp
!= OSCROLL
) if (tmp
!= OPOTION
) { ivenarg
[c
[SHIELD
]]++; bottomline(); } } }
413 if (tmp
!=OSCROLL
) if (tmp
!=OPOTION
) { ivenarg
[c
[WEAR
]]++; bottomline(); }
417 function to enchant a weapon presently being wielded
423 { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
424 tmp
= iven
[c
[WIELD
]];
425 if (tmp
!=OSCROLL
) if (tmp
!=OPOTION
)
426 { ivenarg
[c
[WIELD
]]++;
427 if (tmp
==OCLEVERRING
) c
[INTELLIGENCE
]++; else
428 if (tmp
==OSTRRING
) c
[STREXTRA
]++; else
429 if (tmp
==ODEXRING
) c
[DEXTERITY
]++; bottomline(); }
433 routine to tell if player can carry one more thing
434 returns 1 if pockets are full, else 0
438 register int i
,limit
;
439 if ((limit
= 15+(c
[LEVEL
]>>1)) > 26) limit
=26;
440 for (i
=0; i
<limit
; i
++) if (iven
[i
]==0) return(0);
445 function to return 1 if a monster is next to the player else returns 0
449 register int tmp
,tmp2
;
450 for (tmp
=playerx
-1; tmp
<playerx
+2; tmp
++)
451 for (tmp2
=playery
-1; tmp2
<playery
+2; tmp2
++)
452 if (mitem
[tmp
][tmp2
]) return(1); /* if monster nearby */
457 function to steal an item from the players pockets
458 returns 1 if steals something else returns 0
467 if (iven
[i
]) if (c
[WEAR
]!=i
) if (c
[WIELD
]!=i
) if (c
[SHIELD
]!=i
)
470 adjustcvalues(iven
[i
],ivenarg
[i
]); iven
[i
]=0; return(1);
472 if (--j
<= 0) return(0);
477 function to return 1 is player carrys nothing else return 0
483 if (iven
[i
]) if (i
!=c
[WIELD
]) if (i
!=c
[WEAR
]) if (i
!=c
[SHIELD
]) return(0);
488 function to create a gem on a square near the player
495 case 1: i
=ODIAMOND
; j
=50; break;
496 case 2: i
=ORUBY
; j
=40; break;
497 case 3: i
=OEMERALD
; j
=30; break;
498 default: i
=OSAPPHIRE
; j
=20; break;
500 createitem(i
,rnd(j
)+j
/10);
504 function to change character levels as needed when dropping an object
505 that affects these characteristics
507 adjustcvalues(itm
,arg
)
514 case ODEXRING
: c
[DEXTERITY
] -= arg
+1; flag
=1; break;
515 case OSTRRING
: c
[STREXTRA
] -= arg
+1; flag
=1; break;
516 case OCLEVERRING
: c
[INTELLIGENCE
] -= arg
+1; flag
=1; break;
517 case OHAMMER
: c
[DEXTERITY
] -= 10; c
[STREXTRA
] -= 10;
518 c
[INTELLIGENCE
] += 10; flag
=1; break;
519 case OSWORDofSLASHING
: c
[DEXTERITY
] -= 5; flag
=1; break;
520 case OORBOFDRAGON
: --c
[SLAYING
]; return;
521 case OSPIRITSCARAB
: --c
[NEGATESPIRIT
]; return;
522 case OCUBEofUNDEAD
: --c
[CUBEofUNDEAD
]; return;
523 case ONOTHEFT
: --c
[NOTHEFT
]; return;
524 case OLANCE
: c
[LANCEDEATH
]=0; return;
525 case OPOTION
: case OSCROLL
: return;
529 if (flag
) bottomline();
533 function to read a string from token input "string"
534 returns a pointer to the string
541 while ((getchar() != '"') && (--i
> 0));
545 if ((j
=getchar()) != '"') *str
++ = j
; else i
=0;
549 if (j
!= '"') while ((getchar() != '"') && (--i
> 0)); /* if end due to too long, then find closing quote */
553 function to ask user for a password (no echo)
554 returns 1 if entered correctly, 0 if not
556 static char gpwbuf
[33];
561 extern char *password
;
562 scbr(); /* system("stty -echo cbreak"); */
563 gpwp
= gpwbuf
; lprcat("\nEnter Password: "); lflush();
564 i
= strlen(password
);
565 for (j
=0; j
<i
; j
++) read(0,gpwp
++,1); gpwbuf
[i
]=0;
566 sncbr(); /* system("stty echo -cbreak"); */
567 if (strcmp(gpwbuf
,password
) != 0)
568 { lprcat("\nSorry\n"); lflush(); return(0); }
573 subroutine to get a yes or no response from the user
579 i
=0; while (i
!='y' && i
!='n' && i
!='\33') i
=getchar();
584 function to calculate the pack weight of the player
585 returns the number of pounds the player is carrying
590 k
=c
[GOLD
]/1000; j
=25; while ((iven
[j
]==0) && (j
>0)) --j
;
595 case OSSPLATE
: case OPLATEARMOR
: k
+= 40; break;
596 case OPLATE
: k
+= 35; break;
597 case OHAMMER
: k
+= 30; break;
598 case OSPLINT
: k
+= 26; break;
599 case OSWORDofSLASHING
: case OCHAIN
:
600 case OBATTLEAXE
: case O2SWORD
: k
+= 23; break;
601 case OLONGSWORD
: case OSWORD
:
602 case ORING
: case OFLAIL
: k
+= 20; break;
603 case OLANCE
: case OSTUDLEATHER
: k
+= 15; break;
604 case OLEATHER
: case OSPEAR
: k
+= 8; break;
605 case OORBOFDRAGON
: case OBELT
: k
+= 4; break;
606 case OSHIELD
: k
+= 7; break;
607 case OCHEST
: k
+= 30 + ivenarg
[i
]; break;
614 /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */
618 return((((randx
=randx
*1103515245+12345)>>7)%(x
))+1);
624 return((((randx
=randx
*1103515245+12345)>>7)%(x
)) );