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