-/* $NetBSD: monster.c,v 1.9 2006/03/19 00:32:18 christos Exp $ */
+/* $NetBSD: monster.c,v 1.20 2021/05/02 12:50:45 rillig Exp $ */
/*
* monster.c Larn is copyrighted 1986 by Noah Morgan.
*/
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: monster.c,v 1.9 2006/03/19 00:32:18 christos Exp $");
+__RCSID("$NetBSD: monster.c,v 1.20 2021/05/02 12:50:45 rillig Exp $");
#endif /* not lint */
#include <string.h>
#include <stdlib.h>
+#include <ctype.h>
#include "header.h"
#include "extern.h"
short arg; /* the type of item or hitpoints of monster */
};
+static int cgood(int, int, int, int);
+static void speldamage(int);
+static void loseint(void);
+static int isconfuse(void);
+static int nospell(int, int);
+static int fullhit(int);
+static void direct(int, int, const char *, int);
+static void ifblind(int, int);
+static void tdirect(int);
+static void omnidirect(int, int, const char *);
static int dirsub(int *, int *);
+static void dirpoly(int);
+static int hitm(int, int, int);
+static void dropsomething(int);
+static int spattack(int, int, int);
+static void sphboom(int, int);
+static void genmonst(void);
+
/*
* createmonster(monstno) Function to create a monster next to the player
* int monstno;
* Returns no value.
*/
void
-createmonster(mon)
- int mon;
+createmonster(int mon)
{
int x, y, k, i;
if (mon < 1 || mon > MAXMONST + 8) { /* check for monster number
* out of bounds */
beep();
- lprintf("\ncan't createmonst(%d)\n", (long) mon);
+ lprintf("\ncan't createmonst(%ld)\n", (long) mon);
nap(3000);
return;
}
* if monst==TRUE check for no monster at this location
* This routine will return FALSE if at a wall or the dungeon exit on level 1
*/
-int
-cgood(x, y, itm, monst)
- int x, y;
- int itm, monst;
+static int
+cgood(int x, int y, int theitem, int monst)
{
+#define itm __lose
if ((y >= 0) && (y <= MAXY - 1) && (x >= 0) && (x <= MAXX - 1))
/* within bounds? */
if (item[x][y] != OWALL) /* can't make anything on walls */
/* is it free of items? */
- if (itm == 0 || (item[x][y] == 0))
+ if (theitem == 0 || (item[x][y] == 0))
/* is it free of monsters? */
if (monst == 0 || (mitem[x][y] == 0))
if ((level != 1) || (x != 33) ||
* Returns no value, thus we don't know about createitem() failures.
*/
void
-createitem(it, arg)
- int it, arg;
+createitem(int it, int arg)
{
int x, y, k, i;
if (it >= MAXOBJ)
*/
static char eys[] = "\nEnter your spell: ";
void
-cast()
+cast(void)
{
int i, j, a, b, d;
cursors();
}
lprcat(eys);
--c[SPELLS];
- while ((a = lgetchar()) == 'D') {
+ while ((a = ttgetch()) == 'D') {
seemagic(-1);
cursors();
lprcat(eys);
}
if (a == '\33')
goto over; /* to escape casting a spell */
- if ((b = lgetchar()) == '\33')
+ if ((b = ttgetch()) == '\33')
goto over; /* to escape casting a spell */
- if ((d = lgetchar()) == '\33') {
+ if ((d = ttgetch()) == '\33') {
over: lprcat(aborted);
c[SPELLS]++;
return;
* Enter with the spell number, returns no value.
* Please insure that there are 2 spaces before all messages here
*/
-void
-speldamage(x)
- int x;
+static void
+speldamage(int x)
{
int i, j, clev;
int xl, xh, yl, yh;
- char *p, *kn, *pm;
+ u_char *p, *kn, *pm;
+
if (x >= SPNUM)
return; /* no such spell */
if (c[TIMESTOP]) {
c[DEXCOUNT] += 400;
return;
- case 3:
+ case 3: /* sleep */
i = rnd(3) + 1;
- p = " While the %s slept, you smashed it %d times";
-ws: direct(x, fullhit(i), p, i); /* sleep */
+ direct(x, fullhit(i),
+ " While the %s slept, you smashed it %ld times", i);
return;
case 4: /* charm monster */
/* ----- LEVEL 2 SPELLS ----- */
- case 6:
+ case 6: /* web */
i = rnd(3) + 2;
- p = " While the %s is entangled, you hit %d times";
- goto ws; /* web */
+ direct(x, fullhit(i),
+ " While the %s is entangled, you hit %ld times", i);
+ return;
case 7:
if (c[STRCOUNT] == 0)
return;
default:
- lprintf(" spell %d not available!", (long) x);
+ lprintf(" spell %ld not available!", (long) x);
beep();
return;
};
*
* No arguments and no return value
*/
-void
-loseint()
+static void
+loseint(void)
{
if (--c[INTELLIGENCE] < 3)
c[INTELLIGENCE] = 3;
* This routine prints out a message saying "You can't aim your magic!"
* returns 0 if not confused, non-zero (time remaining confused) if confused
*/
-int
-isconfuse()
+static int
+isconfuse(void)
{
if (c[CONFUSE]) {
lprcat(" You can't aim your magic!");
* otherwise returns 0
* Enter with the spell number in x, and the monster number in monst.
*/
-int
-nospell(x, monst)
- int x, monst;
+static int
+nospell(int x, int monst)
{
int tmp;
if (x >= SPNUM || monst >= MAXMONST + 8 || monst < 0 || x < 0)
* Function to return hp damage to monster due to a number of full hits
* Enter with the number of full hits being done
*/
-int
-fullhit(xx)
- int xx;
+static int
+fullhit(int xx)
{
int i;
if (xx < 0 || xx > 20)
* lprintf format string in str, and lprintf's argument in arg.
* Returns no value.
*/
-void
-direct(spnum, dam, str, arg)
- int spnum, dam, arg;
- char *str;
+static void
+direct(int spnum, int dam, const char *str, int arg)
{
int x, y;
int m;
goto fool;
} else {
lastnum = 278;
- lprintf(str, "spell caster (thats you)", (long) arg);
+ lprintf(str, "spell caster (that's you)", (long) arg);
beep();
losehp(dam);
return;
* Returns no value.
*/
void
-godirect(spnum, dam, str, delay, cshow)
- int spnum, dam, delay;
- char *str, cshow;
+godirect(int spnum, int dam, const char *str, int delay, int cshow_i)
{
- char *p;
+ u_char *p;
int x, y, m;
int dx, dy;
+ char cshow;
+
+ /* truncate to char width in case it matters */
+ cshow = (char)cshow_i;
+
if (spnum < 0 || spnum >= SPNUM || str == 0 || delay < 0)
return; /* bad args */
if (isconfuse())
}
if ((x == playerx) && (y == playery)) { /* if energy hits player */
cursors();
- lprcat("\nYou are hit my your own magic!");
+ lprcat("\nYou are hit by your own magic!");
beep();
lastnum = 278;
losehp(dam);
* Enter with the coordinates (x,y) of the monster
* Returns no value.
*/
-void
-ifblind(x, y)
- int x, y;
+static void
+ifblind(int x, int y)
{
- char *p;
+ const char *p;
+
vxy(&x, &y); /* verify correct x,y coordinates */
if (c[BLINDCOUNT]) {
lastnum = 279;
* Enter with the spell number that wants to teleport away
* Returns no value.
*/
-void
-tdirect(spnum)
- int spnum;
+static void
+tdirect(int spnum)
{
int x, y;
int m;
* and the lprintf string to identify the spell in str.
* Returns no value.
*/
-void
-omnidirect(spnum, dam, str)
- int spnum, dam;
- char *str;
+static void
+omnidirect(int spnum, int dam, const char *str)
{
int x, y, m;
+
if (spnum < 0 || spnum >= SPNUM || str == 0)
return; /* bad args */
for (x = playerx - 1; x < playerx + 2; x++)
* Returns index into diroffx[] (0-8).
*/
static int
-dirsub(x, y)
- int *x, *y;
+dirsub(int *x, int *y)
{
int i;
lprcat("\nIn What Direction? ");
for (i = 0;;)
- switch (lgetchar()) {
+ switch (ttgetch()) {
case 'b':
i++;
+ /* FALLTHROUGH */
case 'n':
i++;
+ /* FALLTHROUGH */
case 'y':
i++;
+ /* FALLTHROUGH */
case 'u':
i++;
+ /* FALLTHROUGH */
case 'h':
i++;
+ /* FALLTHROUGH */
case 'k':
i++;
+ /* FALLTHROUGH */
case 'l':
i++;
+ /* FALLTHROUGH */
case 'j':
i++;
+ /* FALLTHROUGH */
goto out;
};
out:
* routine are affected.
*/
int
-vxy(x, y)
- int *x, *y;
+vxy(int *x, int *y)
{
int flag = 0;
if (*x < 0) {
* Enter with the spell number in spmun.
* Returns no value.
*/
-void
-dirpoly(spnum)
- int spnum;
+static void
+dirpoly(int spnum)
{
int x, y, m;
if (spnum < 0 || spnum >= SPNUM)
* Returns no value.
*/
void
-hitmonster(x, y)
- int x, y;
+hitmonster(int x, int y)
{
int tmp, monst, damag = 0, flag;
if (c[TIMESTOP])
* This routine is used to specifically damage a monster at a location (x,y)
* Called by hitmonster(x,y)
*/
-int
-hitm(x, y, amt)
- int x, y;
- int amt;
+static int
+hitm(int x, int y, int amt)
{
int monst;
int hpoints, amt2;
* Returns nothing of value.
*/
void
-hitplayer(x, y)
- int x, y;
+hitplayer(int x, int y)
{
int dam, tmp, mster, bias;
vxy(&x, &y); /* verify coordinates are within range */
lastnum = mster = mitem[x][y];
/*
- * spirit naga's and poltergeist's do nothing if scarab of negate
+ * spirit nagas and poltergeists do nothing if scarab of negate
* spirit
*/
if (c[NEGATESPIRIT] || c[SPIRITPRO])
* Enter with the monster number
* Returns nothing of value.
*/
-void
-dropsomething(monst)
- int monst;
+static void
+dropsomething(int monst)
{
switch (monst) {
case ORC:
* Returns nothing of value.
*/
void
-dropgold(amount)
- int amount;
+dropgold(int amount)
{
if (amount > 250)
createitem(OMAXGOLD, amount / 100);
* Returns nothing of value.
*/
void
-something(level)
- int level;
+something(int cavelevel)
{
int j;
int i;
- if (level < 0 || level > MAXLEVEL + MAXVLEVEL)
+ if (cavelevel < 0 || cavelevel > MAXLEVEL + MAXVLEVEL)
return; /* correct level? */
if (rnd(101) < 8)
- something(level); /* possibly more than one item */
- j = newobject(level, &i);
+ something(cavelevel); /* possibly more than one item */
+ j = newobject(cavelevel, &i);
createitem(j, i);
}
OLONGSWORD};
int
-newobject(lev, i)
- int lev, *i;
+newobject(int lev, int *i)
{
int tmp = 32, j;
if (level < 0 || level > MAXLEVEL + MAXVLEVEL)
{ OPLATEARMOR, -9}
};
static char spsel[] = {1, 2, 3, 5, 6, 8, 9, 11, 13, 14};
-int
-spattack(x, xx, yy)
- int x, xx, yy;
+static int
+spattack(int x, int xx, int yy)
{
int i, j = 0, k, m;
- char *p = 0;
+ const char *p = NULL;
+
if (c[CANCELLATION])
return (0);
vxy(&xx, &yy); /* verify x & y coordinates */
if (j == 0) /* if rusting did not occur */
switch (m) {
case OLEATHER:
- p = "\nThe %s hit you -- Your lucky you have leather on";
+ p = "\nThe %s hit you -- You're lucky you have leather on";
break;
case OSSPLATE:
- p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!";
+ p = "\nThe %s hit you -- You're fortunate to have stainless steel armor!";
break;
}
else {
i = rnd(15) + 8 - c[AC];
spout: p = "\nThe %s breathes fire at you!";
if (c[FIRERESISTANCE])
- p = "\nThe %s's flame doesn't phase you!";
+ p = "\nThe %s's flame doesn't faze you!";
else
spout2: if (p) {
lprintf(p, lastmonst);
* Note: if x > c[HP] this routine could kill the player!
*/
void
-checkloss(x)
- int x;
+checkloss(int x)
{
if (x > 0) {
losehp(x);
* Returns the experience gained from all monsters killed
*/
int
-annihilate()
+annihilate(void)
{
int i, j;
long k;
* Returns the number of spheres currently in existence
*/
int
-newsphere(x, y, dir, life)
- int x, y, dir, life;
+newsphere(int x, int y, int dir, int life)
{
int m;
struct sphere *sp;
lprintf("\nThe %s dispels the sphere!", monster[m].name);
beep();
rmsphere(x, y); /* remove any spheres that are here */
+ free(sp);
return (c[SPHCAST]);
}
if (m == DISENCHANTRESS) { /* disenchantress cancels spheres */
beep();
boom: sphboom(x, y); /* blow up stuff around sphere */
rmsphere(x, y); /* remove any spheres that are here */
+ free(sp);
return (c[SPHCAST]);
}
if (c[CANCELLATION]) { /* cancellation cancels spheres */
* Returns the number of spheres currently in existence
*/
int
-rmsphere(x, y)
- int x, y;
+rmsphere(int x, int y)
{
struct sphere *sp, *sp2 = 0;
for (sp = spheres; sp; sp2 = sp, sp = sp->p)
*
* Enter with the coordinates of the blast, Returns no value
*/
-void
-sphboom(x, y)
- int x, y;
+static void
+sphboom(int x, int y)
{
int i, j;
if (c[HOLDMONST])
*
* This is done by setting a flag in the monster[] structure
*/
-void
-genmonst()
+static void
+genmonst(void)
{
int i, j;
cursors();
lprcat("\nGenocide what monster? ");
- for (i = 0; (!isalpha(i)) && (i != ' '); i = lgetchar());
+ for (i = 0; (!isalpha(i)) && (i != ' '); i = ttgetch());
lprc(i);
for (j = 0; j < MAXMONST; j++) /* search for the monster type */
if (monstnamelist[j] == i) { /* have we found it? */