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