home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / sail / dr_3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  8.2 KB  |  347 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)dr_3.c    5.4 (Berkeley) 6/1/90";
  36. #endif /* not lint */
  37.  
  38. #include "driver.h"
  39.  
  40. moveall()        /* move all comp ships */
  41. {
  42.     register struct ship *sp, *sq;        /* r11, r10 */
  43.     register int n;                /* r9 */
  44.     register int k, l;            /* r8, r7 */
  45.     int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
  46.     char moved[NSHIP];
  47.  
  48.     /*
  49.      * first try to create moves for OUR ships
  50.      */
  51.     foreachship(sp) {
  52.         struct ship *closest;
  53.         int ma, ta;
  54.         char af;
  55.  
  56.         if (sp->file->captain[0] || sp->file->dir == 0)
  57.             continue;
  58.         if (!sp->file->struck && windspeed && !snagged(sp)
  59.             && sp->specs->crew3) {
  60.             ta = maxturns(sp, &af);
  61.             ma = maxmove(sp, sp->file->dir, 0);
  62.             closest = closestenemy(sp, 0, 0);
  63.             if (closest == 0)
  64.                 *sp->file->movebuf = '\0';
  65.             else
  66.                 closeon(sp, closest, sp->file->movebuf,
  67.                     ta, ma, af);
  68.         } else
  69.             *sp->file->movebuf = '\0';
  70.     }
  71.     /*
  72.      * Then execute the moves for ALL ships (dead ones too),
  73.      * checking for collisions and snags at each step.
  74.      * The old positions are saved in row[], col[], dir[].
  75.      * At the end, we compare and write out the changes.
  76.      */
  77.     n = 0;
  78.     foreachship(sp) {
  79.         if (snagged(sp))
  80.             (void) strcpy(sp->file->movebuf, "d");
  81.         else
  82.             if (*sp->file->movebuf != 'd')
  83.                 (void) strcat(sp->file->movebuf, "d");
  84.         row[n] = sp->file->row;
  85.         col[n] = sp->file->col;
  86.         dir[n] = sp->file->dir;
  87.         drift[n] = sp->file->drift;
  88.         moved[n] = 0;
  89.         n++;
  90.     }
  91.     /*
  92.      * Now resolve collisions.
  93.      * This is the tough part.
  94.      */
  95.     for (k = 0; stillmoving(k); k++) {
  96.         /*
  97.          * Step once.
  98.          * And propagate the nulls at the end of sp->file->movebuf.
  99.          */
  100.         n = 0;
  101.         foreachship(sp) {
  102.             if (!sp->file->movebuf[k])
  103.                 sp->file->movebuf[k+1] = '\0';
  104.             else if (sp->file->dir)
  105.                 step(sp->file->movebuf[k], sp, &moved[n]);
  106.             n++;
  107.         }
  108.         /*
  109.          * The real stuff.
  110.          */
  111.         n = 0;
  112.         foreachship(sp) {
  113.             if (sp->file->dir == 0 || isolated(sp))
  114.                 goto cont1;
  115.             l = 0;
  116.             foreachship(sq) {
  117.                 char snap = 0;
  118.  
  119.                 if (sp == sq)
  120.                     goto cont2;
  121.                 if (sq->file->dir == 0)
  122.                     goto cont2;
  123.                 if (!push(sp, sq))
  124.                     goto cont2;
  125.                 if (snagged2(sp, sq) && range(sp, sq) > 1)
  126.                     snap++;
  127.                 if (!range(sp, sq) && !fouled2(sp, sq)) {
  128.                     makesignal(sp,
  129.                         "collision with %s (%c%c)", sq);
  130.                     if (die() < 4) {
  131.                         makesignal(sp,
  132.                             "fouled with %s (%c%c)",
  133.                             sq);
  134.                         Write(W_FOUL, sp, 0, l, 0, 0, 0);
  135.                         Write(W_FOUL, sq, 0, n, 0, 0, 0);
  136.                     }
  137.                     snap++;
  138.                 }
  139.                 if (snap) {
  140.                     sp->file->movebuf[k + 1] = 0;
  141.                     sq->file->movebuf[k + 1] = 0;
  142.                     sq->file->row = sp->file->row - 1;
  143.                     if (sp->file->dir == 1
  144.                         || sp->file->dir == 5)
  145.                         sq->file->col =
  146.                             sp->file->col - 1;
  147.                     else
  148.                         sq->file->col = sp->file->col;
  149.                     sq->file->dir = sp->file->dir;
  150.                 }
  151.             cont2:
  152.                 l++;
  153.             }
  154.         cont1:
  155.             n++;
  156.         }
  157.     }
  158.     /*
  159.      * Clear old moves.  And write out new pos.
  160.      */
  161.     n = 0;
  162.     foreachship(sp) {
  163.         if (sp->file->dir != 0) {
  164.             *sp->file->movebuf = 0;
  165.             if (row[n] != sp->file->row)
  166.                 Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
  167.             if (col[n] != sp->file->col)
  168.                 Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
  169.             if (dir[n] != sp->file->dir)
  170.                 Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
  171.             if (drift[n] != sp->file->drift)
  172.                 Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
  173.         }
  174.         n++;
  175.     }
  176. }
  177.  
  178. stillmoving(k)
  179. register int k;
  180. {
  181.     register struct ship *sp;
  182.  
  183.     foreachship(sp)
  184.         if (sp->file->movebuf[k])
  185.             return 1;
  186.     return 0;
  187. }
  188.  
  189. isolated(ship)
  190. register struct ship *ship;
  191. {
  192.     register struct ship *sp;
  193.  
  194.     foreachship(sp) {
  195.         if (ship != sp && range(ship, sp) <= 10)
  196.             return 0;
  197.     }
  198.     return 1;
  199. }
  200.  
  201. push(from, to)
  202. register struct ship *from, *to;
  203. {
  204.     register int bs, sb;
  205.  
  206.     sb = to->specs->guns;
  207.     bs = from->specs->guns;
  208.     if (sb > bs)
  209.         return 1;
  210.     if (sb < bs)
  211.         return 0;
  212.     return from < to;
  213. }
  214.  
  215. step(com, sp, moved)
  216. char com;
  217. register struct ship *sp;
  218. char *moved;
  219. {
  220.     register int dist;
  221.  
  222.     switch (com) {
  223.     case 'r':
  224.         if (++sp->file->dir == 9)
  225.             sp->file->dir = 1;
  226.         break;
  227.     case 'l':
  228.         if (--sp->file->dir == 0)
  229.             sp->file->dir = 8;
  230.         break;
  231.         case '0': case '1': case '2': case '3':
  232.         case '4': case '5': case '6': case '7':
  233.         if (sp->file->dir % 2 == 0)
  234.             dist = dtab[com - '0'];
  235.         else
  236.             dist = com - '0';
  237.         sp->file->row -= dr[sp->file->dir] * dist;
  238.         sp->file->col -= dc[sp->file->dir] * dist;
  239.         *moved = 1;
  240.         break;
  241.     case 'b':
  242.         break;
  243.     case 'd':
  244.         if (!*moved) {
  245.             if (windspeed != 0 && ++sp->file->drift > 2 &&
  246.                 (sp->specs->class >= 3 && !snagged(sp)
  247.                  || (turn & 1) == 0)) {
  248.                 sp->file->row -= dr[winddir];
  249.                 sp->file->col -= dc[winddir];
  250.             }
  251.         } else
  252.             sp->file->drift = 0;
  253.         break;
  254.     }
  255. }
  256.  
  257. sendbp(from, to, sections, isdefense)
  258. register struct ship *from, *to;
  259. int sections;
  260. char isdefense;
  261. {
  262.     int n;
  263.     register struct BP *bp;
  264.  
  265.     bp = isdefense ? from->file->DBP : from->file->OBP;
  266.     for (n = 0; n < NBP && bp[n].turnsent; n++)
  267.         ;
  268.     if (n < NBP && sections) {
  269.         Write(isdefense ? W_DBP : W_OBP, from, 0,
  270.             n, turn, to->file->index, sections);
  271.         if (isdefense)
  272.             makesignal(from, "repelling boarders",
  273.                 (struct ship *)0);
  274.         else
  275.             makesignal(from, "boarding the %s (%c%c)", to);
  276.     }
  277. }
  278.  
  279. toughmelee(ship, to, isdefense, count)
  280. register struct ship *ship, *to;
  281. int isdefense, count;
  282. {
  283.     register struct BP *bp;
  284.     register obp = 0;
  285.     int n, OBP = 0, DBP = 0, dbp = 0;
  286.     int qual;
  287.  
  288.     qual = ship->specs->qual;
  289.     bp = isdefense ? ship->file->DBP : ship->file->OBP;
  290.     for (n = 0; n < NBP; n++, bp++) {
  291.         if (bp->turnsent && (to == bp->toship || isdefense)) {
  292.             obp += bp->mensent / 100
  293.                 ? ship->specs->crew1 * qual : 0;
  294.             obp += (bp->mensent % 100)/10
  295.                 ? ship->specs->crew2 * qual : 0;
  296.             obp += bp->mensent % 10
  297.                 ? ship->specs->crew3 * qual : 0;
  298.         }
  299.     }
  300.     if (count || isdefense)
  301.         return obp;
  302.     OBP = toughmelee(to, ship, 0, count + 1);
  303.     dbp = toughmelee(ship, to, 1, count + 1);
  304.     DBP = toughmelee(to, ship, 1, count + 1);
  305.     if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
  306.         return 1;
  307.     else
  308.         return 0;
  309. }
  310.  
  311. reload()
  312. {
  313.     register struct ship *sp;
  314.  
  315.     foreachship(sp) {
  316.         sp->file->loadwith = 0;
  317.     }
  318. }
  319.  
  320. checksails()
  321. {
  322.     register struct ship *sp;
  323.     register int rig, full; 
  324.     struct ship *close;
  325.  
  326.     foreachship(sp) {
  327.         if (sp->file->captain[0] != 0)
  328.             continue;
  329.         rig = sp->specs->rig1;
  330.         if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
  331.             rig = 0;
  332.         if (rig && sp->specs->crew3) {
  333.             close = closestenemy(sp, 0, 0);
  334.             if (close != 0) {
  335.                 if (range(sp, close) > 9)
  336.                     full = 1;
  337.                 else
  338.                     full = 0;
  339.             } else 
  340.                 full = 0;
  341.         } else
  342.             full = 0;
  343.         if ((sp->file->FS != 0) != full)
  344.             Write(W_FS, sp, 0, full, 0, 0, 0);
  345.     }
  346. }
  347.