1 1.12 dholland /* $NetBSD: hack.cmd.c,v 1.12 2011/08/06 20:42:43 dholland Exp $ */ 2 1.4 christos 3 1.2 mycroft /* 4 1.7 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 1.7 jsm * Amsterdam 6 1.7 jsm * All rights reserved. 7 1.7 jsm * 8 1.7 jsm * Redistribution and use in source and binary forms, with or without 9 1.7 jsm * modification, are permitted provided that the following conditions are 10 1.7 jsm * met: 11 1.7 jsm * 12 1.7 jsm * - Redistributions of source code must retain the above copyright notice, 13 1.7 jsm * this list of conditions and the following disclaimer. 14 1.7 jsm * 15 1.7 jsm * - Redistributions in binary form must reproduce the above copyright 16 1.7 jsm * notice, this list of conditions and the following disclaimer in the 17 1.7 jsm * documentation and/or other materials provided with the distribution. 18 1.7 jsm * 19 1.7 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en 20 1.7 jsm * Informatica, nor the names of its contributors may be used to endorse or 21 1.7 jsm * promote products derived from this software without specific prior 22 1.7 jsm * written permission. 23 1.7 jsm * 24 1.7 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 1.7 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.7 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 1.7 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 1.7 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 1.7 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 1.7 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 1.7 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 1.7 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 1.7 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 1.7 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 1.7 jsm */ 36 1.7 jsm 37 1.7 jsm /* 38 1.7 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org> 39 1.7 jsm * All rights reserved. 40 1.7 jsm * 41 1.7 jsm * Redistribution and use in source and binary forms, with or without 42 1.7 jsm * modification, are permitted provided that the following conditions 43 1.7 jsm * are met: 44 1.7 jsm * 1. Redistributions of source code must retain the above copyright 45 1.7 jsm * notice, this list of conditions and the following disclaimer. 46 1.7 jsm * 2. Redistributions in binary form must reproduce the above copyright 47 1.7 jsm * notice, this list of conditions and the following disclaimer in the 48 1.7 jsm * documentation and/or other materials provided with the distribution. 49 1.7 jsm * 3. The name of the author may not be used to endorse or promote products 50 1.7 jsm * derived from this software without specific prior written permission. 51 1.7 jsm * 52 1.7 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 1.7 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 1.7 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 1.7 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 1.7 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 1.7 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 1.7 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 1.7 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 1.7 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 1.7 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.2 mycroft */ 63 1.2 mycroft 64 1.4 christos #include <sys/cdefs.h> 65 1.2 mycroft #ifndef lint 66 1.12 dholland __RCSID("$NetBSD: hack.cmd.c,v 1.12 2011/08/06 20:42:43 dholland Exp $"); 67 1.4 christos #endif /* not lint */ 68 1.1 cgd 69 1.1 cgd #include "hack.h" 70 1.4 christos #include "extern.h" 71 1.1 cgd #include "def.func_tab.h" 72 1.1 cgd 73 1.10 dholland static int doextcmd(void); 74 1.10 dholland 75 1.10 dholland static const struct func_tab cmdlist[] = { 76 1.4 christos { '\020', doredotopl }, 77 1.4 christos { '\022', doredraw }, 78 1.4 christos { '\024', dotele }, 79 1.1 cgd #ifdef SUSPEND 80 1.4 christos { '\032', dosuspend }, 81 1.5 cgd #endif /* SUSPEND */ 82 1.4 christos { 'a', doapply }, 83 1.4 christos /* 'A' : UNUSED */ 84 1.4 christos /* 'b', 'B' : go sw */ 85 1.4 christos { 'c', ddocall }, 86 1.4 christos { 'C', do_mname }, 87 1.4 christos { 'd', dodrop }, 88 1.4 christos { 'D', doddrop }, 89 1.4 christos { 'e', doeat }, 90 1.4 christos { 'E', doengrave }, 91 1.4 christos /* 'f', 'F' : multiple go (might become 'fight') */ 92 1.4 christos /* 'g', 'G' : UNUSED */ 93 1.4 christos /* 'h', 'H' : go west */ 94 1.4 christos { 'I', dotypeinv }, /* Robert Viduya */ 95 1.4 christos { 'i', ddoinv }, 96 1.4 christos /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 97 1.4 christos /* 'o', doopen, */ 98 1.4 christos { 'O', doset }, 99 1.4 christos { 'p', dopay }, 100 1.4 christos { 'P', dowearring }, 101 1.4 christos { 'q', dodrink }, 102 1.4 christos { 'Q', dodone }, 103 1.4 christos { 'r', doread }, 104 1.4 christos { 'R', doremring }, 105 1.4 christos { 's', dosearch }, 106 1.4 christos { 'S', dosave }, 107 1.4 christos { 't', dothrow }, 108 1.4 christos { 'T', doremarm }, 109 1.4 christos /* 'u', 'U' : go ne */ 110 1.4 christos { 'v', doversion }, 111 1.4 christos /* 'V' : UNUSED */ 112 1.4 christos { 'w', dowield }, 113 1.4 christos { 'W', doweararm }, 114 1.4 christos /* 'x', 'X' : UNUSED */ 115 1.4 christos /* 'y', 'Y' : go nw */ 116 1.4 christos { 'z', dozap }, 117 1.4 christos /* 'Z' : UNUSED */ 118 1.4 christos { '<', doup }, 119 1.4 christos { '>', dodown }, 120 1.4 christos { '/', dowhatis }, 121 1.4 christos { '?', dohelp }, 122 1.1 cgd #ifdef SHELL 123 1.4 christos { '!', dosh }, 124 1.5 cgd #endif /* SHELL */ 125 1.4 christos { '.', donull }, 126 1.4 christos { ' ', donull }, 127 1.4 christos { ',', dopickup }, 128 1.4 christos { ':', dolook }, 129 1.4 christos { '^', doidtrap }, 130 1.4 christos { '\\', dodiscovered }, /* Robert Viduya */ 131 1.4 christos { WEAPON_SYM, doprwep }, 132 1.4 christos { ARMOR_SYM, doprarm }, 133 1.4 christos { RING_SYM, doprring }, 134 1.4 christos { '$', doprgold }, 135 1.4 christos { '#', doextcmd }, 136 1.4 christos { 0, 0 } 137 1.1 cgd }; 138 1.1 cgd 139 1.10 dholland static const struct ext_func_tab extcmdlist[] = { 140 1.4 christos { "dip", dodip }, 141 1.4 christos { "pray", dopray }, 142 1.12 dholland { NULL, donull } 143 1.1 cgd }; 144 1.1 cgd 145 1.10 dholland static char lowc(int); 146 1.10 dholland static char unctrl(int); 147 1.10 dholland 148 1.4 christos void 149 1.9 dholland rhack(const char *cmd) 150 1.1 cgd { 151 1.6 jsm const struct func_tab *tlist = cmdlist; 152 1.4 christos boolean firsttime = FALSE; 153 1.4 christos int res; 154 1.1 cgd 155 1.4 christos if (!cmd) { 156 1.1 cgd firsttime = TRUE; 157 1.1 cgd flags.nopick = 0; 158 1.1 cgd cmd = parse(); 159 1.1 cgd } 160 1.4 christos if (!*cmd || (*cmd & 0377) == 0377 || 161 1.4 christos (flags.no_rest_on_space && *cmd == ' ')) { 162 1.11 roy sound_bell(); 163 1.1 cgd flags.move = 0; 164 1.1 cgd return; /* probably we just had an interrupt */ 165 1.1 cgd } 166 1.4 christos if (movecmd(*cmd)) { 167 1.4 christos walk: 168 1.4 christos if (multi) 169 1.4 christos flags.mv = 1; 170 1.1 cgd domove(); 171 1.1 cgd return; 172 1.1 cgd } 173 1.4 christos if (movecmd(lowc(*cmd))) { 174 1.1 cgd flags.run = 1; 175 1.4 christos rush: 176 1.4 christos if (firsttime) { 177 1.4 christos if (!multi) 178 1.4 christos multi = COLNO; 179 1.1 cgd u.last_str_turn = 0; 180 1.1 cgd } 181 1.1 cgd flags.mv = 1; 182 1.1 cgd #ifdef QUEST 183 1.4 christos if (flags.run >= 4) 184 1.4 christos finddir(); 185 1.4 christos if (firsttime) { 186 1.1 cgd u.ux0 = u.ux + u.dx; 187 1.1 cgd u.uy0 = u.uy + u.dy; 188 1.1 cgd } 189 1.4 christos #endif /* QUEST */ 190 1.1 cgd domove(); 191 1.1 cgd return; 192 1.1 cgd } 193 1.4 christos if ((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) { 194 1.1 cgd flags.run = 2; 195 1.1 cgd goto rush; 196 1.1 cgd } 197 1.4 christos if (*cmd == 'F' && movecmd(lowc(cmd[1]))) { 198 1.1 cgd flags.run = 3; 199 1.1 cgd goto rush; 200 1.1 cgd } 201 1.4 christos if (*cmd == 'm' && movecmd(cmd[1])) { 202 1.1 cgd flags.run = 0; 203 1.1 cgd flags.nopick = 1; 204 1.1 cgd goto walk; 205 1.1 cgd } 206 1.4 christos if (*cmd == 'M' && movecmd(lowc(cmd[1]))) { 207 1.1 cgd flags.run = 1; 208 1.1 cgd flags.nopick = 1; 209 1.1 cgd goto rush; 210 1.1 cgd } 211 1.1 cgd #ifdef QUEST 212 1.4 christos if (*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) { 213 1.1 cgd flags.run = 4; 214 1.4 christos if (*cmd == 'F') 215 1.4 christos flags.run += 2; 216 1.4 christos if (cmd[2] == '-') 217 1.4 christos flags.run += 1; 218 1.1 cgd goto rush; 219 1.1 cgd } 220 1.4 christos #endif /* QUEST */ 221 1.4 christos while (tlist->f_char) { 222 1.4 christos if (*cmd == tlist->f_char) { 223 1.4 christos res = (*(tlist->f_funct)) (); 224 1.4 christos if (!res) { 225 1.1 cgd flags.move = 0; 226 1.1 cgd multi = 0; 227 1.1 cgd } 228 1.1 cgd return; 229 1.1 cgd } 230 1.1 cgd tlist++; 231 1.1 cgd } 232 1.4 christos { 233 1.4 christos char expcmd[10]; 234 1.4 christos char *cp = expcmd; 235 1.8 dholland while (*cmd && cp - expcmd < (int)sizeof(expcmd) - 2) { 236 1.4 christos if (*cmd >= 040 && *cmd < 0177) 237 1.4 christos *cp++ = *cmd++; 238 1.4 christos else { 239 1.4 christos *cp++ = '^'; 240 1.4 christos *cp++ = *cmd++ ^ 0100; 241 1.4 christos } 242 1.1 cgd } 243 1.4 christos *cp++ = 0; 244 1.4 christos pline("Unknown command '%s'.", expcmd); 245 1.1 cgd } 246 1.1 cgd multi = flags.move = 0; 247 1.1 cgd } 248 1.1 cgd 249 1.10 dholland static int 250 1.9 dholland doextcmd(void) 251 1.4 christos { /* here after # - now read a full-word 252 1.4 christos * command */ 253 1.4 christos char buf[BUFSZ]; 254 1.6 jsm const struct ext_func_tab *efp = extcmdlist; 255 1.1 cgd 256 1.1 cgd pline("# "); 257 1.1 cgd getlin(buf); 258 1.1 cgd clrlin(); 259 1.4 christos if (buf[0] == '\033') 260 1.4 christos return (0); 261 1.4 christos while (efp->ef_txt) { 262 1.4 christos if (!strcmp(efp->ef_txt, buf)) 263 1.4 christos return ((*(efp->ef_funct)) ()); 264 1.1 cgd efp++; 265 1.1 cgd } 266 1.1 cgd pline("%s: unknown command.", buf); 267 1.4 christos return (0); 268 1.1 cgd } 269 1.1 cgd 270 1.10 dholland static char 271 1.9 dholland lowc(int sym) 272 1.1 cgd { 273 1.4 christos return ((sym >= 'A' && sym <= 'Z') ? sym + 'a' - 'A' : sym); 274 1.1 cgd } 275 1.1 cgd 276 1.10 dholland static char 277 1.9 dholland unctrl(int sym) 278 1.1 cgd { 279 1.4 christos return ((sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym); 280 1.1 cgd } 281 1.1 cgd 282 1.1 cgd /* 'rogue'-like direction commands */ 283 1.4 christos char sdir[] = "hykulnjb><"; 284 1.4 christos schar xdir[10] = {-1, -1, 0, 1, 1, 1, 0, -1, 0, 0}; 285 1.4 christos schar ydir[10] = {0, -1, -1, -1, 0, 1, 1, 1, 0, 0}; 286 1.10 dholland static schar zdir[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, -1}; 287 1.4 christos 288 1.4 christos int 289 1.9 dholland movecmd(int sym) /* also sets u.dz, but returns false for <> */ 290 1.1 cgd { 291 1.4 christos char *dp; 292 1.1 cgd 293 1.1 cgd u.dz = 0; 294 1.4 christos if (!(dp = strchr(sdir, sym))) 295 1.4 christos return (0); 296 1.4 christos u.dx = xdir[dp - sdir]; 297 1.4 christos u.dy = ydir[dp - sdir]; 298 1.4 christos u.dz = zdir[dp - sdir]; 299 1.4 christos return (!u.dz); 300 1.1 cgd } 301 1.1 cgd 302 1.4 christos int 303 1.9 dholland getdir(boolean s) 304 1.1 cgd { 305 1.4 christos char dirsym; 306 1.1 cgd 307 1.4 christos if (s) 308 1.4 christos pline("In what direction?"); 309 1.1 cgd dirsym = readchar(); 310 1.4 christos if (!movecmd(dirsym) && !u.dz) { 311 1.4 christos if (!strchr(quitchars, dirsym)) 312 1.1 cgd pline("What a strange direction!"); 313 1.4 christos return (0); 314 1.1 cgd } 315 1.4 christos if (Confusion && !u.dz) 316 1.1 cgd confdir(); 317 1.4 christos return (1); 318 1.1 cgd } 319 1.1 cgd 320 1.4 christos void 321 1.9 dholland confdir(void) 322 1.1 cgd { 323 1.4 christos int x = rn2(8); 324 1.1 cgd u.dx = xdir[x]; 325 1.1 cgd u.dy = ydir[x]; 326 1.1 cgd } 327 1.1 cgd 328 1.1 cgd #ifdef QUEST 329 1.4 christos int 330 1.9 dholland finddir(void) 331 1.4 christos { 332 1.4 christos int i, ui = u.di; 333 1.4 christos for (i = 0; i <= 8; i++) { 334 1.4 christos if (flags.run & 1) 335 1.4 christos ui++; 336 1.4 christos else 337 1.4 christos ui += 7; 338 1.1 cgd ui %= 8; 339 1.4 christos if (i == 8) { 340 1.1 cgd pline("Not near a wall."); 341 1.1 cgd flags.move = multi = 0; 342 1.4 christos return (0); 343 1.1 cgd } 344 1.4 christos if (!isroom(u.ux + xdir[ui], u.uy + ydir[ui])) 345 1.1 cgd break; 346 1.1 cgd } 347 1.4 christos for (i = 0; i <= 8; i++) { 348 1.4 christos if (flags.run & 1) 349 1.4 christos ui += 7; 350 1.4 christos else 351 1.4 christos ui++; 352 1.1 cgd ui %= 8; 353 1.4 christos if (i == 8) { 354 1.1 cgd pline("Not near a room."); 355 1.1 cgd flags.move = multi = 0; 356 1.4 christos return (0); 357 1.1 cgd } 358 1.4 christos if (isroom(u.ux + xdir[ui], u.uy + ydir[ui])) 359 1.1 cgd break; 360 1.1 cgd } 361 1.1 cgd u.di = ui; 362 1.1 cgd u.dx = xdir[ui]; 363 1.1 cgd u.dy = ydir[ui]; 364 1.4 christos return 0; 365 1.1 cgd } 366 1.1 cgd 367 1.4 christos int 368 1.9 dholland isroom(int x, int y) 369 1.4 christos { /* what about POOL? */ 370 1.4 christos return (isok(x, y) && (levl[x][y].typ == ROOM || 371 1.4 christos (levl[x][y].typ >= LDOOR && flags.run >= 6))); 372 1.1 cgd } 373 1.4 christos #endif /* QUEST */ 374 1.1 cgd 375 1.4 christos int 376 1.9 dholland isok(int x, int y) 377 1.4 christos { 378 1.1 cgd /* x corresponds to curx, so x==1 is the first column. Ach. %% */ 379 1.4 christos return (x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1); 380 1.1 cgd } 381