/* * Hunt * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold * San Francisco, California * * Copyright (c) 1985 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ # include "hunt.h" # undef CTRL # define CTRL(x) ('x' & 037) # ifdef MONITOR /* * mon_execute: * Execute a single monitor command */ mon_execute(pp) register PLAYER *pp; { register char ch; ch = pp->p_cbuf[pp->p_ncount++]; switch (ch) { case CTRL(L): sendcom(pp, REDRAW); break; case 'q': (void) strcpy(pp->p_death, "| Quit |"); break; } } # endif MONITOR /* * execute: * Execute a single command */ execute(pp) register PLAYER *pp; { register char ch; ch = pp->p_cbuf[pp->p_ncount++]; # ifdef FLY if (pp->p_flying >= 0) { switch (ch) { case CTRL(L): sendcom(pp, REDRAW); break; case 'q': (void) strcpy(pp->p_death, "| Quit |"); break; } return; } # endif FLY switch (ch) { case CTRL(L): sendcom(pp, REDRAW); break; case 'h': move(pp, LEFTS); break; case 'H': face(pp, LEFTS); break; case 'j': move(pp, BELOW); break; case 'J': face(pp, BELOW); break; case 'k': move(pp, ABOVE); break; case 'K': face(pp, ABOVE); break; case 'l': move(pp, RIGHT); break; case 'L': face(pp, RIGHT); break; case 'f': fire(pp, SHOT); break; case 'g': fire(pp, GRENADE); break; case 'F': fire(pp, SATCHEL); break; case 'G': fire(pp, BOMB); break; # ifdef OOZE case 'o': fire_slime(pp, SLIMEREQ); break; case 'O': fire_slime(pp, SSLIMEREQ); break; # endif OOZE case 's': scan(pp); break; case 'c': cloak(pp); break; case 'q': (void) strcpy(pp->p_death, "| Quit |"); break; } } /* * move: * Execute a move in the given direction */ move(pp, dir) register PLAYER *pp; int dir; { register PLAYER *newp; register int x, y; register FLAG moved; register BULLET *bp; y = pp->p_y; x = pp->p_x; switch (dir) { case LEFTS: x--; break; case RIGHT: x++; break; case ABOVE: y--; break; case BELOW: y++; break; } moved = FALSE; switch (Maze[y][x]) { case SPACE: # ifdef RANDOM case DOOR: # endif RANDOM moved = TRUE; break; case WALL1: case WALL2: case WALL3: # ifdef REFLECT case WALL4: case WALL5: # endif REFLECT break; case MINE: case GMINE: if (dir == pp->p_face) pickup(pp, y, x, 5, Maze[y][x]); else if (opposite(dir, pp->p_face)) pickup(pp, y, x, 95, Maze[y][x]); else pickup(pp, y, x, 50, Maze[y][x]); Maze[y][x] = SPACE; moved = TRUE; break; case SHOT: case GRENADE: case SATCHEL: case BOMB: bp = is_bullet(y, x); if (bp != NULL) bp->b_expl = TRUE; Maze[y][x] = SPACE; moved = TRUE; break; case LEFTS: case RIGHT: case ABOVE: case BELOW: # ifdef FLY case FLYER: # endif FLY if (dir != pp->p_face) sendcom(pp, BELL); else { newp = play_at(y, x); checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE); } break; } if (moved) { if (pp->p_ncshot > 0) if (--pp->p_ncshot == MAXNCSHOT) { cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); outstr(pp, " ok", 3); } if (pp->p_undershot) { fixshots(pp->p_y, pp->p_x, pp->p_over); pp->p_undershot = FALSE; } drawplayer(pp, FALSE); pp->p_over = Maze[y][x]; pp->p_y = y; pp->p_x = x; drawplayer(pp, TRUE); } } /* * face: * Change the direction the player is facing */ face(pp, dir) register PLAYER *pp; register int dir; { if (pp->p_face != dir) { pp->p_face = dir; drawplayer(pp, TRUE); } } /* * fire: * Fire a shot of the given type in the given direction */ fire(pp, type) register PLAYER *pp; register char type; { register int req_index; static int req[4] = { BULREQ, GRENREQ, SATREQ, BOMBREQ }; static int shot_type[4] = { SHOT, GRENADE, SATCHEL, BOMB }; if (pp == NULL) return; if (pp->p_ammo == 0) { message(pp, "No more charges."); return; } if (pp->p_ncshot > MAXNCSHOT) return; if (pp->p_ncshot++ == MAXNCSHOT) { cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); outstr(pp, " ", 3); } switch (type) { case SHOT: req_index = 0; break; case GRENADE: req_index = 1; break; case SATCHEL: req_index = 2; break; case BOMB: req_index = 3; break; # ifdef DEBUG default: message(pp, "What you do!!!"); return; # endif DEBUG } while (pp->p_ammo < req[req_index]) req_index--; pp->p_ammo -= req[req_index]; (void) sprintf(Buf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face, req[req_index], pp, FALSE, pp->p_face); pp->p_undershot = TRUE; /* * Show the object to everyone */ showexpl(pp->p_y, pp->p_x, shot_type[req_index]); for (pp = Player; pp < End_player; pp++) sendcom(pp, REFRESH); # ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) sendcom(pp, REFRESH); # endif MONITOR } # ifdef OOZE /* * fire_slime: * Fire a slime shot in the given direction */ fire_slime(pp, req) register PLAYER *pp; register int req; { if (pp == NULL) return; if (pp->p_ammo < req) { message(pp, "Not enough charges."); return; } if (pp->p_ncshot > MAXNCSHOT) return; if (pp->p_ncshot++ == MAXNCSHOT) { cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); outstr(pp, " ", 3); } pp->p_ammo -= req; (void) sprintf(Buf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face, req, pp, FALSE, pp->p_face); /* * Show the object to everyone */ showexpl(pp->p_y, pp->p_x, SLIME); for (pp = Player; pp < End_player; pp++) sendcom(pp, REFRESH); # ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) sendcom(pp, REFRESH); # endif MONITOR } # endif OOZE /* * create_shot: * Create a shot with the given properties */ add_shot(type, y, x, face, charge, owner, expl, over) int type; int y, x; char face; int charge; PLAYER *owner; int expl; char over; { register BULLET *bp; # ifdef CONSTANT_MOVE /* * if there are no bullets in flight, set up the alarm */ if (Bullets == NULL) bul_alarm(1); # endif CONSTANT_MOVE bp = create_shot(type, y, x, face, charge, owner, (owner == NULL) ? NULL : owner->p_ident, expl, over); bp->b_next = Bullets; Bullets = bp; } BULLET * create_shot(type, y, x, face, charge, owner, score, expl, over) int type; int y, x; char face; int charge; PLAYER *owner; IDENT *score; int expl; char over; { register BULLET *bp; bp = (BULLET *) malloc(sizeof (BULLET)); /* NOSTRICT */ if (bp == NULL) { if (owner != NULL) message(owner, "Out of memory"); return NULL; } bp->b_face = face; bp->b_x = x; bp->b_y = y; bp->b_charge = charge; bp->b_owner = owner; bp->b_score = score; bp->b_type = type; bp->b_expl = expl; bp->b_over = over; bp->b_next = NULL; return bp; } /* * cloak: * Turn on or increase length of a cloak */ cloak(pp) register PLAYER *pp; { if (pp->p_ammo <= 0) { message(pp, "No more charges"); return; } (void) sprintf(Buf, "%3d", --pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); pp->p_cloak += CLOAKLEN; cgoto(pp, STAT_CLOAK_ROW, STAT_VALUE_COL); outstr(pp, " on", 3); if (pp->p_scan >= 0) { pp->p_scan = -1; cgoto(pp, STAT_SCAN_ROW, STAT_VALUE_COL); outstr(pp, " ", 3); } showstat(pp); } /* * scan: * Turn on or increase length of a scan */ scan(pp) register PLAYER *pp; { if (pp->p_ammo <= 0) { message(pp, "No more charges"); return; } (void) sprintf(Buf, "%3d", --pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); pp->p_scan += SCANLEN; cgoto(pp, STAT_SCAN_ROW, STAT_VALUE_COL); outstr(pp, " on", 3); if (pp->p_cloak >= 0) { pp->p_cloak = -1; cgoto(pp, STAT_CLOAK_ROW, STAT_VALUE_COL); outstr(pp, " ", 3); } showstat(pp); } /* * pickup: * check whether the object blew up or whether he picked it up */ pickup(pp, y, x, prob, obj) register PLAYER *pp; register int y, x; int prob; int obj; { register int req; switch (obj) { case MINE: req = BULREQ; break; case GMINE: req = GRENREQ; break; default: abort(); } if (rand_num(100) < prob) add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL, TRUE, pp->p_face); else { pp->p_ammo += req; (void) sprintf(Buf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); } }