|
|
1.1 ! root 1: /* ! 2: * Hunt ! 3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold ! 4: * San Francisco, California ! 5: * ! 6: * Copyright (c) 1985 Regents of the University of California. ! 7: * All rights reserved. The Berkeley software License Agreement ! 8: * specifies the terms and conditions for redistribution. ! 9: */ ! 10: ! 11: # include "hunt.h" ! 12: ! 13: # undef CTRL ! 14: # define CTRL(x) ('x' & 037) ! 15: ! 16: # ifdef MONITOR ! 17: /* ! 18: * mon_execute: ! 19: * Execute a single monitor command ! 20: */ ! 21: mon_execute(pp) ! 22: register PLAYER *pp; ! 23: { ! 24: register char ch; ! 25: ! 26: ch = pp->p_cbuf[pp->p_ncount++]; ! 27: switch (ch) { ! 28: case CTRL(L): ! 29: sendcom(pp, REDRAW); ! 30: break; ! 31: case 'q': ! 32: (void) strcpy(pp->p_death, "| Quit |"); ! 33: break; ! 34: } ! 35: } ! 36: # endif MONITOR ! 37: ! 38: /* ! 39: * execute: ! 40: * Execute a single command ! 41: */ ! 42: execute(pp) ! 43: register PLAYER *pp; ! 44: { ! 45: register char ch; ! 46: ! 47: ch = pp->p_cbuf[pp->p_ncount++]; ! 48: ! 49: # ifdef FLY ! 50: if (pp->p_flying >= 0) { ! 51: switch (ch) { ! 52: case CTRL(L): ! 53: sendcom(pp, REDRAW); ! 54: break; ! 55: case 'q': ! 56: (void) strcpy(pp->p_death, "| Quit |"); ! 57: break; ! 58: } ! 59: return; ! 60: } ! 61: # endif FLY ! 62: ! 63: switch (ch) { ! 64: case CTRL(L): ! 65: sendcom(pp, REDRAW); ! 66: break; ! 67: case 'h': ! 68: move(pp, LEFTS); ! 69: break; ! 70: case 'H': ! 71: face(pp, LEFTS); ! 72: break; ! 73: case 'j': ! 74: move(pp, BELOW); ! 75: break; ! 76: case 'J': ! 77: face(pp, BELOW); ! 78: break; ! 79: case 'k': ! 80: move(pp, ABOVE); ! 81: break; ! 82: case 'K': ! 83: face(pp, ABOVE); ! 84: break; ! 85: case 'l': ! 86: move(pp, RIGHT); ! 87: break; ! 88: case 'L': ! 89: face(pp, RIGHT); ! 90: break; ! 91: case 'f': ! 92: case '1': ! 93: fire(pp, 0); /* SHOT */ ! 94: break; ! 95: case 'g': ! 96: case '2': ! 97: fire(pp, 1); /* GRENADE */ ! 98: break; ! 99: case 'F': ! 100: case '3': ! 101: fire(pp, 2); /* SATCHEL */ ! 102: break; ! 103: case 'G': ! 104: case '4': ! 105: fire(pp, 3); /* 7x7 BOMB */ ! 106: break; ! 107: case '5': ! 108: fire(pp, 4); /* 9x9 BOMB */ ! 109: break; ! 110: case '6': ! 111: fire(pp, 5); /* 11x11 BOMB */ ! 112: break; ! 113: case '7': ! 114: fire(pp, 6); /* 13x13 BOMB */ ! 115: break; ! 116: case '8': ! 117: fire(pp, 7); /* 15x15 BOMB */ ! 118: break; ! 119: case '9': ! 120: fire(pp, 8); /* 17x17 BOMB */ ! 121: break; ! 122: case '0': ! 123: fire(pp, 9); /* 19x19 BOMB */ ! 124: break; ! 125: case '@': ! 126: fire(pp, 10); /* 21x21 BOMB */ ! 127: break; ! 128: # ifdef OOZE ! 129: case 'o': ! 130: fire_slime(pp, 0); /* SLIME */ ! 131: break; ! 132: case 'O': ! 133: fire_slime(pp, 1); /* SSLIME */ ! 134: break; ! 135: case 'p': ! 136: fire_slime(pp, 2); ! 137: break; ! 138: case 'P': ! 139: fire_slime(pp, 3); ! 140: break; ! 141: # endif OOZE ! 142: case 's': ! 143: scan(pp); ! 144: break; ! 145: case 'c': ! 146: cloak(pp); ! 147: break; ! 148: case 'q': ! 149: (void) strcpy(pp->p_death, "| Quit |"); ! 150: break; ! 151: } ! 152: } ! 153: ! 154: /* ! 155: * move: ! 156: * Execute a move in the given direction ! 157: */ ! 158: move(pp, dir) ! 159: register PLAYER *pp; ! 160: int dir; ! 161: { ! 162: register PLAYER *newp; ! 163: register int x, y; ! 164: register FLAG moved; ! 165: register BULLET *bp; ! 166: ! 167: y = pp->p_y; ! 168: x = pp->p_x; ! 169: ! 170: switch (dir) { ! 171: case LEFTS: ! 172: x--; ! 173: break; ! 174: case RIGHT: ! 175: x++; ! 176: break; ! 177: case ABOVE: ! 178: y--; ! 179: break; ! 180: case BELOW: ! 181: y++; ! 182: break; ! 183: } ! 184: ! 185: moved = FALSE; ! 186: switch (Maze[y][x]) { ! 187: case SPACE: ! 188: # ifdef RANDOM ! 189: case DOOR: ! 190: # endif RANDOM ! 191: moved = TRUE; ! 192: break; ! 193: case WALL1: ! 194: case WALL2: ! 195: case WALL3: ! 196: # ifdef REFLECT ! 197: case WALL4: ! 198: case WALL5: ! 199: # endif REFLECT ! 200: break; ! 201: case MINE: ! 202: case GMINE: ! 203: if (dir == pp->p_face) ! 204: pickup(pp, y, x, 2, Maze[y][x]); ! 205: else if (opposite(dir, pp->p_face)) ! 206: pickup(pp, y, x, 95, Maze[y][x]); ! 207: else ! 208: pickup(pp, y, x, 50, Maze[y][x]); ! 209: Maze[y][x] = SPACE; ! 210: moved = TRUE; ! 211: break; ! 212: case SHOT: ! 213: case GRENADE: ! 214: case SATCHEL: ! 215: case BOMB: ! 216: # ifdef OOZE ! 217: case SLIME: ! 218: # endif OOZE ! 219: # ifdef DRONE ! 220: case DSHOT: ! 221: # endif DRONE ! 222: bp = is_bullet(y, x); ! 223: if (bp != NULL) ! 224: bp->b_expl = TRUE; ! 225: Maze[y][x] = SPACE; ! 226: moved = TRUE; ! 227: break; ! 228: case LEFTS: ! 229: case RIGHT: ! 230: case ABOVE: ! 231: case BELOW: ! 232: if (dir != pp->p_face) ! 233: sendcom(pp, BELL); ! 234: else { ! 235: newp = play_at(y, x); ! 236: checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE); ! 237: } ! 238: break; ! 239: # ifdef FLY ! 240: case FLYER: ! 241: newp = play_at(y, x); ! 242: message(newp, "Oooh, there's a short guy waving at you!"); ! 243: message(pp, "You couldn't quite reach him!"); ! 244: break; ! 245: # endif FLY ! 246: # ifdef BOOTS ! 247: case BOOT: ! 248: case BOOT_PAIR: ! 249: if (Maze[y][x] == BOOT) ! 250: pp->p_nboots++; ! 251: else ! 252: pp->p_nboots += 2; ! 253: for (newp = Boot; newp < &Boot[NBOOTS]; newp++) { ! 254: if (newp->p_flying < 0) ! 255: continue; ! 256: if (newp->p_y == y && newp->p_x == x) { ! 257: newp->p_flying = -1; ! 258: if (newp->p_undershot) ! 259: fixshots(y, x, newp->p_over); ! 260: } ! 261: } ! 262: if (pp->p_nboots == 2) ! 263: message(pp, "Wow! A pair of boots!"); ! 264: else ! 265: message(pp, "You can hobble around on one boot."); ! 266: Maze[y][x] = SPACE; ! 267: moved = TRUE; ! 268: break; ! 269: # endif BOOTS ! 270: } ! 271: if (moved) { ! 272: if (pp->p_ncshot > 0) ! 273: if (--pp->p_ncshot == MAXNCSHOT) { ! 274: cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); ! 275: outstr(pp, " ok", 3); ! 276: } ! 277: if (pp->p_undershot) { ! 278: fixshots(pp->p_y, pp->p_x, pp->p_over); ! 279: pp->p_undershot = FALSE; ! 280: } ! 281: drawplayer(pp, FALSE); ! 282: pp->p_over = Maze[y][x]; ! 283: pp->p_y = y; ! 284: pp->p_x = x; ! 285: drawplayer(pp, TRUE); ! 286: } ! 287: } ! 288: ! 289: /* ! 290: * face: ! 291: * Change the direction the player is facing ! 292: */ ! 293: face(pp, dir) ! 294: register PLAYER *pp; ! 295: register int dir; ! 296: { ! 297: if (pp->p_face != dir) { ! 298: pp->p_face = dir; ! 299: drawplayer(pp, TRUE); ! 300: } ! 301: } ! 302: ! 303: /* ! 304: * fire: ! 305: * Fire a shot of the given type in the given direction ! 306: */ ! 307: fire(pp, req_index) ! 308: register PLAYER *pp; ! 309: register int req_index; ! 310: { ! 311: if (pp == NULL) ! 312: return; ! 313: # ifdef DEBUG ! 314: if (req_index < 0 || req_index >= MAXBOMB) ! 315: message(pp, "What you do?"); ! 316: # endif DEBUG ! 317: while (req_index >= 0 && pp->p_ammo < shot_req[req_index]) ! 318: req_index--; ! 319: if (req_index < 0) { ! 320: message(pp, "Not enough charges."); ! 321: return; ! 322: } ! 323: if (pp->p_ncshot > MAXNCSHOT) ! 324: return; ! 325: if (pp->p_ncshot++ == MAXNCSHOT) { ! 326: cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); ! 327: outstr(pp, " ", 3); ! 328: } ! 329: pp->p_ammo -= shot_req[req_index]; ! 330: (void) sprintf(Buf, "%3d", pp->p_ammo); ! 331: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); ! 332: outstr(pp, Buf, 3); ! 333: ! 334: add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face, ! 335: shot_req[req_index], pp, FALSE, pp->p_face); ! 336: pp->p_undershot = TRUE; ! 337: ! 338: /* ! 339: * Show the object to everyone ! 340: */ ! 341: showexpl(pp->p_y, pp->p_x, shot_type[req_index]); ! 342: for (pp = Player; pp < End_player; pp++) ! 343: sendcom(pp, REFRESH); ! 344: # ifdef MONITOR ! 345: for (pp = Monitor; pp < End_monitor; pp++) ! 346: sendcom(pp, REFRESH); ! 347: # endif MONITOR ! 348: } ! 349: ! 350: # ifdef OOZE ! 351: /* ! 352: * fire_slime: ! 353: * Fire a slime shot in the given direction ! 354: */ ! 355: fire_slime(pp, req_index) ! 356: register PLAYER *pp; ! 357: register int req_index; ! 358: { ! 359: if (pp == NULL) ! 360: return; ! 361: # ifdef DEBUG ! 362: if (req_index < 0 || req_index >= MAXSLIME) ! 363: message(pp, "What you do?"); ! 364: # endif DEBUG ! 365: while (req_index >= 0 && pp->p_ammo < slime_req[req_index]) ! 366: req_index--; ! 367: if (req_index < 0) { ! 368: message(pp, "Not enough charges."); ! 369: return; ! 370: } ! 371: if (pp->p_ncshot > MAXNCSHOT) ! 372: return; ! 373: if (pp->p_ncshot++ == MAXNCSHOT) { ! 374: cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); ! 375: outstr(pp, " ", 3); ! 376: } ! 377: pp->p_ammo -= slime_req[req_index]; ! 378: (void) sprintf(Buf, "%3d", pp->p_ammo); ! 379: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); ! 380: outstr(pp, Buf, 3); ! 381: ! 382: add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face, ! 383: slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face); ! 384: pp->p_undershot = TRUE; ! 385: ! 386: /* ! 387: * Show the object to everyone ! 388: */ ! 389: showexpl(pp->p_y, pp->p_x, SLIME); ! 390: for (pp = Player; pp < End_player; pp++) ! 391: sendcom(pp, REFRESH); ! 392: # ifdef MONITOR ! 393: for (pp = Monitor; pp < End_monitor; pp++) ! 394: sendcom(pp, REFRESH); ! 395: # endif MONITOR ! 396: } ! 397: # endif OOZE ! 398: ! 399: /* ! 400: * add_shot: ! 401: * Create a shot with the given properties ! 402: */ ! 403: add_shot(type, y, x, face, charge, owner, expl, over) ! 404: int type; ! 405: int y, x; ! 406: char face; ! 407: int charge; ! 408: PLAYER *owner; ! 409: int expl; ! 410: char over; ! 411: { ! 412: register BULLET *bp; ! 413: register int size; ! 414: ! 415: switch (type) { ! 416: case SHOT: ! 417: case MINE: ! 418: size = 1; ! 419: break; ! 420: case GRENADE: ! 421: case GMINE: ! 422: size = 2; ! 423: break; ! 424: case SATCHEL: ! 425: size = 3; ! 426: break; ! 427: case BOMB: ! 428: for (size = 3; size < MAXBOMB; size++) ! 429: if (shot_req[size] >= charge) ! 430: break; ! 431: size++; ! 432: break; ! 433: default: ! 434: size = 0; ! 435: break; ! 436: } ! 437: ! 438: bp = create_shot(type, y, x, face, charge, size, owner, ! 439: (owner == NULL) ? NULL : owner->p_ident, expl, over); ! 440: bp->b_next = Bullets; ! 441: Bullets = bp; ! 442: } ! 443: ! 444: BULLET * ! 445: create_shot(type, y, x, face, charge, size, owner, score, expl, over) ! 446: int type; ! 447: int y, x; ! 448: char face; ! 449: int charge; ! 450: int size; ! 451: PLAYER *owner; ! 452: IDENT *score; ! 453: int expl; ! 454: char over; ! 455: { ! 456: register BULLET *bp; ! 457: ! 458: bp = (BULLET *) malloc(sizeof (BULLET)); /* NOSTRICT */ ! 459: if (bp == NULL) { ! 460: if (owner != NULL) ! 461: message(owner, "Out of memory"); ! 462: return NULL; ! 463: } ! 464: ! 465: bp->b_face = face; ! 466: bp->b_x = x; ! 467: bp->b_y = y; ! 468: bp->b_charge = charge; ! 469: bp->b_owner = owner; ! 470: bp->b_score = score; ! 471: bp->b_type = type; ! 472: bp->b_size = size; ! 473: bp->b_expl = expl; ! 474: bp->b_over = over; ! 475: bp->b_next = NULL; ! 476: ! 477: return bp; ! 478: } ! 479: ! 480: /* ! 481: * cloak: ! 482: * Turn on or increase length of a cloak ! 483: */ ! 484: cloak(pp) ! 485: register PLAYER *pp; ! 486: { ! 487: if (pp->p_ammo <= 0) { ! 488: message(pp, "No more charges"); ! 489: return; ! 490: } ! 491: # ifdef BOOTS ! 492: if (pp->p_nboots > 0) { ! 493: message(pp, "Boots are too noisy to cloak!"); ! 494: return; ! 495: } ! 496: # endif BOOTS ! 497: (void) sprintf(Buf, "%3d", --pp->p_ammo); ! 498: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); ! 499: outstr(pp, Buf, 3); ! 500: ! 501: pp->p_cloak += CLOAKLEN; ! 502: ! 503: if (pp->p_scan >= 0) ! 504: pp->p_scan = -1; ! 505: ! 506: showstat(pp); ! 507: } ! 508: ! 509: /* ! 510: * scan: ! 511: * Turn on or increase length of a scan ! 512: */ ! 513: scan(pp) ! 514: register PLAYER *pp; ! 515: { ! 516: if (pp->p_ammo <= 0) { ! 517: message(pp, "No more charges"); ! 518: return; ! 519: } ! 520: (void) sprintf(Buf, "%3d", --pp->p_ammo); ! 521: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); ! 522: outstr(pp, Buf, 3); ! 523: ! 524: pp->p_scan += SCANLEN; ! 525: ! 526: if (pp->p_cloak >= 0) ! 527: pp->p_cloak = -1; ! 528: ! 529: showstat(pp); ! 530: } ! 531: ! 532: /* ! 533: * pickup: ! 534: * check whether the object blew up or whether he picked it up ! 535: */ ! 536: pickup(pp, y, x, prob, obj) ! 537: register PLAYER *pp; ! 538: register int y, x; ! 539: int prob; ! 540: int obj; ! 541: { ! 542: register int req; ! 543: ! 544: switch (obj) { ! 545: case MINE: ! 546: req = BULREQ; ! 547: break; ! 548: case GMINE: ! 549: req = GRENREQ; ! 550: break; ! 551: default: ! 552: abort(); ! 553: } ! 554: if (rand_num(100) < prob) ! 555: add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL, ! 556: TRUE, pp->p_face); ! 557: else { ! 558: pp->p_ammo += req; ! 559: (void) sprintf(Buf, "%3d", pp->p_ammo); ! 560: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); ! 561: outstr(pp, Buf, 3); ! 562: } ! 563: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.