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