1*aed906e4Smestre /* $OpenBSD: hack.cmd.c,v 1.9 2016/01/09 18:33:15 mestre Exp $ */
2d0b779f3Sniklas
3df930be7Sderaadt /*
4d25013f2Scamield * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5d25013f2Scamield * Amsterdam
6d25013f2Scamield * All rights reserved.
7d25013f2Scamield *
8d25013f2Scamield * Redistribution and use in source and binary forms, with or without
9d25013f2Scamield * modification, are permitted provided that the following conditions are
10d25013f2Scamield * met:
11d25013f2Scamield *
12d25013f2Scamield * - Redistributions of source code must retain the above copyright notice,
13d25013f2Scamield * this list of conditions and the following disclaimer.
14d25013f2Scamield *
15d25013f2Scamield * - Redistributions in binary form must reproduce the above copyright
16d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
17d25013f2Scamield * documentation and/or other materials provided with the distribution.
18d25013f2Scamield *
19d25013f2Scamield * - Neither the name of the Stichting Centrum voor Wiskunde en
20d25013f2Scamield * Informatica, nor the names of its contributors may be used to endorse or
21d25013f2Scamield * promote products derived from this software without specific prior
22d25013f2Scamield * written permission.
23d25013f2Scamield *
24d25013f2Scamield * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25d25013f2Scamield * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26d25013f2Scamield * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27d25013f2Scamield * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28d25013f2Scamield * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31d25013f2Scamield * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32d25013f2Scamield * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33d25013f2Scamield * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34d25013f2Scamield * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35d25013f2Scamield */
36d25013f2Scamield
37d25013f2Scamield /*
38d25013f2Scamield * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39d25013f2Scamield * All rights reserved.
40d25013f2Scamield *
41d25013f2Scamield * Redistribution and use in source and binary forms, with or without
42d25013f2Scamield * modification, are permitted provided that the following conditions
43d25013f2Scamield * are met:
44d25013f2Scamield * 1. Redistributions of source code must retain the above copyright
45d25013f2Scamield * notice, this list of conditions and the following disclaimer.
46d25013f2Scamield * 2. Redistributions in binary form must reproduce the above copyright
47d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
48d25013f2Scamield * documentation and/or other materials provided with the distribution.
49d25013f2Scamield * 3. The name of the author may not be used to endorse or promote products
50d25013f2Scamield * derived from this software without specific prior written permission.
51d25013f2Scamield *
52d25013f2Scamield * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53d25013f2Scamield * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54d25013f2Scamield * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55d25013f2Scamield * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58d25013f2Scamield * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59d25013f2Scamield * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60d25013f2Scamield * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61d25013f2Scamield * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62df930be7Sderaadt */
63df930be7Sderaadt
644a5fbbc4Spjanzen #include <ctype.h>
65df930be7Sderaadt
66*aed906e4Smestre #include "def.func_tab.h"
67*aed906e4Smestre #include "hack.h"
68*aed906e4Smestre
69df930be7Sderaadt struct func_tab cmdlist[]={
704a5fbbc4Spjanzen { '\020', doredotopl },
714a5fbbc4Spjanzen { '\022', doredraw },
724a5fbbc4Spjanzen { '\024', dotele },
73df930be7Sderaadt #ifdef SUSPEND
744a5fbbc4Spjanzen { '\032', dosuspend },
7554da88e4Spjanzen #endif /* SUSPEND */
764a5fbbc4Spjanzen { 'a', doapply },
77df930be7Sderaadt /* 'A' : UNUSED */
78df930be7Sderaadt /* 'b', 'B' : go sw */
794a5fbbc4Spjanzen { 'c', ddocall },
804a5fbbc4Spjanzen { 'C', do_mname },
814a5fbbc4Spjanzen { 'd', dodrop },
824a5fbbc4Spjanzen { 'D', doddrop },
834a5fbbc4Spjanzen { 'e', doeat },
844a5fbbc4Spjanzen { 'E', doengrave },
85df930be7Sderaadt /* 'f', 'F' : multiple go (might become 'fight') */
86df930be7Sderaadt /* 'g', 'G' : UNUSED */
87df930be7Sderaadt /* 'h', 'H' : go west */
884a5fbbc4Spjanzen { 'I', dotypeinv }, /* Robert Viduya */
894a5fbbc4Spjanzen { 'i', ddoinv },
90df930be7Sderaadt /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
91df930be7Sderaadt /* 'o', doopen, */
924a5fbbc4Spjanzen { 'O', doset },
934a5fbbc4Spjanzen { 'p', dopay },
944a5fbbc4Spjanzen { 'P', dowearring },
954a5fbbc4Spjanzen { 'q', dodrink },
964a5fbbc4Spjanzen { 'Q', done2 },
974a5fbbc4Spjanzen { 'r', doread },
984a5fbbc4Spjanzen { 'R', doremring },
994a5fbbc4Spjanzen { 's', dosearch },
1004a5fbbc4Spjanzen { 'S', dosave },
1014a5fbbc4Spjanzen { 't', dothrow },
1024a5fbbc4Spjanzen { 'T', doremarm },
103df930be7Sderaadt /* 'u', 'U' : go ne */
1044a5fbbc4Spjanzen { 'v', doversion },
105df930be7Sderaadt /* 'V' : UNUSED */
1064a5fbbc4Spjanzen { 'w', dowield },
1074a5fbbc4Spjanzen { 'W', doweararm },
108df930be7Sderaadt /* 'x', 'X' : UNUSED */
109df930be7Sderaadt /* 'y', 'Y' : go nw */
1104a5fbbc4Spjanzen { 'z', dozap },
111df930be7Sderaadt /* 'Z' : UNUSED */
1124a5fbbc4Spjanzen { '<', doup },
1134a5fbbc4Spjanzen { '>', dodown },
1144a5fbbc4Spjanzen { '/', dowhatis },
1154a5fbbc4Spjanzen { '?', dohelp },
116df930be7Sderaadt #ifdef SHELL
1174a5fbbc4Spjanzen { '!', dosh },
11854da88e4Spjanzen #endif /* SHELL */
1194a5fbbc4Spjanzen { '.', donull },
1204a5fbbc4Spjanzen { ' ', donull },
1214a5fbbc4Spjanzen { ',', dopickup },
1224a5fbbc4Spjanzen { ':', dolook },
1234a5fbbc4Spjanzen { '^', doidtrap },
1244a5fbbc4Spjanzen { '\\', dodiscovered }, /* Robert Viduya */
1254a5fbbc4Spjanzen { WEAPON_SYM, doprwep },
1264a5fbbc4Spjanzen { ARMOR_SYM, doprarm },
1274a5fbbc4Spjanzen { RING_SYM, doprring },
1284a5fbbc4Spjanzen { '$', doprgold },
1294a5fbbc4Spjanzen { '#', doextcmd },
1304a5fbbc4Spjanzen { '\0', NULL }
131df930be7Sderaadt };
132df930be7Sderaadt
133df930be7Sderaadt struct ext_func_tab extcmdlist[] = {
1344a5fbbc4Spjanzen { "dip", dodip },
1354a5fbbc4Spjanzen { "pray", dopray },
1364a5fbbc4Spjanzen { NULL, donull}
137df930be7Sderaadt };
138df930be7Sderaadt
1394a5fbbc4Spjanzen extern char quitchars[];
140df930be7Sderaadt
1414a5fbbc4Spjanzen static char unctrl(char);
1424a5fbbc4Spjanzen
1434a5fbbc4Spjanzen void
rhack(char * cmd)1444a5fbbc4Spjanzen rhack(char *cmd)
145df930be7Sderaadt {
1464a5fbbc4Spjanzen struct func_tab *tlist = cmdlist;
147df930be7Sderaadt boolean firsttime = FALSE;
1484a5fbbc4Spjanzen int res;
149df930be7Sderaadt
150df930be7Sderaadt if(!cmd) {
151df930be7Sderaadt firsttime = TRUE;
152df930be7Sderaadt flags.nopick = 0;
153df930be7Sderaadt cmd = parse();
154df930be7Sderaadt }
155df930be7Sderaadt if(!*cmd || (*cmd & 0377) == 0377 ||
156df930be7Sderaadt (flags.no_rest_on_space && *cmd == ' ')){
1574a5fbbc4Spjanzen hackbell();
158df930be7Sderaadt flags.move = 0;
159df930be7Sderaadt return; /* probably we just had an interrupt */
160df930be7Sderaadt }
161df930be7Sderaadt if(movecmd(*cmd)) {
162df930be7Sderaadt walk:
163df930be7Sderaadt if(multi) flags.mv = 1;
164df930be7Sderaadt domove();
165df930be7Sderaadt return;
166df930be7Sderaadt }
1675eb74ca3Smmcc if(movecmd(tolower((unsigned char)*cmd))) {
168df930be7Sderaadt flags.run = 1;
169df930be7Sderaadt rush:
170df930be7Sderaadt if(firsttime){
171df930be7Sderaadt if(!multi) multi = COLNO;
172df930be7Sderaadt u.last_str_turn = 0;
173df930be7Sderaadt }
174df930be7Sderaadt flags.mv = 1;
175df930be7Sderaadt #ifdef QUEST
176df930be7Sderaadt if(flags.run >= 4) finddir();
177df930be7Sderaadt if(firsttime){
178df930be7Sderaadt u.ux0 = u.ux + u.dx;
179df930be7Sderaadt u.uy0 = u.uy + u.dy;
180df930be7Sderaadt }
18154da88e4Spjanzen #endif /* QUEST */
182df930be7Sderaadt domove();
183df930be7Sderaadt return;
184df930be7Sderaadt }
185df930be7Sderaadt if((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
186df930be7Sderaadt flags.run = 2;
187df930be7Sderaadt goto rush;
188df930be7Sderaadt }
1895eb74ca3Smmcc if(*cmd == 'F' && movecmd(tolower((unsigned char)cmd[1]))) {
190df930be7Sderaadt flags.run = 3;
191df930be7Sderaadt goto rush;
192df930be7Sderaadt }
193df930be7Sderaadt if(*cmd == 'm' && movecmd(cmd[1])) {
194df930be7Sderaadt flags.run = 0;
195df930be7Sderaadt flags.nopick = 1;
196df930be7Sderaadt goto walk;
197df930be7Sderaadt }
1985eb74ca3Smmcc if(*cmd == 'M' && movecmd(tolower((unsigned char)cmd[1]))) {
199df930be7Sderaadt flags.run = 1;
200df930be7Sderaadt flags.nopick = 1;
201df930be7Sderaadt goto rush;
202df930be7Sderaadt }
203df930be7Sderaadt #ifdef QUEST
204df930be7Sderaadt if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
205df930be7Sderaadt flags.run = 4;
206df930be7Sderaadt if(*cmd == 'F') flags.run += 2;
207df930be7Sderaadt if(cmd[2] == '-') flags.run += 1;
208df930be7Sderaadt goto rush;
209df930be7Sderaadt }
21054da88e4Spjanzen #endif /* QUEST */
211df930be7Sderaadt while(tlist->f_char) {
212df930be7Sderaadt if(*cmd == tlist->f_char){
213df930be7Sderaadt res = (*(tlist->f_funct))();
214df930be7Sderaadt if(!res) {
215df930be7Sderaadt flags.move = 0;
216df930be7Sderaadt multi = 0;
217df930be7Sderaadt }
218df930be7Sderaadt return;
219df930be7Sderaadt }
220df930be7Sderaadt tlist++;
221df930be7Sderaadt }
222df930be7Sderaadt { char expcmd[10];
2234a5fbbc4Spjanzen char *cp = expcmd;
224df930be7Sderaadt while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
225df930be7Sderaadt if(*cmd >= 040 && *cmd < 0177)
226df930be7Sderaadt *cp++ = *cmd++;
227df930be7Sderaadt else {
228df930be7Sderaadt *cp++ = '^';
229df930be7Sderaadt *cp++ = *cmd++ ^ 0100;
230df930be7Sderaadt }
231df930be7Sderaadt }
232df930be7Sderaadt *cp++ = 0;
233df930be7Sderaadt pline("Unknown command '%s'.", expcmd);
234df930be7Sderaadt }
235df930be7Sderaadt multi = flags.move = 0;
236df930be7Sderaadt }
237df930be7Sderaadt
2384a5fbbc4Spjanzen int
doextcmd(void)239*aed906e4Smestre doextcmd(void) /* here after # - now read a full-word command */
240df930be7Sderaadt {
241df930be7Sderaadt char buf[BUFSZ];
2424a5fbbc4Spjanzen struct ext_func_tab *efp = extcmdlist;
243df930be7Sderaadt
244df930be7Sderaadt pline("# ");
245df930be7Sderaadt getlin(buf);
246df930be7Sderaadt clrlin();
247df930be7Sderaadt if(buf[0] == '\033')
248df930be7Sderaadt return(0);
249df930be7Sderaadt while(efp->ef_txt) {
250df930be7Sderaadt if(!strcmp(efp->ef_txt, buf))
251df930be7Sderaadt return((*(efp->ef_funct))());
252df930be7Sderaadt efp++;
253df930be7Sderaadt }
254df930be7Sderaadt pline("%s: unknown command.", buf);
255df930be7Sderaadt return(0);
256df930be7Sderaadt }
257df930be7Sderaadt
2584a5fbbc4Spjanzen static char
unctrl(char sym)2594a5fbbc4Spjanzen unctrl(char sym)
260df930be7Sderaadt {
261df930be7Sderaadt return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym );
262df930be7Sderaadt }
263df930be7Sderaadt
264df930be7Sderaadt /* 'rogue'-like direction commands */
265df930be7Sderaadt char sdir[] = "hykulnjb><";
266df930be7Sderaadt schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 };
267df930be7Sderaadt schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 };
268df930be7Sderaadt schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 };
269df930be7Sderaadt
2704a5fbbc4Spjanzen int
movecmd(char sym)2714a5fbbc4Spjanzen movecmd(char sym) /* also sets u.dz, but returns false for <> */
272df930be7Sderaadt {
2734a5fbbc4Spjanzen char *dp;
274df930be7Sderaadt
275df930be7Sderaadt u.dz = 0;
276180acc8fSmillert if(!(dp = strchr(sdir, sym))) return(0);
277df930be7Sderaadt u.dx = xdir[dp-sdir];
278df930be7Sderaadt u.dy = ydir[dp-sdir];
279df930be7Sderaadt u.dz = zdir[dp-sdir];
280df930be7Sderaadt return(!u.dz);
281df930be7Sderaadt }
282df930be7Sderaadt
2834a5fbbc4Spjanzen int
getdir(boolean s)2844a5fbbc4Spjanzen getdir(boolean s)
285df930be7Sderaadt {
286df930be7Sderaadt char dirsym;
287df930be7Sderaadt
288df930be7Sderaadt if(s) pline("In what direction?");
289df930be7Sderaadt dirsym = readchar();
290df930be7Sderaadt if(!movecmd(dirsym) && !u.dz) {
291180acc8fSmillert if(!strchr(quitchars, dirsym))
292df930be7Sderaadt pline("What a strange direction!");
293df930be7Sderaadt return(0);
294df930be7Sderaadt }
295df930be7Sderaadt if(Confusion && !u.dz)
296df930be7Sderaadt confdir();
297df930be7Sderaadt return(1);
298df930be7Sderaadt }
299df930be7Sderaadt
3004a5fbbc4Spjanzen void
confdir(void)301*aed906e4Smestre confdir(void)
302df930be7Sderaadt {
3034a5fbbc4Spjanzen int x = rn2(8);
304df930be7Sderaadt u.dx = xdir[x];
305df930be7Sderaadt u.dy = ydir[x];
306df930be7Sderaadt }
307df930be7Sderaadt
308df930be7Sderaadt #ifdef QUEST
3094a5fbbc4Spjanzen void
finddir(void)310*aed906e4Smestre finddir(void)
3114a5fbbc4Spjanzen {
3124a5fbbc4Spjanzen int i, ui = u.di;
3134a5fbbc4Spjanzen
314df930be7Sderaadt for(i = 0; i <= 8; i++){
315df930be7Sderaadt if(flags.run & 1) ui++; else ui += 7;
316df930be7Sderaadt ui %= 8;
317df930be7Sderaadt if(i == 8){
318df930be7Sderaadt pline("Not near a wall.");
319df930be7Sderaadt flags.move = multi = 0;
3204a5fbbc4Spjanzen return;
321df930be7Sderaadt }
322df930be7Sderaadt if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
323df930be7Sderaadt break;
324df930be7Sderaadt }
325df930be7Sderaadt for(i = 0; i <= 8; i++){
326df930be7Sderaadt if(flags.run & 1) ui += 7; else ui++;
327df930be7Sderaadt ui %= 8;
328df930be7Sderaadt if(i == 8){
329df930be7Sderaadt pline("Not near a room.");
330df930be7Sderaadt flags.move = multi = 0;
3314a5fbbc4Spjanzen return;
332df930be7Sderaadt }
333df930be7Sderaadt if(isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
334df930be7Sderaadt break;
335df930be7Sderaadt }
336df930be7Sderaadt u.di = ui;
337df930be7Sderaadt u.dx = xdir[ui];
338df930be7Sderaadt u.dy = ydir[ui];
339df930be7Sderaadt }
340df930be7Sderaadt
3414a5fbbc4Spjanzen int
isroom(int x,int y)3424a5fbbc4Spjanzen isroom(int x, int y)
3434a5fbbc4Spjanzen { /* what about POOL? */
344df930be7Sderaadt return(isok(x,y) && (levl[x][y].typ == ROOM ||
345df930be7Sderaadt (levl[x][y].typ >= LDOOR && flags.run >= 6)));
346df930be7Sderaadt }
34754da88e4Spjanzen #endif /* QUEST */
348df930be7Sderaadt
3494a5fbbc4Spjanzen int
isok(int x,int y)3504a5fbbc4Spjanzen isok(int x, int y)
3514a5fbbc4Spjanzen {
352df930be7Sderaadt /* x corresponds to curx, so x==1 is the first column. Ach. %% */
353df930be7Sderaadt return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1);
354df930be7Sderaadt }
355