home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume6 / gb / part01 / doship.c < prev    next >
C/C++ Source or Header  |  1989-07-06  |  13KB  |  373 lines

  1. /*
  2.  * Galactic Bloodshed (Robert Chansky, smq@b)
  3.  * doship -- do one ship turn.
  4.  */
  5.  
  6. #include "vars.h"
  7. #include "ships.h"
  8. #include "races.h"
  9. #include "doturn.h"
  10. #include "power.h"
  11. #include <math.h>
  12. extern struct power Power[];
  13.  
  14. extern int Ignore_lockfile;
  15.  
  16. doship(shipno,ship)
  17. int shipno;
  18. shiptype *ship;
  19. {
  20.  int j,t;
  21.  char buf[200];
  22.  
  23.  if (!ship->is_dead) {
  24.  
  25.         /* add ships, popn to total count to add AP's */
  26.     Power[ship->owner].ships_owned++;
  27.     Power[ship->owner].resource += ship->resource;
  28.     Power[ship->owner].fuel += ship->fuel;
  29.     Power[ship->owner].destruct += ship->destruct;
  30.     Power[ship->owner].popn += ship->popn;
  31.     if (ship->whatorbits==LEVEL_UNIV) {
  32.          Sdatanumships[ship->owner]++;
  33.          Sdatapopns[ship->owner] += ship->popn;
  34.     } else {
  35.         starnumships[ship->storbits][ship->owner] += (ship->type==OTYPE_VN) ? ship->orders.object.number : 1;
  36.             /* add popn of ships to popn */
  37.             starpopns[ship->storbits][ship->owner] += ship->popn;
  38.     }
  39.  
  40.         /* repair radiation */
  41.       if (ship->rad) {
  42.             /* kill off some people */
  43.         ship->popn = round_rand(ship->popn * .80);
  44.         if (ship->rad > REPAIR_RATE)
  45.             ship->rad = 0;
  46.         else
  47.             ship->rad -= REPAIR_RATE;
  48.       } else {
  49.         /* irradiated ships are immobile */
  50.  
  51.     Moveship(shipno, ship, Stars[ship->storbits],
  52.         Stars[ship->deststar],
  53.         planets[ship->storbits][ship->pnumorbits],
  54.         planets[ship->deststar][ship->destpnum],
  55.         ships[ship->destshipno]);
  56.     
  57.         /* repair ship by the amount of crew it has */
  58.     if (ship->damage && ship->popn) { reg int d;
  59.         if ((d = ((float)ship->popn / 
  60.             Shipdata[ship->type][ABIL_MAXCREW]) * REPAIR_RATE)
  61.             > ship->damage)
  62.            ship->damage = 0;
  63.         else
  64.            ship->damage -= d;
  65.     }
  66.  
  67.      switch (ship->type) {
  68.  
  69.       case OTYPE_CANIST:
  70.        if (ship->whatorbits == LEVEL_PLAN && !ship->is_docked) { char *t;
  71.           if (--ship->orders.object.number) {
  72.           t = &Stinfo[ship->storbits][ship->pnumorbits].temp_add;
  73.           if (*t - 10 < -120)
  74.             *t = -120;
  75.           else
  76.             *t -= 10;
  77.           } else {    /* timer expired; destroy canister */
  78.            int fd,j=0;
  79.           ship->is_dead = 1;
  80.           while (j<MAXPSHIPS && planets[ship->storbits][ship->pnumorbits]->shipnums[j] != shipno)
  81.             j++;
  82.           if (j<MAXPSHIPS) {
  83.              planets[ship->storbits][ship->pnumorbits]->shipnums[j] = 0;
  84.                openshfdata(&fd); destroyship(fd,shipno); close(fd);
  85.                teleg_add("",telegram_buf);
  86.                sprintf(buf,"Notice from /%s/%s\n\n", 
  87.                Stars[ship->storbits]->name, 
  88.                Stars[ship->storbits]->pnames[ship->pnumorbits]);
  89.                teleg_add(buf,telegram_buf);
  90.                teleg_add("Canister of dust previously covering this planet has dissipated.\n",telegram_buf);
  91.                for (j=1; j<=Num_races; j++)
  92.                  if (planets[ship->storbits][ship->pnumorbits]->info[j-1].numsectsowned) 
  93.                 teleg_send(TELEG_PLAYER_AUTO, j, telegram_buf);
  94.           } else fprintf(stderr,"can't delete canister #%d!\n",shipno);
  95.           }
  96.        }
  97.        break;
  98.  
  99.       case STYPE_MINE:{ reg int i,rad=0; float xd[MAXSSHIPS],yd[MAXSSHIPS];
  100.             int p,shfdata;
  101.         /* check around and see if we should explode. */
  102.        if (ship->orders.object.on && ship->whatorbits==LEVEL_STAR) {
  103.          for (i=0; i<MAXSSHIPS; i++)
  104.         if (Stars[ship->storbits]->shipnums[i]) {
  105.             xd[i] = ships[Stars[ship->storbits]->shipnums[i]]->xpos- ship->xpos;
  106.             yd[i] = ships[Stars[ship->storbits]->shipnums[i]]->ypos- ship->ypos;
  107.             if (Stars[ship->storbits]->shipnums[i]==shipno)
  108.             p = i;
  109.             else
  110.                 if (isset(races[ship->owner]->atwar,ships[Stars[ship->storbits]->shipnums[i]]->owner) &&
  111.             (abs(xd[i])+abs(yd[i])) < ship->orders.object.number)
  112.                 rad = 1;
  113.             if (rad) {
  114.              /* we've found someone we don't like,
  115.                detonate and irradiate them */
  116.                 Stars[ship->storbits]->shipnums[p] = 0;
  117.             openshfdata(&shfdata);
  118.             destroyship(shfdata, shipno);
  119.             close(shfdata);
  120.             teleg_add("",telegram_buf);
  121.             sprintf(buf, "BULLETIN!\n mine #%d triggered at system /%s",shipno,Stars[ship->storbits]->name);
  122.             teleg_add(buf, telegram_buf);
  123.             teleg_send(TELEG_PLAYER_AUTO,ship->owner,telegram_buf);
  124.                for (i=0; i<=MAXSSHIPS; i++)
  125.                 if (Stars[ship->storbits]->shipnums[i] &&
  126.                         Stars[ship->storbits]->shipnums[i]!=shipno &&
  127.                         (abs(xd[i])+abs(yd[i]))<ship->orders.object.number) {
  128.                           rad = round_rand(((float)Shipdata[STYPE_MINE][ABIL_DESTCAP] / ship->destruct)*.5);
  129.                                 if (ships[Stars[ship->storbits]->shipnums[i]]->rad + rad > 100)
  130.                             ships[Stars[ship->storbits]->shipnums[i]]->rad = 100;
  131.                           else
  132.                             ships[Stars[ship->storbits]->shipnums[i]]->rad += rad;
  133.                           teleg_add("",telegram_buf);
  134.                           sprintf(buf, "BULLETIN!\n ship #%d irradiated by mine at system /%s", Stars[ship->storbits]->shipnums[i],
  135.                            Stars[ship->storbits]->name);
  136.                           teleg_add(buf, telegram_buf);
  137.                           teleg_send(TELEG_PLAYER_AUTO,ships[Stars[ship->storbits]->shipnums[i]]->owner,telegram_buf);
  138.                 }
  139.             }
  140.         }
  141.        }/* else if (ship->whatorbits==LEVEL_PLAN) {}*/
  142.        } break;
  143.  
  144.       case STYPE_MIRROR:
  145.       switch (ship->orders.aimed_at.level) {
  146.        case LEVEL_SHIP: /* ship aimed at is a legal ship now */
  147.               /* if in the same system */
  148.            if ( (ship->whatorbits==LEVEL_STAR || ship->whatorbits==LEVEL_PLAN)
  149.             && (ships[ship->orders.aimed_at.shipno]!=NULL)
  150.             && (ships[ship->orders.aimed_at.shipno]->whatorbits==LEVEL_STAR ||
  151.             ships[ship->orders.aimed_at.shipno]->whatorbits==LEVEL_PLAN)
  152.             && ship->storbits == ships[ship->orders.aimed_at.shipno]->storbits 
  153.             && !ships[ship->orders.aimed_at.shipno]->is_dead )
  154.                 ships[ship->orders.aimed_at.shipno]->damage += 10;
  155.         break;
  156.        case LEVEL_PLAN: { reg char *t;
  157.           t = &Stinfo[ship->storbits][ship->orders.aimed_at.pnum].temp_add;
  158.           if (*t + ship->orders.aimed_at.intensity > 120)
  159.             *t = 120;
  160.           else if (*t + ship->orders.aimed_at.intensity < -120)
  161.             *t = -120;
  162.           else
  163.             *t += ship->orders.aimed_at.intensity;
  164.         }
  165.         break;
  166.        case LEVEL_STAR:
  167.         Stars[ship->storbits]->stability += random()&01;
  168.         break;
  169.        case LEVEL_UNIV:
  170.         break;
  171.     }
  172.     break;
  173.      case STYPE_GOD:
  174.         /* gods have infinite power.... heh heh heh */
  175.     ship->fuel = Shipdata[ship->type][ABIL_FUELCAP];
  176.     ship->popn = Shipdata[ship->type][ABIL_MAXCREW];
  177.     ship->destruct = Shipdata[ship->type][ABIL_DESTCAP];
  178.     ship->resource = Shipdata[ship->type][ABIL_CARGO];
  179.     break;
  180.  
  181.      case OTYPE_TERRA:    /* terraforming device */
  182.         /* if landed on planet, change conditions to be like race */
  183.     if (ship->is_docked && ship->whatdest==LEVEL_PLAN && ship->orders.object.on) {
  184.         int j,d,a;planettype *p;
  185.         p = planets[ship->storbits][ship->pnumorbits];
  186.         if (p->info[ship->owner-1].fuel >= 3) {
  187.             p->info[ship->owner-1].fuel-= 3;
  188.             for (j=RTEMP+1; j<=OTHER; j++) {
  189.                 d = races[ship->owner]->conditions[j] - p->conditions[j];
  190.                 a = int_rand(sgn(d)*3,-sgn(d));
  191.                 if (p->conditions[j] + a < 0)
  192.                     p->conditions[j] = 0;
  193.                 else if (p->conditions[j] + a > 100)
  194.                     p->conditions[j] = 100;
  195.                 else p->conditions[j] += a;
  196.             }
  197.         }
  198.     }
  199.     break;
  200.  
  201.      case OTYPE_VN:    /* Von Neumann machine */
  202.     do_VN(ship,shipno);
  203.     break;
  204.  
  205.      case STYPE_POD:
  206.     if (ship->notified) {
  207.         /* we just arrived at this system -- explode */
  208.         int shfdata;
  209.         reg int i,f= -1;
  210.         for (i=0; i<MAXSSHIPS && Stars[ship->storbits]->shipnums[i]!=shipno; i++) ;
  211.         if (i==MAXSSHIPS)
  212.             fprintf(stderr,"cannot del pod #%d!\n",shipno);
  213.         else {
  214.             Stars[ship->storbits]->shipnums[i] = 0;
  215.             ship->is_dead = 1;
  216.             openshfdata(&shfdata);
  217.             destroyship(shfdata, shipno);
  218.             close(shfdata);
  219.             for (i=0; f== -1 && i<Stars[ship->storbits]->numplanets; i++)
  220.                 if (sqrt((double)Distsq(ship->xpos, ship->ypos,
  221.                   Stars[ship->storbits]->xpos + planets[ship->storbits][i]->xpos,
  222.                   Stars[ship->storbits]->ypos + planets[ship->storbits][i]->ypos))/SYSTEMSIZE < float_rand()*2)
  223.                     f = i;
  224.             teleg_add("",telegram_buf);
  225.             sprintf(buf, "Bulletin\n\nSpore pod #%d has warmed and exploded.\n",shipno);
  226.             teleg_add(buf,telegram_buf);
  227.             if (f != -1) {
  228.                 sprintf(buf,"A spore has landed on planet %s.\n",Stars[ship->storbits]->pnames[f]);
  229.                 Stinfo[ship->storbits][f].Thing_add = ship->owner;
  230.                     /* so doplanet does not pass over it */
  231.                 setbit(Stars[ship->storbits]->inhabited,ship->owner);
  232.                 planets[ship->storbits][f]->info[ship->owner-1].explored = 1;
  233.             } else {
  234.                 sprintf(buf,"No spores have survived.\n");
  235.             }
  236.             teleg_add(buf,telegram_buf);
  237.             teleg_send(TELEG_PLAYER_AUTO, ship->owner, telegram_buf);
  238.             teleg_add("",telegram_buf);
  239.             sprintf(buf,"BULLETIN!\n\n A spore pod has exploded in system /%s.\n",Stars[ship->storbits]->name);
  240.             teleg_add(buf,telegram_buf);
  241.             teleg_add("Spores may have drifted to planets here.\n",telegram_buf);
  242.             for (i=1; i<=Num_races; i++)
  243.                 if (i!=ship->owner && isset(Stars[ship->storbits]->inhabited,i))
  244.                     teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
  245.         }
  246.     }
  247.     break;
  248.  
  249.      default:
  250.     break;
  251.     }
  252.  
  253.    }
  254.  }
  255.  
  256. }
  257.  
  258.  
  259.  
  260. do_VN(ship,shipno)
  261. shiptype *ship;
  262. int shipno;
  263. {
  264. int j,n,r; 
  265. planettype *p;
  266. char buf[150];
  267.  
  268.   if (ship->orders.object.on) {
  269.  
  270.     p = planets[ship->storbits][ship->pnumorbits];
  271.  
  272.     if (ship->is_docked && ship->whatdest==LEVEL_PLAN && ship->whatorbits==LEVEL_PLAN) {
  273.        /* try to launch it */
  274.     if (ship->orders.object.number2 == 0) {    /* launch if no assignment */
  275.       /* steal some fuel from other players,telegram */
  276.         bool f=0;
  277.         for (r=Num_races-1; !f && r>0; r--)
  278.           if (p->info[r-1].fuel >= Shipdata[OTYPE_VN][ABIL_COST]) {
  279.             p->info[ship->owner-1].fuel += 
  280.                     Shipdata[OTYPE_VN][ABIL_FUELCAP];
  281.               p->info[r-1].fuel -= Shipdata[OTYPE_VN][ABIL_FUELCAP];
  282.             f = r;
  283.           }
  284.           if (f) {
  285.           /*if (f!=1) {*/
  286.             teleg_add("",telegram_buf);
  287.             teleg_add("Bulletin!\n\n",telegram_buf);
  288.             sprintf(buf,"%d fuel stolen by %s #%d on planet /%s/%s!\n",
  289.                Shipdata[OTYPE_VN][ABIL_FUELCAP],
  290.                Shipnames[OTYPE_VN],
  291.                shipno, Stars[ship->storbits]->name,
  292.                Stars[ship->storbits]->pnames[ship->pnumorbits]);
  293.             teleg_add(buf,telegram_buf);
  294.                 teleg_send(TELEG_PLAYER_AUTO, f, telegram_buf);
  295.                 teleg_send(TELEG_PLAYER_AUTO, 1, telegram_buf);
  296.           /*}*/
  297.         
  298.         ship->orders.object.number2 = 0; /* no current assignment */
  299.         ship->xpos = Stars[ship->storbits]->xpos + planets[ship->storbits][ship->pnumorbits]->xpos + int_rand(-10,10);
  300.         ship->ypos = Stars[ship->storbits]->ypos + planets[ship->storbits][ship->pnumorbits]->ypos + int_rand(-10,10);
  301.         ship->is_docked = 0;
  302.         ship->whatdest = LEVEL_UNIV;
  303.           }
  304.     } else {
  305.         /* we have an assignment.  Since we are landed, this means
  306.            we are engaged in building up resources/fuel. */
  307.         /* steal resources from other players,telegram */
  308.         bool f=0;
  309.         for (r=Num_races-1; !f && r>0; r--)
  310.           if (p->info[r-1].resource >= Shipdata[OTYPE_VN][ABIL_COST])
  311.             f = r;
  312.         if (f) {
  313.           /*if (f!=1) {*/
  314.             ship->resource += Shipdata[OTYPE_VN][ABIL_COST];
  315.             ship->mass += Shipdata[OTYPE_VN][ABIL_COST] * MASS_RESOURCE;
  316.               p->info[f-1].resource -= Shipdata[OTYPE_VN][ABIL_COST];
  317.             teleg_add("",telegram_buf);
  318.             teleg_add("Bulletin!\n\n",telegram_buf);
  319.             sprintf(buf,"%d resources stolen by %s #%d\non planet ",
  320.                  Shipdata[OTYPE_VN][ABIL_COST],
  321.                  Shipnames[OTYPE_VN], shipno);
  322.             teleg_add(buf,telegram_buf);
  323.             sprintf(buf,"/%s/%s!\n",
  324.                  Stars[ship->storbits]->name,
  325.                  Stars[ship->storbits]->pnames[ship->pnumorbits]);
  326.             teleg_add(buf,telegram_buf);
  327.                 teleg_send(TELEG_PLAYER_AUTO, f, telegram_buf);
  328.                 /* remove */
  329.                 teleg_send(TELEG_PLAYER_AUTO, 1, telegram_buf);
  330.           /*}*/
  331.         /* if no resources to steal, more will be produced in doplanet*/
  332.         }
  333.     }
  334.   } else {
  335.     /* we are not landed */
  336.     if (ship->orders.object.number2) {
  337.         /* we've arrived from somewhere -- look for a place to land.  
  338.            this is done on planet turn */
  339.     } else {
  340.         /* we were just built & launched */
  341.         reg int s,min=0,min2=0;
  342.           /* find closest unexplored star */
  343.         for (s=1; s<Sdata.numstars; s++)
  344.             if (s != ship->storbits &&
  345.                 Distsq(Stars[s]->xpos,Stars[s]->ypos,ship->xpos,ship->ypos) < 
  346.                 Distsq(Stars[min]->xpos,Stars[min]->ypos,ship->xpos,ship->ypos))
  347.                    min2 = min,min = s;
  348.             /* don't go there if we have a choice, 
  349.                and we have VN's there already */
  350.         if (isset(Stars[min]->inhabited,1))
  351.           if (isset(Stars[min2]->inhabited,1))
  352.             ship->deststar = int_rand(0,Sdata.numstars-1);
  353.           else
  354.             ship->deststar = min2;    /* 2nd closest star */
  355.         else
  356.               ship->deststar = min;
  357.         if (Stars[ship->deststar]->numplanets) {
  358.             ship->destpnum =
  359.                 int_rand(0,Stars[ship->deststar]->numplanets-1);
  360.              ship->whatdest = LEVEL_PLAN;
  361.         } else {
  362.              ship->whatdest = LEVEL_STAR;
  363.         }
  364.         fprintf(stderr,"VN #%d headed for star %d, pl %d.\n",shipno,ship->deststar, ship->destpnum);
  365.         ship->orders.object.number2 = 1;
  366.             /* we are assigned to go */
  367.     }
  368.   }
  369.  
  370.  }
  371.  
  372. }
  373.