home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 7 Games / 07-Games.zip / VTREK.ZIP / SUB1.C < prev    next >
Text File  |  1989-12-26  |  15KB  |  736 lines

  1. /* sub1.c -- subroutines for visual star trek */
  2.  
  3. #include "vtrek.h"
  4.  
  5. #ifdef HI_TECH_C
  6. #define atan2 atan
  7. #endif
  8.  
  9. /* print short help information */
  10. help()
  11. {
  12.     if (rolines > 5)
  13.         readout(CLEAR, NULL);
  14.     readout(ADDLINE, "Directions = Q,W,E,A,D,Z,X,C");
  15.     readout(ADDLINE, "H = Hyper-space      S = Short range scan");
  16.     readout(ADDLINE, "L = Long range scan  P = Fire phasers");
  17.     readout(ADDLINE, "T = Fire torpedo     U = Defense control");
  18.     readout(ADDLINE, "R = Redraw screen    F = Fix devices");
  19. }
  20.  
  21. /* get command character */
  22. getcmd()
  23. {
  24.     int ch;
  25.     char str[40];
  26.  
  27.     sprintf(str, "Command, Captain %s ? ", captain);
  28.     prompt(str);
  29.  
  30.     ch = getch();
  31.  
  32.     return Toupper(ch);
  33. }
  34.  
  35. /* give option to see instructions */
  36. instructions()
  37. {
  38.     FILE *fp;
  39.     char line[80];
  40.     int n, ch;
  41.  
  42.     printf("Instructions ? ");
  43.  
  44.     /* This would seem to be a silly place to randomize,  but this */
  45.     /* location made things a bit easier for the CPM version. */
  46. #ifndef UNIX
  47.     /* if randomize is available then use it instead of this: */
  48.     while (!chready())
  49.         rnd(1);
  50. #else
  51.     randomize();
  52. #endif
  53.  
  54.     if (fgets(line, 80, stdin) == (char *)NULL)
  55.         vexit(0);
  56.     ch = Toupper(line[0]);
  57.     if (ch == 'Y') {
  58.         if ((fp = fopen(VTREKINS, "r")) == (FILE *)NULL)
  59.         printf("Error: Missing instruction file\n");
  60.         else {
  61.         terminit();
  62.         for (;;) {
  63.             cls();
  64.             for (n = 0; n < 22; n++) {
  65.             if (fgets(line, 80, fp) == (char *)NULL)
  66.                 break;
  67.             printf("%s", line);
  68. #ifdef UNIX
  69.             putchar('\r');
  70. #endif
  71.             }
  72.             if (n < 22)
  73.             break;
  74.             printf("--More--");
  75.             getch();
  76.         }
  77.         fclose(fp);
  78.         termreset();
  79.         }
  80.     }
  81. }
  82.  
  83. /* get captain's name and ship's name */
  84. getnames()
  85. {
  86.     int tmp;
  87.  
  88.     printf("Your name captain ? ");
  89.     if (fgets(captain, 11, stdin) == (char *)NULL)
  90.         vexit(1);
  91.     if (captain[tmp = strlen(captain) - 1] == '\n')
  92.         captain[tmp] = '\0';
  93.     else
  94.         while (getchar() != '\n');
  95.     if (*captain == '\0')
  96.         strcpy(captain, "Kirk");
  97.  
  98.     printf("Your ship's name captain ? ");
  99.     if (fgets(shipname, 11, stdin) == (char *)NULL)
  100.         vexit(1);
  101.     if (shipname[tmp = strlen(shipname) - 1] == '\n')
  102.         shipname[tmp] = '\0';
  103.     else
  104.         while (getchar() != '\n');
  105.     if (*shipname == '\0')
  106.         strcpy(shipname, "Enterprise");
  107. }
  108.  
  109. /* get skill level */
  110. getskill()
  111. {
  112.     char level[10];
  113.  
  114.     printf("Skill level (0-5, 0=easy, 5=hard) ? ");
  115.     if (fgets(level, 10, stdin) == (char *)NULL)
  116.         vexit(1);
  117.     if (isdigit(level[0]))
  118.         skill = level[0] - '0';
  119.     else
  120.         skill = 3;
  121. }
  122.  
  123. /* initialize galaxy */
  124. initgal()
  125. {
  126.     int i, j, k, r, n;
  127.  
  128.     numkling = 0;
  129.  
  130.     for (i = 0; i < 8; i++) {
  131.         for (j = 0; j < 8; j++) {
  132.         if ((r = rnd(100)) < 10)
  133.             k = 3;
  134.         else if (r < 20)
  135.             k = 2;
  136.         else if (r < 30)
  137.             k = 1;
  138.         else
  139.             k = 0;
  140.         numkling += k;
  141.         galaxy[i][j].nkling = k;
  142.         galaxy[i][j].nstar = rnd(8) + 1;
  143.         galaxy[i][j].nbase = 0;
  144.         galaxy[i][j].known = 0;
  145.         }
  146.     }
  147.  
  148.     numbases = rnd(3) + 2;
  149.  
  150.     for (n = 0; n < numbases; n++) {
  151.         for (;;) {
  152.         if (galaxy[i = rnd(7)][j = rnd(7)].nbase == 0) {
  153.             galaxy[i][j].nbase = 1;
  154.             break;
  155.         }
  156.         }
  157.     }
  158. }
  159.  
  160. /* initialize variables */
  161. initvars()
  162. {
  163.     int i;
  164.  
  165.     getnames();
  166.     getskill();
  167.     initgal();
  168.  
  169.     numkmove = skill;
  170.     begkling = numkling;
  171.     xquad = rnd(7);
  172.     yquad = rnd(7);
  173.     old_xsect = (xsect = rnd(7));
  174.     old_ysect = (ysect = rnd(7));
  175.     shields = 0;
  176.     energy = 3000;
  177.     stardate = 2000.0;
  178.     begdate = stardate;
  179.     lastdate = stardate + (float)numkling;
  180.     torps = 10;
  181.     playership[1] = *shipname;
  182.     condition = YELLOW;
  183.  
  184.     for (i = 0; i < 8; i++)
  185.         damage[i] = 100;
  186.     
  187.     old_xquad = -1;
  188.     old_yquad = -1;
  189.     setpos();
  190. }
  191.  
  192. /* set new position -- check for outside galaxy, set up new quadrant */
  193. setpos()
  194. {
  195.     int dam = 0, i, j, n, status = 0;
  196.     static int notfirstcall = 0;
  197.  
  198.     if (xsect > 7) {
  199.         xsect = 0;
  200.         xquad++;
  201.     }
  202.     else if (xsect < 0) {
  203.         xsect = 7;
  204.         xquad--;
  205.     }
  206.  
  207.     if (ysect > 7) {
  208.         ysect = 0;
  209.         yquad++;
  210.     }
  211.     else if (ysect < 0) {
  212.         ysect = 7;
  213.         yquad--;
  214.     }
  215.  
  216.     if (xquad > 7) {
  217.         dam = 1;
  218.         xquad = 7;
  219.         xsect = 7;
  220.     }
  221.     else if (xquad < 0) {
  222.         dam = 1;
  223.         xquad = 0;
  224.         xsect = 0;
  225.     }
  226.  
  227.     if (yquad > 7) {
  228.         dam = 1;
  229.         yquad = 7;
  230.         ysect = 7;
  231.     }
  232.     else if (yquad < 0) {
  233.         dam = 1;
  234.         yquad = 0;
  235.         ysect = 0;
  236.     }
  237.  
  238.     if (dam) {
  239.         readout(ADDLINE, "You encounter a force field.");
  240.         shields -= rnd(20) + 90;
  241.         plt_stat(ELEMENT, SHIELDS);
  242.         status = DAMAGE;
  243.         if (shields < 0)
  244.         die();
  245.     }
  246.  
  247.     if (xquad != old_xquad || yquad != old_yquad) {
  248.         galaxy[xquad][yquad].known = 1;
  249.         if (notfirstcall) {
  250.         plt_gal(ELEMENT, old_xquad, old_yquad);
  251.             plt_gal(ELEMENT, xquad, yquad);
  252.         }
  253.  
  254.         for (i = 0; i < 8; i++)
  255.         for (j = 0; j < 8; j++)
  256.             quadrant[i][j] = EMPTY;
  257.  
  258.         quadrant[xsect][ysect] = PLAYER;
  259.  
  260.         for (n = 0; n < galaxy[xquad][yquad].nkling; n++) {
  261.         for (;;) {
  262.             if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
  263.             quadrant[i][j] = KLINGON;
  264.             break;
  265.             }
  266.         }
  267.         klingon[n].xs = i;
  268.         klingon[n].ys = j;
  269.         klingon[n].sh = 200;
  270.         }
  271.  
  272.         for (; n < 3; n++)
  273.         klingon[n].xs = klingon[n].ys = klingon[n].sh = -1;
  274.  
  275.         for (n = 0; n < galaxy[xquad][yquad].nbase; n++)
  276.         for (;;) {
  277.             if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
  278.             quadrant[i][j] = STARBASE;
  279.             base_xsect = i;
  280.             base_ysect = j;
  281.             break;
  282.             }
  283.         }
  284.  
  285.         for (n = 0; n < galaxy[xquad][yquad].nstar; n++)
  286.         for (;;) {
  287.             if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
  288.             quadrant[i][j] = STAR;
  289.             break;
  290.             }
  291.         }
  292.  
  293.         old_xquad = xquad;
  294.         old_yquad = yquad;
  295.         if (notfirstcall) {
  296.             plt_srs(INFO);
  297.             plt_stat(ELEMENT, CONDITION);
  298.             plt_stat(ELEMENT, QUADRANT);
  299.             plt_gal(ELEMENT, xquad, yquad);
  300.         }
  301.     }
  302.     else {
  303.         switch (quadrant[xsect][ysect]) {
  304.  
  305.         case KLINGON:
  306.         dam = rnd(20) + 90;
  307.         if (damkling(xsect, ysect, dam) != DEAD) {
  308.             xsect = old_xsect;
  309.             ysect = old_ysect;
  310.         }
  311.         dam >>= 1;
  312.         if ((shields -= dam) < 0)
  313.             die();
  314.         fixdev(REL, RND, -dam);
  315.         plt_stat(ELEMENT, SHIELDS);
  316.         break;
  317.  
  318.         case STAR:
  319.         readout(ADDLINE, "There's a star in the way, Dunce!");
  320.         if (damage[SRS] > 0)
  321.             strcpy(captain, "Dunce");
  322.         xsect = old_xsect;
  323.         ysect = old_ysect;
  324.         break;
  325.  
  326.         case STARBASE:
  327.         xsect = old_xsect;
  328.         ysect = old_ysect;
  329.         readout(ADDLINE, "There's a star base in the way!");
  330.         break;
  331.         }
  332.  
  333.         status = quadrant[xsect][ysect];
  334.         quadrant[old_xsect][old_ysect] = EMPTY;
  335.         quadrant[xsect][ysect] = PLAYER;
  336.         plt_srs(ELEMENT, old_xsect, old_ysect);
  337.         plt_srs(ELEMENT, xsect, ysect);
  338.     }
  339.     old_xsect = xsect;
  340.     old_ysect = ysect;
  341.     if (notfirstcall)
  342.         plt_stat(ELEMENT, SECTOR);
  343.     notfirstcall = 1;
  344.  
  345.     return status;
  346. }
  347.  
  348. /* "So this is it.  We're going to die." -- Arthur Dent */
  349. die()
  350. {
  351.     plt_stat(ELEMENT, SHIELDS);
  352.     prompt("(Press RETURN)");
  353.     while (getch() != '\r')
  354.         ;
  355.     cls();
  356.     score(0);
  357.     moveyx(15, 21);
  358.     printf("Your ship the %s has been destroyed.", shipname);
  359.     moveyx(16, 21);
  360.     printf("The Federation will be conquered.\n\n\n\r");
  361.     vexit(0);
  362. }
  363.  
  364. win()
  365. {
  366.     readout(ADDLINE, "Congratulations!");
  367.     prompt("(Press RETURN)");
  368.     while (getch() != '\r')
  369.         ;
  370.     cls();
  371.     score(1);
  372.     moveyx(20,1);
  373.     printf("[Press Return]\n");
  374.     while (getch() != '\r')
  375.         ;
  376.     cls();
  377.     moveyx(11, 16);
  378.     printf("The last of the Klingon battle cruisers have been\n");
  379.     printf("%15sdestroyed.  You alone have saved the Federation.  You\n", "");
  380.     printf("%15sare promoted to Admiral %s !!!\n\n\n\r", "", captain);
  381.     vexit(0);
  382. }
  383.  
  384. /* random (?) number generator */
  385. rnd(max)
  386. int max;
  387. {
  388. #ifdef AZTEC
  389.     static long iy = 0x86A186A1;
  390.  
  391.     iy *= 125;
  392.     iy &= 0x7FFFFFFF;
  393.     iy %= 0xAAAAAAAd;
  394.  
  395.     return (int)((iy >> 8) % max);
  396. #else
  397.     return (int)(rand() % max);
  398. #endif
  399. }
  400.  
  401. #ifdef UNIX
  402. /* randomize */
  403. randomize()
  404. {
  405.     srand(time(0));
  406. }
  407. #endif
  408.  
  409. /* impulse drive -- move one sector */
  410. impulse(dir)
  411. int dir;
  412. {
  413.     int dx, dy, status;
  414.  
  415.     if (energy <= 0) {
  416.         readout(ADDLINE, "Insufficient energy for command.");
  417.         return ERROR;
  418.     }
  419.  
  420.     if (checkdir(dir, &dx, &dy) != ERROR) {
  421.         xsect += dx;
  422.         ysect += dy;
  423.     }
  424.  
  425.     energy--;
  426.     status = setpos();
  427.     plt_stat(ELEMENT, ENERGY);
  428.  
  429.     return status;
  430. }
  431.  
  432. /* defense -- set shield level */
  433. defense()
  434. {
  435.     if (damage[DEFENSE] <= 0)
  436.         readout(ADDLINE, "Defense control is damaged.");
  437.     else {
  438.         energy += shields;
  439.         for (;;) {    
  440.             prompt("Shield level ? ");
  441.             if ((shields = getnumb()) >= 0 && shields <= energy) {
  442.                 energy -= shields;
  443.             break;
  444.         }
  445.         }
  446.         if (shields > 0) {
  447.         playership[0] = '(';
  448.         playership[2] = ')';
  449.         }
  450.         else {
  451.         playership[0] = ' ';
  452.         playership[2] = ' ';
  453.         }
  454.         plt_srs(ELEMENT, xsect, ysect);
  455.         plt_stat(ELEMENT, SHIELDS);
  456.         plt_stat(ELEMENT, ENERGY);
  457.     }
  458. }
  459.  
  460. /* get a number */
  461. getnumb()
  462. {
  463.     int num = 0, ch;
  464.  
  465.     while ((ch = getch()) != '\r') {
  466.         putch(ch);
  467.         if (isdigit(ch))
  468.         num = num * 10 + ch - '0';
  469.         else if (ch == '\b') {
  470.         num = num / 10;
  471.         putch(' ');
  472.         putch('\b');
  473.         }
  474.         else
  475.         break;
  476.     }
  477.  
  478.     return num;
  479. }
  480.  
  481. /* damage a klingon */
  482. damkling(xs, ys, dam)
  483. int xs, ys, dam;
  484. {
  485.     char str[40];
  486.     int k;
  487.  
  488.     if ((k = findkling(xs, ys)) == ERROR)
  489.         readout(ADDLINE, "damkling: error");
  490.     else {
  491.         if (dam != AUTOKILL) {
  492.             sprintf(str, "You did %d to the Klingon.", dam);
  493.             readout(ADDLINE, str);
  494.         }
  495.  
  496.         if ((klingon[k].sh -= dam) < 0) {
  497.         readout(ADDLINE, "Klingon destroyed.");
  498.         klingon[k].xs = klingon[k].ys = -1;
  499.         quadrant[xs][ys] = EMPTY;
  500.         plt_srs(ELEMENT, xs, ys);
  501.         numkling--;
  502.         plt_num(INFO);
  503.         galaxy[xquad][yquad].nkling--;
  504.         plt_gal(ELEMENT, xquad, yquad);
  505.  
  506.         return DEAD;
  507.         }
  508.     }
  509.  
  510.     return ALIVE;
  511. }
  512.  
  513. /* fix/damage a device */
  514. fixdev(type, dev, value)
  515. int type;    /* ABSolution fix or RELative fix */
  516. int dev;    /* device (if RND then pick a damaged device) */
  517. int value;    /* new device value for ABS, amount to add for REL */
  518. {
  519.     int i, old_dam;
  520.  
  521.     if (dev == RND) {
  522.         dev = rnd(8);
  523.         if (value > 0 && damage[dev] >= 100) {
  524.         for (i = 0; i < 8; i++) {
  525.             if (++dev > 7)
  526.             dev = 0;
  527.             if (damage[dev] < 100)
  528.             break;
  529.         }
  530.         }
  531.     }
  532.  
  533.     old_dam = damage[dev];
  534.  
  535.     if (type == ABS)
  536.         damage[dev] = value;
  537.     else
  538.         damage[dev] += value;
  539.  
  540.     if (damage[dev] > 100)
  541.         damage[dev] = 100;
  542.  
  543.     plt_dam(ELEMENT, dev);
  544.  
  545.     /* see if device changed from fixed <==> broken */
  546.     if ((old_dam <= 0 && damage[dev] > 0) || (old_dam > 0 && damage[dev] <= 0)) {
  547.         switch (dev) {
  548.         case SRS :
  549.             plt_srs(INFO);
  550.             break;
  551.         case DAMAGE :
  552.             plt_dam(INFO);
  553.             break;
  554.         case COMPUTER :
  555.             plt_gal(INFO);
  556.             break;
  557.         }
  558.     }
  559. }
  560.  
  561. /* print a prompt in the upper left hand corner */
  562. prompt(str)
  563. char *str;
  564. {
  565.     int i;
  566.  
  567.     moveyx(1, 1);
  568.     for (i = 0; i < 26; i++)
  569.         putch(' ');
  570.     moveyx(1, 1);
  571.     printf("%-.26s", str);
  572. }
  573.  
  574. /* check a direction for validity and return delta-x and delta-y */
  575. checkdir(dir, dx, dy)
  576. int dir, *dx, *dy;
  577. {
  578.     static struct {
  579.         int d, x, y;
  580.     } dirs[8] = {
  581.         {'Q', -1, -1}, {'W', 0, -1}, {'E', 1, -1}, {'D', 1, 0},
  582.         {'C', 1, 1}, {'X', 0, 1}, {'Z', -1, 1}, {'A', -1, 0}
  583.     };
  584.     int i;
  585.  
  586.     for (i = 0; i < 8; i++)
  587.         if (dirs[i].d == dir) {
  588.         *dx = dirs[i].x;
  589.         *dy = dirs[i].y;
  590.         return 0;
  591.         }
  592.  
  593.     return ERROR;
  594. }
  595.  
  596. /* hyperspace drive */
  597. hyperspace()
  598. {
  599.     int dir, dx, dy, w, tmp, savex, savey;
  600.  
  601.     if (damage[WARP] <= 0)
  602.         readout(ADDLINE, "Warp engines are damaged.");
  603.     else {
  604.         prompt("Direction ? ");
  605.         if (islower(dir = getch()))
  606.         dir = toupper(dir);
  607.         if (checkdir(dir, &dx, &dy) == ERROR) {
  608.         readout(ADDLINE, "Illegal direction.");
  609.         return;
  610.         }
  611.  
  612.         prompt("Warp ? ");
  613.         putch(w = getch());
  614.         if (isdigit(w)) {
  615.         w -= '0';
  616.             if (w <= 0)
  617.             return;
  618.             savex = xsect;
  619.             savey = ysect;
  620.             while ((tmp = xsect + dx) >= 0 && tmp <= 7 && (tmp = ysect + dy) >= 0 && tmp <= 7) {
  621.             if (impulse(dir))
  622.                 return;
  623.             }
  624.             if (energy < 20 * w)
  625.             readout(ADDLINE, "Insufficient energy for command.");
  626.             else {
  627.                 xquad += w * dx;
  628.                 yquad += w * dy;
  629.                 energy -= 20 * w;
  630.             stardate += (double)(w) / 5.0;
  631.                 xsect = savex;
  632.                 ysect = savey;
  633.                 setpos();
  634.                 plt_stat(ELEMENT, ENERGY);
  635.             }
  636.         }
  637.         else if (w == '.' && isdigit(w = getch())) {
  638.         putch(w);
  639.         w -= '0';
  640.         stardate += (double)(w) / 50.0;
  641.         for (; w > 0; w--)
  642.             if (impulse(dir))
  643.             break;
  644.         }
  645.         else
  646.         readout(ADDLINE, "Illegal warp factor.");
  647.     }
  648. }
  649.  
  650. /* long range scan */
  651. lrs()
  652. {
  653.     int x, y;
  654.     char str[20];
  655.  
  656.     if (damage[LRS] <= 0)
  657.         readout(ADDLINE, "Long range sensors are damaged.");
  658.     else {
  659.         if (rolines > 3)
  660.         readout(CLEAR, NULL);
  661.  
  662.         for (y = yquad - 1; y <= yquad + 1; y++) {
  663.         readout(ADDLINE, "+---+---+---+");
  664.         strcpy(str, "|");
  665.         for (x = xquad - 1; x <= xquad + 1; x++) {
  666.             if (x < 0 || x > 7 || y < 0 || y > 7)
  667.             strcat(str, "XXX");
  668.             else {
  669.             if (damage[COMPUTER] > 0)
  670.                 galaxy[x][y].known = 1;
  671.             sprintf(str + strlen(str), "%d%d%d", galaxy[x][y].nkling,
  672.             galaxy[x][y].nbase, galaxy[x][y].nstar);
  673.             plt_gal(ELEMENT, x, y);
  674.             }
  675.             strcat(str, "|");
  676.         }
  677.         str[13] = '\0';
  678.         readout(ADDLINE, str);
  679.         }
  680.  
  681.         readout(ADDLINE, "+---+---+---+");
  682.         plt_gal(ELEMENT, xquad, yquad);
  683.     }
  684. }
  685.  
  686. /* short range scan */
  687. srs()
  688. {
  689.     int k, dx, dy;
  690.     double dir, dist;
  691.     char str[40];
  692.  
  693.     if (damage[SRS] <= 0)
  694.         readout(ADDLINE, "Short range sensors are damaged.");
  695.     else {
  696.         if (rolines > 6)
  697.         readout(CLEAR, NULL);
  698.         readout(ADDLINE, "Sector  Direction  Distance");
  699.         for (k = 0; k < 3; k++) {
  700.         if (klingon[k].sh >= 0) {
  701.             if (damage[COMPUTER] <= 0)
  702.             sprintf(str, "[%d,%d]", klingon[k].xs+1, klingon[k].ys+1);
  703.             else {
  704.             dx = klingon[k].xs - xsect;
  705.             dy = klingon[k].ys - ysect;
  706.             dist = sqrt((double)(dx*dx) + (double)(dy*dy));
  707.             if (dx) {
  708.                 dir = atan2(-(double)dy, (double)dx) * 180.0 / PI;
  709.                 if (dir < 0.0)
  710.                 dir += 360.0;
  711.             }
  712.             else if (dy > 0)
  713.                 dir = 270.0;
  714.             else
  715.                 dir = 90.0;
  716.             sprintf(str, "[%d,%d]     %5.1f      %4.1f", klingon[k].xs+1,
  717.             klingon[k].ys+1, dir, dist);
  718.             }
  719.             readout(ADDLINE, str);
  720.         }
  721.         }
  722.     }
  723. }
  724.  
  725. findkling(x, y)
  726. int x, y;
  727. {
  728.     int i;
  729.  
  730.     for (i = 0; i < 3; i++)
  731.         if (x == klingon[i].xs && y == klingon[i].ys)
  732.         return i;
  733.  
  734.     return ERROR;
  735. }
  736.