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