Home | History | Annotate | Line # | Download | only in hack
hack.cmd.c revision 1.6
      1  1.6       jsm /*	$NetBSD: hack.cmd.c,v 1.6 2001/03/25 20:43:59 jsm Exp $	*/
      2  1.4  christos 
      3  1.2   mycroft /*
      4  1.2   mycroft  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
      5  1.2   mycroft  */
      6  1.2   mycroft 
      7  1.4  christos #include <sys/cdefs.h>
      8  1.2   mycroft #ifndef lint
      9  1.6       jsm __RCSID("$NetBSD: hack.cmd.c,v 1.6 2001/03/25 20:43:59 jsm Exp $");
     10  1.4  christos #endif				/* not lint */
     11  1.1       cgd 
     12  1.1       cgd #include	"hack.h"
     13  1.4  christos #include	"extern.h"
     14  1.1       cgd #include	"def.func_tab.h"
     15  1.1       cgd 
     16  1.6       jsm const struct func_tab cmdlist[] = {
     17  1.4  christos 	{ '\020', doredotopl },
     18  1.4  christos 	{ '\022', doredraw },
     19  1.4  christos 	{ '\024', dotele },
     20  1.1       cgd #ifdef SUSPEND
     21  1.4  christos 	{ '\032', dosuspend },
     22  1.5       cgd #endif	/* SUSPEND */
     23  1.4  christos 	{ 'a', doapply },
     24  1.4  christos 	/* 'A' : UNUSED */
     25  1.4  christos 	/* 'b', 'B' : go sw */
     26  1.4  christos 	{ 'c', ddocall },
     27  1.4  christos 	{ 'C', do_mname },
     28  1.4  christos 	{ 'd', dodrop },
     29  1.4  christos 	{ 'D', doddrop },
     30  1.4  christos 	{ 'e', doeat },
     31  1.4  christos 	{ 'E', doengrave },
     32  1.4  christos 	/* 'f', 'F' : multiple go (might become 'fight') */
     33  1.4  christos 	/* 'g', 'G' : UNUSED */
     34  1.4  christos 	/* 'h', 'H' : go west */
     35  1.4  christos 	{ 'I', dotypeinv },		/* Robert Viduya */
     36  1.4  christos 	{ 'i', ddoinv },
     37  1.4  christos 	/* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
     38  1.4  christos 	/* 'o', doopen,	 */
     39  1.4  christos 	{ 'O', doset },
     40  1.4  christos 	{ 'p', dopay },
     41  1.4  christos 	{ 'P', dowearring },
     42  1.4  christos 	{ 'q', dodrink },
     43  1.4  christos 	{ 'Q', dodone },
     44  1.4  christos 	{ 'r', doread },
     45  1.4  christos 	{ 'R', doremring },
     46  1.4  christos 	{ 's', dosearch },
     47  1.4  christos 	{ 'S', dosave },
     48  1.4  christos 	{ 't', dothrow },
     49  1.4  christos 	{ 'T', doremarm },
     50  1.4  christos 	/* 'u', 'U' : go ne */
     51  1.4  christos 	{ 'v', doversion },
     52  1.4  christos 	/* 'V' : UNUSED */
     53  1.4  christos 	{ 'w', dowield },
     54  1.4  christos 	{ 'W', doweararm },
     55  1.4  christos 	/* 'x', 'X' : UNUSED */
     56  1.4  christos 	/* 'y', 'Y' : go nw */
     57  1.4  christos 	{ 'z', dozap },
     58  1.4  christos 	/* 'Z' : UNUSED */
     59  1.4  christos 	{ '<', doup },
     60  1.4  christos 	{ '>', dodown },
     61  1.4  christos 	{ '/', dowhatis },
     62  1.4  christos 	{ '?', dohelp },
     63  1.1       cgd #ifdef SHELL
     64  1.4  christos 	{ '!', dosh },
     65  1.5       cgd #endif	/* SHELL */
     66  1.4  christos 	{ '.', donull },
     67  1.4  christos 	{ ' ', donull },
     68  1.4  christos 	{ ',', dopickup },
     69  1.4  christos 	{ ':', dolook },
     70  1.4  christos 	{ '^', doidtrap },
     71  1.4  christos 	{ '\\', dodiscovered },	/* Robert Viduya */
     72  1.4  christos 	{ WEAPON_SYM, doprwep },
     73  1.4  christos 	{ ARMOR_SYM, doprarm },
     74  1.4  christos 	{ RING_SYM, doprring },
     75  1.4  christos 	{ '$', doprgold },
     76  1.4  christos 	{ '#', doextcmd },
     77  1.4  christos 	{ 0, 0 }
     78  1.1       cgd };
     79  1.1       cgd 
     80  1.6       jsm const struct ext_func_tab extcmdlist[] = {
     81  1.4  christos 	{ "dip", dodip },
     82  1.4  christos 	{ "pray", dopray },
     83  1.4  christos 	{ (char *) 0, donull }
     84  1.1       cgd };
     85  1.1       cgd 
     86  1.4  christos void
     87  1.1       cgd rhack(cmd)
     88  1.6       jsm 	const char  *cmd;
     89  1.1       cgd {
     90  1.6       jsm 	const struct func_tab *tlist = cmdlist;
     91  1.4  christos 	boolean         firsttime = FALSE;
     92  1.4  christos 	int res;
     93  1.1       cgd 
     94  1.4  christos 	if (!cmd) {
     95  1.1       cgd 		firsttime = TRUE;
     96  1.1       cgd 		flags.nopick = 0;
     97  1.1       cgd 		cmd = parse();
     98  1.1       cgd 	}
     99  1.4  christos 	if (!*cmd || (*cmd & 0377) == 0377 ||
    100  1.4  christos 	    (flags.no_rest_on_space && *cmd == ' ')) {
    101  1.1       cgd 		bell();
    102  1.1       cgd 		flags.move = 0;
    103  1.1       cgd 		return;		/* probably we just had an interrupt */
    104  1.1       cgd 	}
    105  1.4  christos 	if (movecmd(*cmd)) {
    106  1.4  christos walk:
    107  1.4  christos 		if (multi)
    108  1.4  christos 			flags.mv = 1;
    109  1.1       cgd 		domove();
    110  1.1       cgd 		return;
    111  1.1       cgd 	}
    112  1.4  christos 	if (movecmd(lowc(*cmd))) {
    113  1.1       cgd 		flags.run = 1;
    114  1.4  christos rush:
    115  1.4  christos 		if (firsttime) {
    116  1.4  christos 			if (!multi)
    117  1.4  christos 				multi = COLNO;
    118  1.1       cgd 			u.last_str_turn = 0;
    119  1.1       cgd 		}
    120  1.1       cgd 		flags.mv = 1;
    121  1.1       cgd #ifdef QUEST
    122  1.4  christos 		if (flags.run >= 4)
    123  1.4  christos 			finddir();
    124  1.4  christos 		if (firsttime) {
    125  1.1       cgd 			u.ux0 = u.ux + u.dx;
    126  1.1       cgd 			u.uy0 = u.uy + u.dy;
    127  1.1       cgd 		}
    128  1.4  christos #endif	/* QUEST */
    129  1.1       cgd 		domove();
    130  1.1       cgd 		return;
    131  1.1       cgd 	}
    132  1.4  christos 	if ((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
    133  1.1       cgd 		flags.run = 2;
    134  1.1       cgd 		goto rush;
    135  1.1       cgd 	}
    136  1.4  christos 	if (*cmd == 'F' && movecmd(lowc(cmd[1]))) {
    137  1.1       cgd 		flags.run = 3;
    138  1.1       cgd 		goto rush;
    139  1.1       cgd 	}
    140  1.4  christos 	if (*cmd == 'm' && movecmd(cmd[1])) {
    141  1.1       cgd 		flags.run = 0;
    142  1.1       cgd 		flags.nopick = 1;
    143  1.1       cgd 		goto walk;
    144  1.1       cgd 	}
    145  1.4  christos 	if (*cmd == 'M' && movecmd(lowc(cmd[1]))) {
    146  1.1       cgd 		flags.run = 1;
    147  1.1       cgd 		flags.nopick = 1;
    148  1.1       cgd 		goto rush;
    149  1.1       cgd 	}
    150  1.1       cgd #ifdef QUEST
    151  1.4  christos 	if (*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
    152  1.1       cgd 		flags.run = 4;
    153  1.4  christos 		if (*cmd == 'F')
    154  1.4  christos 			flags.run += 2;
    155  1.4  christos 		if (cmd[2] == '-')
    156  1.4  christos 			flags.run += 1;
    157  1.1       cgd 		goto rush;
    158  1.1       cgd 	}
    159  1.4  christos #endif	/* QUEST */
    160  1.4  christos 	while (tlist->f_char) {
    161  1.4  christos 		if (*cmd == tlist->f_char) {
    162  1.4  christos 			res = (*(tlist->f_funct)) ();
    163  1.4  christos 			if (!res) {
    164  1.1       cgd 				flags.move = 0;
    165  1.1       cgd 				multi = 0;
    166  1.1       cgd 			}
    167  1.1       cgd 			return;
    168  1.1       cgd 		}
    169  1.1       cgd 		tlist++;
    170  1.1       cgd 	}
    171  1.4  christos 	{
    172  1.4  christos 		char            expcmd[10];
    173  1.4  christos 		char  *cp = expcmd;
    174  1.4  christos 		while (*cmd && cp - expcmd < sizeof(expcmd) - 2) {
    175  1.4  christos 			if (*cmd >= 040 && *cmd < 0177)
    176  1.4  christos 				*cp++ = *cmd++;
    177  1.4  christos 			else {
    178  1.4  christos 				*cp++ = '^';
    179  1.4  christos 				*cp++ = *cmd++ ^ 0100;
    180  1.4  christos 			}
    181  1.1       cgd 		}
    182  1.4  christos 		*cp++ = 0;
    183  1.4  christos 		pline("Unknown command '%s'.", expcmd);
    184  1.1       cgd 	}
    185  1.1       cgd 	multi = flags.move = 0;
    186  1.1       cgd }
    187  1.1       cgd 
    188  1.4  christos int
    189  1.4  christos doextcmd()
    190  1.4  christos {				/* here after # - now read a full-word
    191  1.4  christos 				 * command */
    192  1.4  christos 	char            buf[BUFSZ];
    193  1.6       jsm 	const struct ext_func_tab *efp = extcmdlist;
    194  1.1       cgd 
    195  1.1       cgd 	pline("# ");
    196  1.1       cgd 	getlin(buf);
    197  1.1       cgd 	clrlin();
    198  1.4  christos 	if (buf[0] == '\033')
    199  1.4  christos 		return (0);
    200  1.4  christos 	while (efp->ef_txt) {
    201  1.4  christos 		if (!strcmp(efp->ef_txt, buf))
    202  1.4  christos 			return ((*(efp->ef_funct)) ());
    203  1.1       cgd 		efp++;
    204  1.1       cgd 	}
    205  1.1       cgd 	pline("%s: unknown command.", buf);
    206  1.4  christos 	return (0);
    207  1.1       cgd }
    208  1.1       cgd 
    209  1.1       cgd char
    210  1.1       cgd lowc(sym)
    211  1.4  christos 	char            sym;
    212  1.1       cgd {
    213  1.4  christos 	return ((sym >= 'A' && sym <= 'Z') ? sym + 'a' - 'A' : sym);
    214  1.1       cgd }
    215  1.1       cgd 
    216  1.1       cgd char
    217  1.1       cgd unctrl(sym)
    218  1.4  christos 	char            sym;
    219  1.1       cgd {
    220  1.4  christos 	return ((sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym);
    221  1.1       cgd }
    222  1.1       cgd 
    223  1.1       cgd /* 'rogue'-like direction commands */
    224  1.4  christos char            sdir[] = "hykulnjb><";
    225  1.4  christos schar           xdir[10] = {-1, -1, 0, 1, 1, 1, 0, -1, 0, 0};
    226  1.4  christos schar           ydir[10] = {0, -1, -1, -1, 0, 1, 1, 1, 0, 0};
    227  1.4  christos schar           zdir[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, -1};
    228  1.4  christos 
    229  1.4  christos int
    230  1.4  christos movecmd(sym)			/* also sets u.dz, but returns false for <> */
    231  1.4  christos 	char            sym;
    232  1.1       cgd {
    233  1.4  christos 	char  *dp;
    234  1.1       cgd 
    235  1.1       cgd 	u.dz = 0;
    236  1.4  christos 	if (!(dp = strchr(sdir, sym)))
    237  1.4  christos 		return (0);
    238  1.4  christos 	u.dx = xdir[dp - sdir];
    239  1.4  christos 	u.dy = ydir[dp - sdir];
    240  1.4  christos 	u.dz = zdir[dp - sdir];
    241  1.4  christos 	return (!u.dz);
    242  1.1       cgd }
    243  1.1       cgd 
    244  1.4  christos int
    245  1.1       cgd getdir(s)
    246  1.4  christos 	boolean         s;
    247  1.1       cgd {
    248  1.4  christos 	char            dirsym;
    249  1.1       cgd 
    250  1.4  christos 	if (s)
    251  1.4  christos 		pline("In what direction?");
    252  1.1       cgd 	dirsym = readchar();
    253  1.4  christos 	if (!movecmd(dirsym) && !u.dz) {
    254  1.4  christos 		if (!strchr(quitchars, dirsym))
    255  1.1       cgd 			pline("What a strange direction!");
    256  1.4  christos 		return (0);
    257  1.1       cgd 	}
    258  1.4  christos 	if (Confusion && !u.dz)
    259  1.1       cgd 		confdir();
    260  1.4  christos 	return (1);
    261  1.1       cgd }
    262  1.1       cgd 
    263  1.4  christos void
    264  1.1       cgd confdir()
    265  1.1       cgd {
    266  1.4  christos 	int x = rn2(8);
    267  1.1       cgd 	u.dx = xdir[x];
    268  1.1       cgd 	u.dy = ydir[x];
    269  1.1       cgd }
    270  1.1       cgd 
    271  1.1       cgd #ifdef QUEST
    272  1.4  christos int
    273  1.4  christos finddir()
    274  1.4  christos {
    275  1.4  christos 	int    i, ui = u.di;
    276  1.4  christos 	for (i = 0; i <= 8; i++) {
    277  1.4  christos 		if (flags.run & 1)
    278  1.4  christos 			ui++;
    279  1.4  christos 		else
    280  1.4  christos 			ui += 7;
    281  1.1       cgd 		ui %= 8;
    282  1.4  christos 		if (i == 8) {
    283  1.1       cgd 			pline("Not near a wall.");
    284  1.1       cgd 			flags.move = multi = 0;
    285  1.4  christos 			return (0);
    286  1.1       cgd 		}
    287  1.4  christos 		if (!isroom(u.ux + xdir[ui], u.uy + ydir[ui]))
    288  1.1       cgd 			break;
    289  1.1       cgd 	}
    290  1.4  christos 	for (i = 0; i <= 8; i++) {
    291  1.4  christos 		if (flags.run & 1)
    292  1.4  christos 			ui += 7;
    293  1.4  christos 		else
    294  1.4  christos 			ui++;
    295  1.1       cgd 		ui %= 8;
    296  1.4  christos 		if (i == 8) {
    297  1.1       cgd 			pline("Not near a room.");
    298  1.1       cgd 			flags.move = multi = 0;
    299  1.4  christos 			return (0);
    300  1.1       cgd 		}
    301  1.4  christos 		if (isroom(u.ux + xdir[ui], u.uy + ydir[ui]))
    302  1.1       cgd 			break;
    303  1.1       cgd 	}
    304  1.1       cgd 	u.di = ui;
    305  1.1       cgd 	u.dx = xdir[ui];
    306  1.1       cgd 	u.dy = ydir[ui];
    307  1.4  christos 	return 0;
    308  1.1       cgd }
    309  1.1       cgd 
    310  1.4  christos int
    311  1.4  christos isroom(x, y)
    312  1.4  christos 	int	x, y;
    313  1.4  christos {				/* what about POOL? */
    314  1.4  christos 	return (isok(x, y) && (levl[x][y].typ == ROOM ||
    315  1.4  christos 			       (levl[x][y].typ >= LDOOR && flags.run >= 6)));
    316  1.1       cgd }
    317  1.4  christos #endif	/* QUEST */
    318  1.1       cgd 
    319  1.4  christos int
    320  1.4  christos isok(x, y)
    321  1.4  christos 	int x, y;
    322  1.4  christos {
    323  1.1       cgd 	/* x corresponds to curx, so x==1 is the first column. Ach. %% */
    324  1.4  christos 	return (x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1);
    325  1.1       cgd }
    326