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