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