Home | History | Annotate | Line # | Download | only in hack
hack.cmd.c revision 1.8
      1  1.8  dholland /*	$NetBSD: hack.cmd.c,v 1.8 2008/01/28 06:55:41 dholland Exp $	*/
      2  1.4  christos 
      3  1.2   mycroft /*
      4  1.7       jsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
      5  1.7       jsm  * Amsterdam
      6  1.7       jsm  * All rights reserved.
      7  1.7       jsm  *
      8  1.7       jsm  * Redistribution and use in source and binary forms, with or without
      9  1.7       jsm  * modification, are permitted provided that the following conditions are
     10  1.7       jsm  * met:
     11  1.7       jsm  *
     12  1.7       jsm  * - Redistributions of source code must retain the above copyright notice,
     13  1.7       jsm  * this list of conditions and the following disclaimer.
     14  1.7       jsm  *
     15  1.7       jsm  * - Redistributions in binary form must reproduce the above copyright
     16  1.7       jsm  * notice, this list of conditions and the following disclaimer in the
     17  1.7       jsm  * documentation and/or other materials provided with the distribution.
     18  1.7       jsm  *
     19  1.7       jsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
     20  1.7       jsm  * Informatica, nor the names of its contributors may be used to endorse or
     21  1.7       jsm  * promote products derived from this software without specific prior
     22  1.7       jsm  * written permission.
     23  1.7       jsm  *
     24  1.7       jsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     25  1.7       jsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  1.7       jsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     27  1.7       jsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     28  1.7       jsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     29  1.7       jsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     30  1.7       jsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     31  1.7       jsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     32  1.7       jsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     33  1.7       jsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     34  1.7       jsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35  1.7       jsm  */
     36  1.7       jsm 
     37  1.7       jsm /*
     38  1.7       jsm  * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
     39  1.7       jsm  * All rights reserved.
     40  1.7       jsm  *
     41  1.7       jsm  * Redistribution and use in source and binary forms, with or without
     42  1.7       jsm  * modification, are permitted provided that the following conditions
     43  1.7       jsm  * are met:
     44  1.7       jsm  * 1. Redistributions of source code must retain the above copyright
     45  1.7       jsm  *    notice, this list of conditions and the following disclaimer.
     46  1.7       jsm  * 2. Redistributions in binary form must reproduce the above copyright
     47  1.7       jsm  *    notice, this list of conditions and the following disclaimer in the
     48  1.7       jsm  *    documentation and/or other materials provided with the distribution.
     49  1.7       jsm  * 3. The name of the author may not be used to endorse or promote products
     50  1.7       jsm  *    derived from this software without specific prior written permission.
     51  1.7       jsm  *
     52  1.7       jsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     53  1.7       jsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     54  1.7       jsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     55  1.7       jsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     56  1.7       jsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     57  1.7       jsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     58  1.7       jsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     59  1.7       jsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     60  1.7       jsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     61  1.7       jsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     62  1.2   mycroft  */
     63  1.2   mycroft 
     64  1.4  christos #include <sys/cdefs.h>
     65  1.2   mycroft #ifndef lint
     66  1.8  dholland __RCSID("$NetBSD: hack.cmd.c,v 1.8 2008/01/28 06:55:41 dholland Exp $");
     67  1.4  christos #endif				/* not lint */
     68  1.1       cgd 
     69  1.1       cgd #include	"hack.h"
     70  1.4  christos #include	"extern.h"
     71  1.1       cgd #include	"def.func_tab.h"
     72  1.1       cgd 
     73  1.6       jsm const struct func_tab cmdlist[] = {
     74  1.4  christos 	{ '\020', doredotopl },
     75  1.4  christos 	{ '\022', doredraw },
     76  1.4  christos 	{ '\024', dotele },
     77  1.1       cgd #ifdef SUSPEND
     78  1.4  christos 	{ '\032', dosuspend },
     79  1.5       cgd #endif	/* SUSPEND */
     80  1.4  christos 	{ 'a', doapply },
     81  1.4  christos 	/* 'A' : UNUSED */
     82  1.4  christos 	/* 'b', 'B' : go sw */
     83  1.4  christos 	{ 'c', ddocall },
     84  1.4  christos 	{ 'C', do_mname },
     85  1.4  christos 	{ 'd', dodrop },
     86  1.4  christos 	{ 'D', doddrop },
     87  1.4  christos 	{ 'e', doeat },
     88  1.4  christos 	{ 'E', doengrave },
     89  1.4  christos 	/* 'f', 'F' : multiple go (might become 'fight') */
     90  1.4  christos 	/* 'g', 'G' : UNUSED */
     91  1.4  christos 	/* 'h', 'H' : go west */
     92  1.4  christos 	{ 'I', dotypeinv },		/* Robert Viduya */
     93  1.4  christos 	{ 'i', ddoinv },
     94  1.4  christos 	/* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
     95  1.4  christos 	/* 'o', doopen,	 */
     96  1.4  christos 	{ 'O', doset },
     97  1.4  christos 	{ 'p', dopay },
     98  1.4  christos 	{ 'P', dowearring },
     99  1.4  christos 	{ 'q', dodrink },
    100  1.4  christos 	{ 'Q', dodone },
    101  1.4  christos 	{ 'r', doread },
    102  1.4  christos 	{ 'R', doremring },
    103  1.4  christos 	{ 's', dosearch },
    104  1.4  christos 	{ 'S', dosave },
    105  1.4  christos 	{ 't', dothrow },
    106  1.4  christos 	{ 'T', doremarm },
    107  1.4  christos 	/* 'u', 'U' : go ne */
    108  1.4  christos 	{ 'v', doversion },
    109  1.4  christos 	/* 'V' : UNUSED */
    110  1.4  christos 	{ 'w', dowield },
    111  1.4  christos 	{ 'W', doweararm },
    112  1.4  christos 	/* 'x', 'X' : UNUSED */
    113  1.4  christos 	/* 'y', 'Y' : go nw */
    114  1.4  christos 	{ 'z', dozap },
    115  1.4  christos 	/* 'Z' : UNUSED */
    116  1.4  christos 	{ '<', doup },
    117  1.4  christos 	{ '>', dodown },
    118  1.4  christos 	{ '/', dowhatis },
    119  1.4  christos 	{ '?', dohelp },
    120  1.1       cgd #ifdef SHELL
    121  1.4  christos 	{ '!', dosh },
    122  1.5       cgd #endif	/* SHELL */
    123  1.4  christos 	{ '.', donull },
    124  1.4  christos 	{ ' ', donull },
    125  1.4  christos 	{ ',', dopickup },
    126  1.4  christos 	{ ':', dolook },
    127  1.4  christos 	{ '^', doidtrap },
    128  1.4  christos 	{ '\\', dodiscovered },	/* Robert Viduya */
    129  1.4  christos 	{ WEAPON_SYM, doprwep },
    130  1.4  christos 	{ ARMOR_SYM, doprarm },
    131  1.4  christos 	{ RING_SYM, doprring },
    132  1.4  christos 	{ '$', doprgold },
    133  1.4  christos 	{ '#', doextcmd },
    134  1.4  christos 	{ 0, 0 }
    135  1.1       cgd };
    136  1.1       cgd 
    137  1.6       jsm const struct ext_func_tab extcmdlist[] = {
    138  1.4  christos 	{ "dip", dodip },
    139  1.4  christos 	{ "pray", dopray },
    140  1.4  christos 	{ (char *) 0, donull }
    141  1.1       cgd };
    142  1.1       cgd 
    143  1.4  christos void
    144  1.1       cgd rhack(cmd)
    145  1.6       jsm 	const char  *cmd;
    146  1.1       cgd {
    147  1.6       jsm 	const struct func_tab *tlist = cmdlist;
    148  1.4  christos 	boolean         firsttime = FALSE;
    149  1.4  christos 	int res;
    150  1.1       cgd 
    151  1.4  christos 	if (!cmd) {
    152  1.1       cgd 		firsttime = TRUE;
    153  1.1       cgd 		flags.nopick = 0;
    154  1.1       cgd 		cmd = parse();
    155  1.1       cgd 	}
    156  1.4  christos 	if (!*cmd || (*cmd & 0377) == 0377 ||
    157  1.4  christos 	    (flags.no_rest_on_space && *cmd == ' ')) {
    158  1.1       cgd 		bell();
    159  1.1       cgd 		flags.move = 0;
    160  1.1       cgd 		return;		/* probably we just had an interrupt */
    161  1.1       cgd 	}
    162  1.4  christos 	if (movecmd(*cmd)) {
    163  1.4  christos walk:
    164  1.4  christos 		if (multi)
    165  1.4  christos 			flags.mv = 1;
    166  1.1       cgd 		domove();
    167  1.1       cgd 		return;
    168  1.1       cgd 	}
    169  1.4  christos 	if (movecmd(lowc(*cmd))) {
    170  1.1       cgd 		flags.run = 1;
    171  1.4  christos rush:
    172  1.4  christos 		if (firsttime) {
    173  1.4  christos 			if (!multi)
    174  1.4  christos 				multi = COLNO;
    175  1.1       cgd 			u.last_str_turn = 0;
    176  1.1       cgd 		}
    177  1.1       cgd 		flags.mv = 1;
    178  1.1       cgd #ifdef QUEST
    179  1.4  christos 		if (flags.run >= 4)
    180  1.4  christos 			finddir();
    181  1.4  christos 		if (firsttime) {
    182  1.1       cgd 			u.ux0 = u.ux + u.dx;
    183  1.1       cgd 			u.uy0 = u.uy + u.dy;
    184  1.1       cgd 		}
    185  1.4  christos #endif	/* QUEST */
    186  1.1       cgd 		domove();
    187  1.1       cgd 		return;
    188  1.1       cgd 	}
    189  1.4  christos 	if ((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
    190  1.1       cgd 		flags.run = 2;
    191  1.1       cgd 		goto rush;
    192  1.1       cgd 	}
    193  1.4  christos 	if (*cmd == 'F' && movecmd(lowc(cmd[1]))) {
    194  1.1       cgd 		flags.run = 3;
    195  1.1       cgd 		goto rush;
    196  1.1       cgd 	}
    197  1.4  christos 	if (*cmd == 'm' && movecmd(cmd[1])) {
    198  1.1       cgd 		flags.run = 0;
    199  1.1       cgd 		flags.nopick = 1;
    200  1.1       cgd 		goto walk;
    201  1.1       cgd 	}
    202  1.4  christos 	if (*cmd == 'M' && movecmd(lowc(cmd[1]))) {
    203  1.1       cgd 		flags.run = 1;
    204  1.1       cgd 		flags.nopick = 1;
    205  1.1       cgd 		goto rush;
    206  1.1       cgd 	}
    207  1.1       cgd #ifdef QUEST
    208  1.4  christos 	if (*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
    209  1.1       cgd 		flags.run = 4;
    210  1.4  christos 		if (*cmd == 'F')
    211  1.4  christos 			flags.run += 2;
    212  1.4  christos 		if (cmd[2] == '-')
    213  1.4  christos 			flags.run += 1;
    214  1.1       cgd 		goto rush;
    215  1.1       cgd 	}
    216  1.4  christos #endif	/* QUEST */
    217  1.4  christos 	while (tlist->f_char) {
    218  1.4  christos 		if (*cmd == tlist->f_char) {
    219  1.4  christos 			res = (*(tlist->f_funct)) ();
    220  1.4  christos 			if (!res) {
    221  1.1       cgd 				flags.move = 0;
    222  1.1       cgd 				multi = 0;
    223  1.1       cgd 			}
    224  1.1       cgd 			return;
    225  1.1       cgd 		}
    226  1.1       cgd 		tlist++;
    227  1.1       cgd 	}
    228  1.4  christos 	{
    229  1.4  christos 		char            expcmd[10];
    230  1.4  christos 		char  *cp = expcmd;
    231  1.8  dholland 		while (*cmd && cp - expcmd < (int)sizeof(expcmd) - 2) {
    232  1.4  christos 			if (*cmd >= 040 && *cmd < 0177)
    233  1.4  christos 				*cp++ = *cmd++;
    234  1.4  christos 			else {
    235  1.4  christos 				*cp++ = '^';
    236  1.4  christos 				*cp++ = *cmd++ ^ 0100;
    237  1.4  christos 			}
    238  1.1       cgd 		}
    239  1.4  christos 		*cp++ = 0;
    240  1.4  christos 		pline("Unknown command '%s'.", expcmd);
    241  1.1       cgd 	}
    242  1.1       cgd 	multi = flags.move = 0;
    243  1.1       cgd }
    244  1.1       cgd 
    245  1.4  christos int
    246  1.4  christos doextcmd()
    247  1.4  christos {				/* here after # - now read a full-word
    248  1.4  christos 				 * command */
    249  1.4  christos 	char            buf[BUFSZ];
    250  1.6       jsm 	const struct ext_func_tab *efp = extcmdlist;
    251  1.1       cgd 
    252  1.1       cgd 	pline("# ");
    253  1.1       cgd 	getlin(buf);
    254  1.1       cgd 	clrlin();
    255  1.4  christos 	if (buf[0] == '\033')
    256  1.4  christos 		return (0);
    257  1.4  christos 	while (efp->ef_txt) {
    258  1.4  christos 		if (!strcmp(efp->ef_txt, buf))
    259  1.4  christos 			return ((*(efp->ef_funct)) ());
    260  1.1       cgd 		efp++;
    261  1.1       cgd 	}
    262  1.1       cgd 	pline("%s: unknown command.", buf);
    263  1.4  christos 	return (0);
    264  1.1       cgd }
    265  1.1       cgd 
    266  1.1       cgd char
    267  1.1       cgd lowc(sym)
    268  1.4  christos 	char            sym;
    269  1.1       cgd {
    270  1.4  christos 	return ((sym >= 'A' && sym <= 'Z') ? sym + 'a' - 'A' : sym);
    271  1.1       cgd }
    272  1.1       cgd 
    273  1.1       cgd char
    274  1.1       cgd unctrl(sym)
    275  1.4  christos 	char            sym;
    276  1.1       cgd {
    277  1.4  christos 	return ((sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym);
    278  1.1       cgd }
    279  1.1       cgd 
    280  1.1       cgd /* 'rogue'-like direction commands */
    281  1.4  christos char            sdir[] = "hykulnjb><";
    282  1.4  christos schar           xdir[10] = {-1, -1, 0, 1, 1, 1, 0, -1, 0, 0};
    283  1.4  christos schar           ydir[10] = {0, -1, -1, -1, 0, 1, 1, 1, 0, 0};
    284  1.4  christos schar           zdir[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, -1};
    285  1.4  christos 
    286  1.4  christos int
    287  1.4  christos movecmd(sym)			/* also sets u.dz, but returns false for <> */
    288  1.4  christos 	char            sym;
    289  1.1       cgd {
    290  1.4  christos 	char  *dp;
    291  1.1       cgd 
    292  1.1       cgd 	u.dz = 0;
    293  1.4  christos 	if (!(dp = strchr(sdir, sym)))
    294  1.4  christos 		return (0);
    295  1.4  christos 	u.dx = xdir[dp - sdir];
    296  1.4  christos 	u.dy = ydir[dp - sdir];
    297  1.4  christos 	u.dz = zdir[dp - sdir];
    298  1.4  christos 	return (!u.dz);
    299  1.1       cgd }
    300  1.1       cgd 
    301  1.4  christos int
    302  1.1       cgd getdir(s)
    303  1.4  christos 	boolean         s;
    304  1.1       cgd {
    305  1.4  christos 	char            dirsym;
    306  1.1       cgd 
    307  1.4  christos 	if (s)
    308  1.4  christos 		pline("In what direction?");
    309  1.1       cgd 	dirsym = readchar();
    310  1.4  christos 	if (!movecmd(dirsym) && !u.dz) {
    311  1.4  christos 		if (!strchr(quitchars, dirsym))
    312  1.1       cgd 			pline("What a strange direction!");
    313  1.4  christos 		return (0);
    314  1.1       cgd 	}
    315  1.4  christos 	if (Confusion && !u.dz)
    316  1.1       cgd 		confdir();
    317  1.4  christos 	return (1);
    318  1.1       cgd }
    319  1.1       cgd 
    320  1.4  christos void
    321  1.1       cgd confdir()
    322  1.1       cgd {
    323  1.4  christos 	int x = rn2(8);
    324  1.1       cgd 	u.dx = xdir[x];
    325  1.1       cgd 	u.dy = ydir[x];
    326  1.1       cgd }
    327  1.1       cgd 
    328  1.1       cgd #ifdef QUEST
    329  1.4  christos int
    330  1.4  christos finddir()
    331  1.4  christos {
    332  1.4  christos 	int    i, ui = u.di;
    333  1.4  christos 	for (i = 0; i <= 8; i++) {
    334  1.4  christos 		if (flags.run & 1)
    335  1.4  christos 			ui++;
    336  1.4  christos 		else
    337  1.4  christos 			ui += 7;
    338  1.1       cgd 		ui %= 8;
    339  1.4  christos 		if (i == 8) {
    340  1.1       cgd 			pline("Not near a wall.");
    341  1.1       cgd 			flags.move = multi = 0;
    342  1.4  christos 			return (0);
    343  1.1       cgd 		}
    344  1.4  christos 		if (!isroom(u.ux + xdir[ui], u.uy + ydir[ui]))
    345  1.1       cgd 			break;
    346  1.1       cgd 	}
    347  1.4  christos 	for (i = 0; i <= 8; i++) {
    348  1.4  christos 		if (flags.run & 1)
    349  1.4  christos 			ui += 7;
    350  1.4  christos 		else
    351  1.4  christos 			ui++;
    352  1.1       cgd 		ui %= 8;
    353  1.4  christos 		if (i == 8) {
    354  1.1       cgd 			pline("Not near a room.");
    355  1.1       cgd 			flags.move = multi = 0;
    356  1.4  christos 			return (0);
    357  1.1       cgd 		}
    358  1.4  christos 		if (isroom(u.ux + xdir[ui], u.uy + ydir[ui]))
    359  1.1       cgd 			break;
    360  1.1       cgd 	}
    361  1.1       cgd 	u.di = ui;
    362  1.1       cgd 	u.dx = xdir[ui];
    363  1.1       cgd 	u.dy = ydir[ui];
    364  1.4  christos 	return 0;
    365  1.1       cgd }
    366  1.1       cgd 
    367  1.4  christos int
    368  1.4  christos isroom(x, y)
    369  1.4  christos 	int	x, y;
    370  1.4  christos {				/* what about POOL? */
    371  1.4  christos 	return (isok(x, y) && (levl[x][y].typ == ROOM ||
    372  1.4  christos 			       (levl[x][y].typ >= LDOOR && flags.run >= 6)));
    373  1.1       cgd }
    374  1.4  christos #endif	/* QUEST */
    375  1.1       cgd 
    376  1.4  christos int
    377  1.4  christos isok(x, y)
    378  1.4  christos 	int x, y;
    379  1.4  christos {
    380  1.1       cgd 	/* x corresponds to curx, so x==1 is the first column. Ach. %% */
    381  1.4  christos 	return (x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1);
    382  1.1       cgd }
    383