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