home *** CD-ROM | disk | FTP | other *** search
/ Adventures in Heaven 2 / adventuresinheaven2powergamesfordosandwindows.iso / windows / arcade / cbzone / c_move.c < prev    next >
C/C++ Source or Header  |  1992-05-27  |  19KB  |  742 lines

  1. #include "c_includ.h"
  2. /*
  3.  * cbzone_move.c
  4.  *  -- Todd W Mummert, December 1990, CMU
  5.  *
  6.  * RCS Info
  7.  *  $Header: c_move.c,v 1.1 91/01/12 02:03:35 mummert Locked $
  8.  *
  9.  * This file is largely based on the Fortran source by
  10.  * Justin S Revenaugh.  I've added the necessary information
  11.  * to handle multiple objects in placeobjects, but that's
  12.  * about it.  Moved any variables that were controlling
  13.  * an object that had to be static into the Generic structure.
  14.  */
  15.  
  16. void placeobjects(o, missilerun, score)
  17.      Genericp o;
  18.      Bool missilerun;
  19.      LONG score;
  20. {
  21.   static int lander = 1000;
  22.   static int landercount = 0;
  23.   static struct timeval clock = {0, 40000};
  24.   float odds, scale, r, dazm, ca, sa;
  25.   Genericp g;
  26.   Genericp pl = o;
  27.   int nta = 0;
  28.   int nsu = 0;
  29.   int nmi = 0;
  30.   int nco = 0;
  31.   int nla = 0;
  32.  
  33.   landercount++;
  34.   for (g=o; g<o+opt->mobjects; g++)
  35.     if (g->attr & STILL_THERE)
  36.       switch (g->type) {
  37.       case IS_TANK:
  38.         nta++; break;
  39.       case IS_SUPER:
  40.         nsu++; break;
  41.       case IS_MISSILE:
  42.         nmi++; break;
  43.       case IS_COPTER:
  44.         nco++; break;
  45.       case IS_LANDER:
  46.         nla++; break;
  47.       }
  48.  
  49.   if (pl->attr & IS_ALIVE &&
  50.       (missilerun && nta + nsu == 0 && nmi + nco < opt->mmissiles ||
  51.        !missilerun && nmi + nco == 0 && nta + nsu < opt->mtanks)) {
  52.     for (g=o+opt->estart; g<o+opt->lstart; g++)
  53.       if (!(g->attr & STILL_THERE))
  54.         break;
  55.     if (g == o+opt->lstart) {
  56.       printf("Help! Did not have space available for enemy!\n");
  57.       printf("Should not have been possible.\n");
  58. #ifdef WIN32
  59.       return;
  60. #else //X11
  61.       exit(1);
  62. #endif
  63.     }
  64.  
  65.     if (missilerun) {
  66.       /* reset clock usec just in case they change select to return the
  67.          amount of time remaining after the select finishes.   The
  68.          man page mentions this might occur in future releases.
  69.        */
  70.       tonetime();
  71.       clock.tv_usec = 40000;
  72.       select(0, 0, 0, 0, &clock);
  73.       tonetime();
  74.       clock.tv_usec = 40000;
  75.       select(0, 0, 0, 0, &clock);
  76.       tonetime();
  77.       odds = score / 500000.0;
  78.       if (score < 75000)
  79.         odds = 0.0;
  80.       if (odds > 0.333)
  81.         odds = 0.333;
  82.       if (opt->copters || frand() < odds) {
  83.         g->type = IS_COPTER;
  84.         g->lntype = LN_COPTER;
  85.         scale = 0.2;
  86.         g->z = 150.0;
  87.         r = 1900;
  88.       }
  89.       else {
  90.         g->type = IS_MISSILE;
  91.         g->lntype = LN_MISSILE;
  92.         scale = 0.1;
  93.         g->z = 250.0;
  94.         r = 1750;
  95.       }
  96.       dazm = frand() * scale;
  97.       if (frand() > 0.5)
  98.         dazm = - dazm;
  99.       dazm += pl->azm;
  100.       ca = cos(dazm);
  101.       sa = sin(dazm);
  102.       g->x = pl->x - r * sa;
  103.       g->y = pl->y + r * ca;
  104.       g->attr = START_LIVING;
  105.       dazm = frand() * 0.015 / scale;
  106.       if (frand() > 0.5)
  107.         dazm = - dazm;
  108.       g->azm = pl->azm - PI + dazm;
  109.     }
  110.     else {
  111.       odds = (60000.0 - score) / 30000.0;
  112.       if (odds < 0.10)
  113.         odds = 0.10;
  114.       if (frand() < odds) {
  115.         g->type = IS_TANK;
  116.         g->lntype = LN_TANK;
  117.       }
  118.       else {
  119.         g->type = IS_SUPER;
  120.         g->lntype = LN_SUPER;
  121.       }
  122.       r = 800.0 + 1200.0 * frand();
  123.       dazm = frand() * PI2;
  124.       g->x = pl->x + r * cos(dazm);
  125.       g->y = pl->y + r * sin(dazm);
  126.       g->z = 0.0;
  127.       g->azm = frand() * PI2;
  128.       g->attr = START_LIVING;
  129.     }
  130.     g->criticalx = 45.0;
  131.     g->criticaly = 70.0;
  132.   }
  133.  
  134.   if (landercount > lander && nla < opt->mlanders) {
  135.     for (g=o+opt->lstart; g<o+opt->sstart; g++)
  136.       if (!(g->attr & STILL_THERE))
  137.         break;
  138.     if (g == o+opt->sstart) {
  139.       printf("Help! Did not have space available for lander!\n");
  140.       printf("Should not have been possible.\n");
  141. #ifdef WIN32
  142.       return;
  143. #else //X11
  144.       exit(1);
  145. #endif
  146.     }
  147.  
  148.     r = 1500.0 + 500.0 * frand();
  149.     dazm = frand() * PI2;
  150.     g->x = pl->x + r * cos(dazm);
  151.     g->y = pl->y + r * sin(dazm);
  152.     g->z = 0.0;
  153.     g->azm = frand() * PI2;
  154.     g->speed = frand() * 10.0;
  155.     g->criticalx = g->criticaly = 6400.0;
  156.     g->type = IS_LANDER;
  157.     g->lntype = LN_LANDER;
  158.     g->attr = START_LIVING;
  159.   }
  160.  
  161.   for (g=o+opt->bstart; g<o+opt->mobjects; g++)
  162.     if (!(g->attr & IS_ALIVE)) {
  163.       if (frand() > 0.5) {
  164.         g->type = IS_CUBE;
  165.         g->lntype = LN_CUBE;
  166.         g->criticalx = g->criticaly = 50.0;
  167.       }
  168.       else {
  169.         g->type = IS_PYRAMID;
  170.         g->lntype = LN_PYRAMID;
  171.         g->criticalx = g->criticaly = 35.0;
  172.       }
  173.       g->attr = START_LIVING;
  174.       if (pl->attr & IS_NEW)
  175.         r = 400 + frand() * 1800.0;
  176.       else
  177.         r = 2000.0;
  178.       dazm = frand() * PI2;
  179.       g->x = pl->x + r * cos(dazm);
  180.       g->y = pl->y + r * sin(dazm);
  181.       g->z = 0.0;
  182.     }
  183. }
  184.  
  185. void movesuper(g, pl)
  186.      Genericp g;
  187.      Genericp pl;
  188. {
  189.   int i;
  190.   float dx, dy, tazm, t1, t3, scrot, sctot, scale, cp, sp, dcp;
  191.   float dsp, cm, sm, xmt, ymt, xpt, ypt, rate, temp, dist;
  192.   Genericp s;
  193.  
  194.   g->pcount++;
  195.   g->fcount++;
  196.   if (g->attr & IS_NEW) {
  197.     g->attr &=  ~(IS_NEW | IS_PRESET);
  198.     g->bcount = 0;
  199.     g->ecount = 0;
  200.     g->pcount = 10;
  201.     g->fcount = 15;
  202.     g->orientation = 1.0;
  203.   }
  204.   if (g->attr & IS_BLOCKED && g->attr & LAST_BLOCKED)
  205.     g->orientation = -g->orientation;
  206.   g->attr &= ~LAST_BLOCKED;
  207.  
  208.   if (g->attr & IS_BLOCKED) {
  209.     if (g->attr & BLOCKED_BY_ENEMY)
  210.       g->attr |= IS_EVADING;
  211.     else
  212.       g->attr &= ~IS_EVADING;
  213.     g->attr |= IS_PRESET | LAST_BLOCKED;
  214.     g->bcount  = 0;
  215.   }
  216.   if (g->attr & IS_PRESET) {
  217.     g->bcount++;
  218.     if (!(g->attr & IS_EVADING)) {
  219.       if (g->bcount == 1) {
  220.         g->speed = -12.0 * g->orientation;
  221.         g->rotate = 0.045;
  222.         if (frand() > 0.5)
  223.           g->rotate = -g->rotate;
  224.       }
  225.       else if (g->bcount == 30) {
  226.         g->speed  = 12.0 * g->orientation;
  227.         g->rotate = 0.0;
  228.       }
  229.       else if (g->bcount > 60)
  230.         g->attr &= ~IS_PRESET;
  231.     }
  232.     else {
  233.       if (g->bcount == 1) {
  234.         g->speed  = -12.0 * g->orientation;
  235.         g->rotate = 0.0;
  236.       }
  237.       else if (g->bcount == 10 || g->bcount == 15 ||
  238.                g->bcount == 20 || g->bcount == 25) {
  239.         dx = pl->x - g->x;
  240.         dy = pl->y - g->y;
  241.         if (fabs(dy) < 1.e-7)
  242.           dy = sign(1.e-7, dy);
  243.         if (dy <= 0.0)
  244.           tazm = - atan(dx / dy) + ra (180.0);
  245.         else
  246.           tazm = - atan(dx / dy) ;
  247.         if (g->azm > PI2)
  248.           g->azm -= PI2;
  249.         if (g->azm < 0.0)
  250.           g->azm += PI2;
  251.         t1 = (tazm - g->azm) / 5.0;
  252.         t3 = (tazm - (g->azm - PI2)) / 5.0;
  253.         if (fabs(t3) < fabs(t1))
  254.           t1 = t3;
  255.         if (fabs(t1) > 0.045)
  256.           t1 = sign (.045, t1);
  257.         g->rotate = t1;
  258.         g->speed = 0.0;
  259.       }
  260.       else if (g->bcount > 30)
  261.         g->attr &= ~IS_PRESET;
  262.     }
  263.   }
  264.   else if (g->pcount >= 5) {
  265.     g->orientation = 1.0;
  266.     g->pcount = 0;
  267.     dx = pl->x - g->x;
  268.     dy = pl->y - g->y;
  269.     if (fabs(dy) < 1.e-7) dy =
  270.       sign(1.e-7, dy);
  271.     if (dy <= 0.0)
  272.       tazm = - atan(dx / dy) + ra (180.0);
  273.     else
  274.       tazm = - atan(dx / dy);
  275.     if (g->azm > PI2)
  276.       g->azm -= PI2;
  277.     if (g->azm < 0.0)
  278.       g->azm += PI2;
  279.     t1 = (tazm - g->azm) / 5.0;
  280.     t3 = (tazm - (g->azm - PI2)) / 5.0;
  281.     if (fabs(t3) < fabs(t1))
  282.       t1 = t3;
  283.     g->speed = 12.0 * (PI - fabs(t1) * 5.0) / PI;
  284.     if (fabs(t1) > 0.045)
  285.       t1 = sign (0.045, t1);
  286.     g->rotate = t1;
  287.   }
  288.  
  289.   scrot = g->rotate / 0.045 * 12.0;
  290.   sctot = sqrt (g->speed*g->speed + scrot*scrot);
  291.   if (sctot > 12.0) {
  292.     scale = 12.0 / sctot;
  293.     g->speed *= scale;
  294.     g->rotate *= scale;
  295.   }
  296.  
  297.   s = g->salvo;
  298.   if (pl->attr & IS_ALIVE && g->fcount>10 && g->ecount>50 &&
  299.       !(s->attr & STILL_THERE)) {
  300.     g->fcount = 0;
  301.     cp = pl->ca;
  302.     sp = pl->sa;
  303.     dcp = cos(pl->rotate);
  304.     dsp = sin(pl->rotate);
  305.     cm = cos(g->azm);
  306.     sm = sin(g->azm);
  307.     i = 0;
  308.     xmt = g->x;
  309.     ymt = g->y;
  310.     xpt = pl->x;
  311.     ypt = pl->y;
  312.     rate = 40.0;
  313.  
  314.     for (i=0; i<50; i++) {
  315.       temp = cp;
  316.       cp = cp * dcp - sp * dsp;
  317.       sp = sp * dcp + dsp * temp;
  318.       xmt -= sm * rate;
  319.       ymt += cm * rate;
  320.       xpt -= sp * pl->speed;
  321.       ypt += cp * pl->speed;
  322.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  323.       if (dist <= BMS_TOL) {
  324.         s->attr = START_LIVING;
  325.         s->x = g->x;
  326.         s->y = g->y;
  327.         s->z = 0.0;
  328.         s->prox = g->prox;
  329.         s->proy = g->proy;
  330.         s->azm = g->azm;
  331.         s->speed = 40.0;
  332.         s->ecount = 0;
  333.         message(3, True);
  334.         break;
  335.       }
  336.     }
  337.   }
  338. }
  339.  
  340. void movemissile(g, pl, first)
  341.      Genericp g;
  342.      Genericp pl;
  343.      Bool first;
  344. {
  345.   float dx, dy, tazm, t1, t3, dt1, t2;
  346.  
  347.   if (g->attr & IS_NEW) {
  348.     g->ecount = 0;
  349.     g->pcount = 0;
  350.     g->attr &= ~IS_NEW;
  351.   }
  352.  
  353.   g->rotate = 0.0;
  354.   g->pcount++;
  355.   g->z -= 25.0;
  356.   if (g->z <= 0.0)
  357.     g->z = 0.0;
  358.   if (g->attr & IS_BLOCKED)
  359.     g->z = 90.0;
  360.   g->speed = 35.0;
  361.   if (g->z > 91.0)
  362.     g->speed = 0.0;
  363.   if (g->pcount >= 12) {
  364.     g->pcount = 0;
  365.     if (g->proy > 60.0) {
  366.       dx = pl->x - g->x;
  367.       dy = pl->y - g->y;
  368.       if (fabs(dy) < 1.e-7)
  369.         dy = sign(1.e-7, dy);
  370.       if (dy <= 0.0)
  371.         tazm = - atan(dx / dy) + ra (180.0);
  372.       else
  373.         tazm = - atan(dx / dy);
  374.       if (g->azm > PI2)
  375.         g->azm -= PI2;
  376.       if (g->azm < 0.0)
  377.         g->azm += PI2;
  378.       t1 = (tazm - g->azm);
  379.       t3 = (tazm - (g->azm - PI2));
  380.       if (fabs(t3) < fabs(t1))
  381.         t1 = t3;
  382.       if (!first) {
  383.         dt1 = frand() * 0.5;
  384.         dt1 = sign (dt1, t1);
  385.         if (frand() > 0.8)
  386.           dt1 = - dt1;
  387.         t1 += dt1;
  388.       }
  389.       if (fabs(t1) > 0.90)
  390.         t1 = sign (0.90, t1);
  391.       g->rotate = t1;
  392.     }
  393.     else {
  394.       tazm = pl->azm - PI;
  395.       if (tazm < 0.0)
  396.         tazm += PI2;
  397.       if (tazm > PI2)
  398.         tazm -= PI2;
  399.       if (g->azm < 0.0)
  400.         g->azm += PI2;
  401.       if (g->azm > PI2)
  402.         g->azm -= PI2;
  403.       t1 = (tazm - g->azm);
  404.       t2 = (tazm - (g->azm - PI2));
  405.       if (fabs(t2) < fabs(t1))
  406.         t1 = t2;
  407.       if (fabs(t1) > 0.90)
  408.         t1 = sign (0.90, t1);
  409.       g->rotate = t1;
  410.     }
  411.   }
  412. }
  413.  
  414. void movecopter(g, pl)
  415.      Genericp g;
  416.      Genericp pl;
  417. {
  418.   float dx, dy, tazm, t1, t2, t3, cp, sp, dcp, dsp, cm, sm;
  419.   float xmt, ymt, xpt, ypt, rate, temp, dist;
  420.   int i;
  421.   Genericp s;
  422.  
  423.   g->pcount++;
  424.   if (!(pl->attr & IS_ALIVE)) {
  425.     g->pcount = 0;
  426.     g->attr &= ~CAN_SHOOT;
  427.   }
  428.  
  429.   if (g->attr & IS_NEW) {
  430.     g->pcount = 10;
  431.     g->ecount = 0;
  432.     g->attr |= CAN_SHOOT;
  433.     g->attr &= ~IS_NEW;
  434.     if (frand() > 0.5)
  435.       g->orientation = PI / 2.0;
  436.     else
  437.       g->orientation = -PI / 2.0;
  438.   }
  439.  
  440.   s = g->salvo;
  441.   if (g->ecount < 150 && g->range > 400.0)
  442.     if (!(s->attr & STILL_THERE))
  443.       g->z -= 5.0;
  444.     else
  445.       g->z += 5.0;
  446.   else
  447.     g->z += 5.0;
  448.  
  449.   if (g->z <= 40.0)
  450.     g->z = 40.0;
  451.   if (g->z > 150.0)
  452.     g->z = 150.0;
  453.   if (g->attr & IS_BLOCKED && g->z < 90.0) {
  454.     g->z = 90.0;
  455.     g->attr &= ~IS_BLOCKED;
  456.   }
  457.  
  458.   g->speed = 20.0;
  459.   if (g->pcount >= 10) {
  460.     g->pcount = 0;
  461.     if (g->range > 400.0 && g->ecount < 150) {
  462.       dx = pl->x - g->x;
  463.       dy = pl->y - g->y;
  464.       if (fabs(dy) < 1.e-7)
  465.         dy = sign(1.e-7, dy);
  466.       if (dy <= 0.0)
  467.         tazm = - atan(dx / dy) + ra (180.0);
  468.       else
  469.         tazm = - atan(dx / dy);
  470.       if (g->azm > PI2)
  471.         g->azm -= PI2;
  472.       if (g->azm < 0.0)
  473.         g->azm += PI2;
  474.       t1 = (tazm - g->azm) / 10.0;
  475.       t3 = (tazm - (g->azm - PI2)) /10.0;
  476.       if (fabs(t3) < fabs(t1))
  477.         t1 = t3;
  478.       if (fabs(t1) > 0.06)
  479.         t1 = sign (0.06, t1);
  480.       g->rotate = t1;
  481.     }
  482.     else {
  483.       tazm = g->orientation;
  484.       if (tazm < 0.0)
  485.         tazm += PI2;
  486.       if (tazm > PI2)
  487.         tazm -= PI2;
  488.       if (g->azm < 0.0)
  489.         g->azm += PI2;
  490.       if (g->azm > PI2)
  491.         g->azm -= PI2;
  492.       t1 = (tazm - g->azm) / 10.0;
  493.       t2 = (tazm - (g->azm - PI2)) / 10.0;
  494.       if (fabs(t2) < fabs(t1))
  495.         t1 = t2;
  496.       if (fabs(t1) > 0.06)
  497.         t1 = sign (0.06, t1);
  498.       g->rotate = t1;
  499.       g->speed = 30.0;
  500.     }
  501.   }
  502.  
  503.   if (g->attr & CAN_SHOOT && g->z < 50.0 &&
  504.       !(s->attr & STILL_THERE)) {
  505.     /*
  506.      * the original Fortran had the following
  507.      *    sp = pl->sa     and    cp = pl->ca
  508.      *
  509.      * however, sa and ca were undefined...fortran was really good
  510.      * about making these 0, C doesn't guarantee this will occur.
  511.      * the two choices to fix this are to make sp and cp
  512.      * 0 initially or to make them the sin/cos of azm.
  513.      * the first method makes the copter fire as it hits
  514.      * the ground, the second method the copter won't fire
  515.      * until it is very close unless you are moving straight
  516.      * toward it or straight away from it.
  517.      */
  518.     cp = sp = 0;
  519.     dcp = cos(pl->rotate);
  520.     dsp = sin(pl->rotate);
  521.     cm = cos(g->azm);
  522.     sm = sin(g->azm);
  523.     xmt = g->x;
  524.     ymt = g->y;
  525.     xpt = pl->x;
  526.     ypt = pl->y;
  527.     rate = 40.0;
  528.  
  529.     for (i=0; i<50; i++) {
  530.       temp = cp;
  531.       cp = cp * dcp - sp * dsp;
  532.       sp = sp * dcp + dsp * temp;
  533.       xmt -= sm * rate;
  534.       ymt += cm * rate;
  535.       xpt -= sp * pl->speed;
  536.       ypt += cp * pl->speed;
  537.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  538.       if (dist <= BMC_TOL) {
  539.         s->attr = START_LIVING;
  540.         s->x = g->x;
  541.         s->y = g->y;
  542.         s->z = 0.0;
  543.         s->prox = g->prox;
  544.         s->proy = g->proy;
  545.         s->azm = g->azm;
  546.         s->speed = 40.0;
  547.         s->ecount = 0;
  548.         message(3, True);
  549.         break;
  550.       }
  551.     }
  552.   }
  553. }
  554.  
  555. void movetank(g, pl)
  556.      Genericp g;
  557.      Genericp pl;
  558. {
  559.   int i;
  560.   float dx, dy, tazm, t1, t3, scrot, sctot, scale, cp, sp, dcp;
  561.   float dsp, cm, sm, xmt, ymt, xpt, ypt, rate, temp, dist;
  562.   Genericp s;
  563.  
  564.   g->pcount++;
  565.   g->fcount++;
  566.   if (g->attr & IS_NEW) {
  567.     g->attr &= ~(IS_NEW | IS_PRESET);
  568.     g->bcount = 0;
  569.     g->ecount = 0;
  570.     g->pcount = 5;
  571.     g->fcount = 5;
  572.     g->orientation = 1.0;
  573.   }
  574.   if (g->attr & IS_BLOCKED && g->attr & LAST_BLOCKED)
  575.     g->orientation = -g->orientation;
  576.   g->attr &= ~LAST_BLOCKED;
  577.  
  578.   if (g->attr & IS_BLOCKED) {
  579.     if (g->attr & BLOCKED_BY_ENEMY)
  580.       g->attr |= IS_EVADING;
  581.     else
  582.       g->attr &= ~IS_EVADING;
  583.     g->attr |= IS_PRESET | LAST_BLOCKED;
  584.     g->bcount  = 0;
  585.   }
  586.  
  587.   if (g->attr & IS_PRESET) {
  588.     g->bcount++;
  589.     if (!(g->attr & IS_EVADING)) {
  590.       if (g->bcount == 1) {
  591.         g->speed = -8.0 * g->orientation;
  592.         g->rotate = 0.030;
  593.         if (frand() > 0.5)
  594.           g->rotate = -g->rotate;
  595.       }
  596.       else if (g->bcount == 45) {
  597.         g->speed  = 8.0 * g->orientation;
  598.         g->rotate = 0.0;
  599.       }
  600.       else if (g->bcount > 90)
  601.         g->attr &= ~IS_PRESET;
  602.     }
  603.     else {
  604.       if (g->bcount == 1) {
  605.         g->speed  = -8.0 * g->orientation;
  606.         g->rotate = 0.0;
  607.       }
  608.       else if (g->bcount == 10 || g->bcount == 15 ||
  609.                g->bcount == 20 || g->bcount == 25) {
  610.         dx = pl->x - g->x;
  611.         dy = pl->y - g->y;
  612.         if (fabs(dy) < 1.e-7)
  613.           dy = sign(1.e-7, dy);
  614.         if (dy <= 0.0)
  615.           tazm = - atan(dx / dy) + ra (180.0);
  616.         else
  617.           tazm = - atan(dx / dy) ;
  618.         if (g->azm > PI2)
  619.           g->azm -= PI2;
  620.         if (g->azm < 0.0)
  621.           g->azm += PI2;
  622.         t1 = (tazm - g->azm) / 5.0;
  623.         t3 = (tazm - (g->azm - PI2)) / 5.0;
  624.         if (fabs(t3) < fabs(t1))
  625.           t1 = t3;
  626.         if (fabs(t1) > 0.030)
  627.           t1 = sign (.030, t1);
  628.         g->rotate = t1;
  629.         g->speed = 0.0;
  630.       }
  631.       else if (g->bcount > 30)
  632.         g->attr &= ~IS_PRESET;
  633.     }
  634.   }
  635.   else if (g->pcount >= 10) {
  636.     g->orientation = 1.0;
  637.     g->pcount = 0;
  638.     dx = pl->x - g->x;
  639.     dy = pl->y - g->y;
  640.     if (fabs(dy) < 1.e-7)
  641.       dy = sign(1.e-7, dy);
  642.     if (dy <= 0.0)
  643.       tazm = - atan(dx / dy) + ra (180.0);
  644.     else
  645.       tazm = - atan(dx / dy);
  646.     if (g->azm > PI2)
  647.       g->azm -= PI2;
  648.     if (g->azm < 0.0)
  649.       g->azm += PI2;
  650.     t1 = (tazm - g->azm) / 10.0;
  651.     t3 = (tazm - (g->azm - PI2)) / 10.0;
  652.     if (fabs(t3) < fabs(t1))
  653.       t1 = t3;
  654.     g->speed = 8.0 * (PI - fabs(t1) * 10.0) / PI;
  655.     if (fabs(t1) > 0.030)
  656.       t1 = sign (0.030, t1);
  657.     g->rotate = t1;
  658.   }
  659.  
  660.   scrot = g->rotate / 0.030 * 8.0;
  661.   sctot = sqrt (g->speed*g->speed + scrot*scrot);
  662.   if (sctot > 8.0) {
  663.     scale = 8.0 / sctot;
  664.     g->speed *= scale;
  665.     g->rotate *= scale;
  666.   }
  667.  
  668.   s = g->salvo;
  669.   if (pl->attr & IS_ALIVE && g->fcount>10 && g->ecount>100 &&
  670.       !(s->attr & STILL_THERE)) {
  671.     g->fcount = 0;
  672.     cp = pl->ca;
  673.     sp = pl->sa;
  674.     dcp = cos(pl->rotate);
  675.     dsp = sin(pl->rotate);
  676.     cm = cos(g->azm);
  677.     sm = sin(g->azm);
  678.     i = 0;
  679.     xmt = g->x;
  680.     ymt = g->y;
  681.     xpt = pl->x;
  682.     ypt = pl->y;
  683.     rate = 40.0;
  684.  
  685.     for (i=0; i<50; i++) {
  686.       temp = cp;
  687.       cp = cp * dcp - sp * dsp;
  688.       sp = sp * dcp + dsp * temp;
  689.       xmt -= sm * rate;
  690.       ymt += cm * rate;
  691.       xpt -= sp * pl->speed;
  692.       ypt += cp * pl->speed;
  693.       dist = (xpt-xmt)*(xpt-xmt) + (ymt-ypt)*(ymt-ypt);
  694.       if (dist <= BMT_TOL) {
  695.         s->attr = START_LIVING;
  696.         s->x = g->x;
  697.         s->y = g->y;
  698.         s->z = 0.0;
  699.         s->prox = g->prox;
  700.         s->proy = g->proy;
  701.         s->azm = g->azm;
  702.         s->speed = 40.0;
  703.         s->ecount = 0;
  704.         message(3, True);
  705.         break;
  706.       }
  707.     }
  708.   }
  709. }
  710.  
  711. void movelander(g, pl)
  712.      Genericp g;
  713.      Genericp pl;
  714. {
  715.   float dx, dy, theta;
  716.  
  717.   if (++g->pcount > 20) {
  718.     g->pcount = 0;
  719.  
  720.     if (g->range <= 750.0) {
  721.       dx = g->x - pl->x;
  722.       dy = g->y - pl->y;
  723.       theta = atan (dy / (fabs(dx) + 1.0));
  724.       if (dx <= 0.0)
  725.         theta = PI - theta;
  726.       /* the original fortran went to all the trouble of calculating
  727.        * theta above, but never used it.  perhaps the following
  728.        * statement was left out.
  729.        */
  730.       g->azm = theta;
  731.     }
  732.  
  733.     if (frand() >= 0.5) {
  734.       g->azm += frand() * PI / 4.0;
  735.     }
  736.     else {
  737.       g->azm -= frand() * PI / 4.0;
  738.     }
  739.     g->speed = frand() * 20.0;
  740.   }
  741. }
  742.