diff options
Diffstat (limited to 'hunt/huntd/execute.c')
| -rw-r--r-- | hunt/huntd/execute.c | 556 |
1 files changed, 556 insertions, 0 deletions
diff --git a/hunt/huntd/execute.c b/hunt/huntd/execute.c new file mode 100644 index 00000000..c961d486 --- /dev/null +++ b/hunt/huntd/execute.c @@ -0,0 +1,556 @@ +/* + * Hunt + * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold + * San Francisco, California + */ + +# include "hunt.h" + +# 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 + +/* + * 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 + + switch (ch) { + case CTRL('L'): + sendcom(pp, REDRAW); + break; + case 'h': + move_player(pp, LEFTS); + break; + case 'H': + face(pp, LEFTS); + break; + case 'j': + move_player(pp, BELOW); + break; + case 'J': + face(pp, BELOW); + break; + case 'k': + move_player(pp, ABOVE); + break; + case 'K': + face(pp, ABOVE); + break; + case 'l': + move_player(pp, RIGHT); + break; + case 'L': + face(pp, RIGHT); + break; + case 'f': + case '1': + fire(pp, 0); /* SHOT */ + break; + case 'g': + case '2': + fire(pp, 1); /* GRENADE */ + break; + case 'F': + case '3': + fire(pp, 2); /* SATCHEL */ + break; + case 'G': + case '4': + fire(pp, 3); /* 7x7 BOMB */ + break; + case '5': + fire(pp, 4); /* 9x9 BOMB */ + break; + case '6': + fire(pp, 5); /* 11x11 BOMB */ + break; + case '7': + fire(pp, 6); /* 13x13 BOMB */ + break; + case '8': + fire(pp, 7); /* 15x15 BOMB */ + break; + case '9': + fire(pp, 8); /* 17x17 BOMB */ + break; + case '0': + fire(pp, 9); /* 19x19 BOMB */ + break; + case '@': + fire(pp, 10); /* 21x21 BOMB */ + break; +# ifdef OOZE + case 'o': + fire_slime(pp, 0); /* SLIME */ + break; + case 'O': + fire_slime(pp, 1); /* SSLIME */ + break; + case 'p': + fire_slime(pp, 2); + break; + case 'P': + fire_slime(pp, 3); + break; +# endif + case 's': + scan(pp); + break; + case 'c': + cloak(pp); + break; + case 'q': + (void) strcpy(pp->p_death, "| Quit |"); + break; + } +} + +/* + * move_player: + * Execute a move in the given direction + */ +move_player(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 + moved = TRUE; + break; + case WALL1: + case WALL2: + case WALL3: +# ifdef REFLECT + case WALL4: + case WALL5: +# endif + break; + case MINE: + case GMINE: + if (dir == pp->p_face) + pickup(pp, y, x, 2, 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: +# ifdef OOZE + case SLIME: +# endif +# ifdef DRONE + case DSHOT: +# endif + 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: + if (dir != pp->p_face) + sendcom(pp, BELL); + else { + newp = play_at(y, x); + checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE); + } + break; +# ifdef FLY + case FLYER: + newp = play_at(y, x); + message(newp, "Oooh, there's a short guy waving at you!"); + message(pp, "You couldn't quite reach him!"); + break; +# endif +# ifdef BOOTS + case BOOT: + case BOOT_PAIR: + if (Maze[y][x] == BOOT) + pp->p_nboots++; + else + pp->p_nboots += 2; + for (newp = Boot; newp < &Boot[NBOOTS]; newp++) { + if (newp->p_flying < 0) + continue; + if (newp->p_y == y && newp->p_x == x) { + newp->p_flying = -1; + if (newp->p_undershot) + fixshots(y, x, newp->p_over); + } + } + if (pp->p_nboots == 2) + message(pp, "Wow! A pair of boots!"); + else + message(pp, "You can hobble around on one boot."); + Maze[y][x] = SPACE; + moved = TRUE; + break; +# endif + } + 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, req_index) +register PLAYER *pp; +register int req_index; +{ + if (pp == NULL) + return; +# ifdef DEBUG + if (req_index < 0 || req_index >= MAXBOMB) + message(pp, "What you do?"); +# endif + while (req_index >= 0 && pp->p_ammo < shot_req[req_index]) + req_index--; + if (req_index < 0) { + 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 -= shot_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, + shot_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 +} + +# ifdef OOZE +/* + * fire_slime: + * Fire a slime shot in the given direction + */ +fire_slime(pp, req_index) +register PLAYER *pp; +register int req_index; +{ + if (pp == NULL) + return; +# ifdef DEBUG + if (req_index < 0 || req_index >= MAXSLIME) + message(pp, "What you do?"); +# endif + while (req_index >= 0 && pp->p_ammo < slime_req[req_index]) + req_index--; + if (req_index < 0) { + 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 -= slime_req[req_index]; + (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, + slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face); + pp->p_undershot = TRUE; + + /* + * 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 +} +# endif + +/* + * add_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; + register int size; + + switch (type) { + case SHOT: + case MINE: + size = 1; + break; + case GRENADE: + case GMINE: + size = 2; + break; + case SATCHEL: + size = 3; + break; + case BOMB: + for (size = 3; size < MAXBOMB; size++) + if (shot_req[size] >= charge) + break; + size++; + break; + default: + size = 0; + break; + } + + bp = create_shot(type, y, x, face, charge, size, owner, + (owner == NULL) ? NULL : owner->p_ident, expl, over); + bp->b_next = Bullets; + Bullets = bp; +} + +BULLET * +create_shot(type, y, x, face, charge, size, owner, score, expl, over) +int type; +int y, x; +char face; +int charge; +int size; +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_size = size; + 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; + } +# ifdef BOOTS + if (pp->p_nboots > 0) { + message(pp, "Boots are too noisy to cloak!"); + return; + } +# endif + (void) sprintf(Buf, "%3d", --pp->p_ammo); + cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); + outstr(pp, Buf, 3); + + pp->p_cloak += CLOAKLEN; + + if (pp->p_scan >= 0) + pp->p_scan = -1; + + 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; + + if (pp->p_cloak >= 0) + pp->p_cloak = -1; + + 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); + } +} |
