home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / y / bsdgames / bsd-game.000 / bsd-game / games / hunt / execute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-21  |  9.4 KB  |  557 lines

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