(linenum→info "unix/slp.c:2238")

bsd-games/2.17/sail/dr_1.c

    1: /*      $NetBSD: dr_1.c,v 1.21 2004/11/05 21:30:32 dsl Exp $ */
    2: 
    3: /*
    4:  * Copyright (c) 1983, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    6:  *
    7:  * Redistribution and use in source and binary forms, with or without
    8:  * modification, are permitted provided that the following conditions
    9:  * are met:
   10:  * 1. Redistributions of source code must retain the above copyright
   11:  *    notice, this list of conditions and the following disclaimer.
   12:  * 2. Redistributions in binary form must reproduce the above copyright
   13:  *    notice, this list of conditions and the following disclaimer in the
   14:  *    documentation and/or other materials provided with the distribution.
   15:  * 3. Neither the name of the University nor the names of its contributors
   16:  *    may be used to endorse or promote products derived from this software
   17:  *    without specific prior written permission.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29:  * SUCH DAMAGE.
   30:  */
   31: 
   32: #include <sys/cdefs.h>
   33: #ifndef lint
   34: #if 0
   35: static char sccsid[] = "@(#)dr_1.c      8.1 (Berkeley) 5/31/93";
   36: #else
   37: __RCSID("$NetBSD: dr_1.c,v 1.21 2004/11/05 21:30:32 dsl Exp $");
   38: #endif
   39: #endif /* not lint */
   40: 
   41: #include <ctype.h>
   42: #include <stdio.h>
   43: #include <stdlib.h>
   44: #include <string.h>
   45: #include "extern.h"
   46: #include "driver.h"
   47: 
   48: static int      fightitout(struct ship *, struct ship *, int);
   49: 
   50: void
   51: unfoul(void)
   52: {
   53:         struct ship *sp;
   54:         struct ship *to;
   55:         int nat;
   56:         int i;
   57: 
   58:         foreachship(sp) {
   59:                 if (sp->file->captain[0])
   60:                         continue;
   61:                 nat = capship(sp)->nationality;
   62:                 foreachship(to) {
   63:                         if (nat != capship(to)->nationality &&
   64:                             !is_toughmelee(sp, to, 0, 0))
   65:                                 continue;
   66:                         for (i = fouled2(sp, to); --i >= 0;)
   67:                                 if (dieroll() <= 2)
   68:                                         cleanfoul(sp, to, 0);
   69:                 }
   70:         }
   71: }
   72: 
   73: void
   74: boardcomp(void)
   75: {
   76:         int crew[3];
   77:         struct ship *sp, *sq;
   78: 
   79:         foreachship(sp) {
   80:                 if (*sp->file->captain)
   81:                         continue;
   82:                 if (sp->file->dir == 0)
   83:                         continue;
   84:                 if (sp->file->struck || sp->file->captured != 0)
   85:                         continue;
   86:                 if (!snagged(sp))
   87:                         continue;
   88:                 crew[0] = sp->specs->crew1 != 0;
   89:                 crew[1] = sp->specs->crew2 != 0;
   90:                 crew[2] = sp->specs->crew3 != 0;
   91:                 foreachship(sq) {
   92:                         if (!Xsnagged2(sp, sq))
   93:                                 continue;
   94:                         if (meleeing(sp, sq))
   95:                                 continue;
   96:                         if (!sq->file->dir
   97:                                 || sp->nationality == capship(sq)->nationality)
   98:                                 continue;
   99:                         switch (sp->specs->class - sq->specs->class) {
  100:                         case -3: case -4: case -5:
  101:                                 if (crew[0]) {
  102:                                         /* OBP */
  103:                                         sendbp(sp, sq, crew[0]*100, 0);
  104:                                         crew[0] = 0;
  105:                                 } else if (crew[1]){
  106:                                         /* OBP */
  107:                                         sendbp(sp, sq, crew[1]*10, 0);
  108:                                         crew[1] = 0;
  109:                                 }
  110:                                 break;
  111:                         case -2:
  112:                                 if (crew[0] || crew[1]) {
  113:                                         /* OBP */
  114:                                         sendbp(sp, sq, crew[0]*100+crew[1]*10,
  115:                                                 0);
  116:                                         crew[0] = crew[1] = 0;
  117:                                 }
  118:                                 break;
  119:                         case -1: case 0: case 1:
  120:                                 if (crew[0]) {
  121:                                         /* OBP */
  122:                                         sendbp(sp, sq, crew[0]*100+crew[1]*10,
  123:                                                 0);
  124:                                         crew[0] = crew[1] = 0;
  125:                                 }
  126:                                 break;
  127:                         case 2: case 3: case 4: case 5:
  128:                                 /* OBP */
  129:                                 sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
  130:                                         0);
  131:                                 crew[0] = crew[1] = crew[2] = 0;
  132:                                 break;
  133:                         }
  134:                 }
  135:         }
  136: }
  137: 
  138: static int
  139: fightitout(struct ship *from, struct ship *to, int key)
  140: {
  141:         struct ship *fromcap, *tocap;
  142:         int crewfrom[3], crewto[3], menfrom, mento;
  143:         int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
  144:         int topoints;
  145:         int index, totalfrom = 0, totalto = 0;
  146:         int count;
  147:         char message[60];
  148: 
  149:         menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
  150:         mento = mensent(to, from, crewto, &tocap, &pcto, 0);
  151:         if (fromcap == 0)
  152:                 fromcap = from;
  153:         if (tocap == 0)
  154:                 tocap = to;
  155:         if (key) {
  156:                 if (!menfrom) {                /* if crew surprised */
  157:                         if (fromcap == from)
  158:                                 menfrom = from->specs->crew1
  159:                                         + from->specs->crew2
  160:                                         + from->specs->crew3;
  161:                         else
  162:                                 menfrom = from->file->pcrew;
  163:                 } else {
  164:                         menfrom *= 2;        /* DBP's fight at an advantage */
  165:                 }
  166:         }
  167:         fromstrength = menfrom * fromcap->specs->qual;
  168:         strengthto = mento * tocap->specs->qual;
  169:         for (count = 0;
  170:              ((fromstrength < strengthto * 3 && strengthto < fromstrength * 3)
  171:               || fromstrength == -1) && count < 4;
  172:              count++) {
  173:                 index = fromstrength/10;
  174:                 if (index > 8)
  175:                         index = 8;
  176:                 toinjured = MT[index][2 - dieroll() / 3];
  177:                 totalto += toinjured;
  178:                 index = strengthto/10;
  179:                 if (index > 8)
  180:                         index = 8;
  181:                 frominjured = MT[index][2 - dieroll() / 3];
  182:                 totalfrom += frominjured;
  183:                 menfrom -= frominjured;
  184:                 mento -= toinjured;
  185:                 fromstrength = menfrom * fromcap->specs->qual;
  186:                 strengthto = mento * tocap->specs->qual;
  187:         }
  188:         if (fromstrength >= strengthto * 3 || count == 4) {
  189:                 unboard(to, from, 0);
  190:                 subtract(from, fromcap, totalfrom, crewfrom, pcfrom);
  191:                 subtract(to, tocap, totalto, crewto, pcto);
  192:                 makemsg(from, "boarders from %s repelled", to->shipname);
  193:                 sprintf(message, "killed in melee: %d.  %s: %d",
  194:                         totalto, from->shipname, totalfrom);
  195:                 Writestr(W_SIGNAL, to, message);
  196:                 if (key)
  197:                         return 1;
  198:         } else if (strengthto >= fromstrength * 3) {
  199:                 unboard(from, to, 0);
  200:                 subtract(from, fromcap, totalfrom, crewfrom, pcfrom);
  201:                 subtract(to, tocap, totalto, crewto, pcto);
  202:                 if (key) {
  203:                         if (fromcap != from)
  204:                                 Write(W_POINTS, fromcap,
  205:                                         fromcap->file->points -
  206:                                                 from->file->struck
  207:                                                 ? from->specs->pts
  208:                                                 : 2 * from->specs->pts,
  209:                                         0, 0, 0);
  210: 
  211: /* ptr1 points to the shipspec for the ship that was just unboarded.
  212:    I guess that what is going on here is that the pointer is multiplied
  213:    or something. */
  214: 
  215:                         Write(W_CAPTURED, from, to->file->index, 0, 0, 0);
  216:                         topoints = 2 * from->specs->pts + to->file->points;
  217:                         if (from->file->struck)
  218:                                 topoints -= from->specs->pts;
  219:                         Write(W_POINTS, to, topoints, 0, 0, 0);
  220:                         mento = crewto[0] ? crewto[0] : crewto[1];
  221:                         if (mento) {
  222:                                 subtract(to, tocap, mento, crewto, pcto);
  223:                                 subtract(from, to, - mento, crewfrom, 0);
  224:                         }
  225:                         sprintf(message, "captured by the %s!", to->shipname);
  226:                         Writestr(W_SIGNAL, from, message);
  227:                         sprintf(message, "killed in melee: %d.  %s: %d",
  228:                                 totalto, from->shipname, totalfrom);
  229:                         Writestr(W_SIGNAL, to, message);
  230:                         mento = 0;
  231:                         return 0;
  232:                 }
  233:         }
  234:         return 0;
  235: }
  236: 
  237: void
  238: resolve(void)
  239: {
  240:         int thwart;
  241:         struct ship *sp, *sq;
  242: 
  243:         foreachship(sp) {
  244:                 if (sp->file->dir == 0)
  245:                         continue;
  246:                 for (sq = sp + 1; sq < ls; sq++)
  247:                         if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
  248:                                 fightitout(sp, sq, 0);
  249:                 thwart = 2;
  250:                 foreachship(sq) {
  251:                         if (sq->file->dir && meleeing(sq, sp))
  252:                                 thwart = fightitout(sp, sq, 1);
  253:                         if (!thwart)
  254:                                 break;
  255:                 }
  256:                 if (!thwart) {
  257:                         foreachship(sq) {
  258:                                 if (sq->file->dir && meleeing(sq, sp))
  259:                                         unboard(sq, sp, 0);
  260:                                 unboard(sp, sq, 0);
  261:                         }
  262:                         unboard(sp, sp, 1);
  263:                 } else if (thwart == 2)
  264:                         unboard(sp, sp, 1);
  265:         }
  266: }
  267: 
  268: void
  269: compcombat(void)
  270: {
  271:         int n;
  272:         struct ship *sp;
  273:         struct ship *closest;
  274:         int crew[3], men = 0, target, temp;
  275:         int r, guns, ready, load, car;
  276:         int index, rakehim, sternrake;
  277:         int shootat, hit;
  278: 
  279:         foreachship(sp) {
  280:                 if (sp->file->captain[0] || sp->file->dir == 0)
  281:                         continue;
  282:                 crew[0] = sp->specs->crew1;
  283:                 crew[1] = sp->specs->crew2;
  284:                 crew[2] = sp->specs->crew3;
  285:                 for (n = 0; n < 3; n++) {
  286:                         if (sp->file->OBP[n].turnsent)
  287:                                 men += sp->file->OBP[n].mensent;
  288:                 }
  289:                 for (n = 0; n < 3; n++) {
  290:                         if (sp->file->DBP[n].turnsent)
  291:                                 men += sp->file->DBP[n].mensent;
  292:                 }
  293:                 if (men){
  294:                         crew[0] = men/100 ? 0 : crew[0] != 0;
  295:                         crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
  296:                         crew[2] = men%10 ? 0 : crew[2] != 0;
  297:                 }
  298:                 for (r = 0; r < 2; r++) {
  299:                         if (!crew[2])
  300:                                 continue;
  301:                         if (sp->file->struck)
  302:                                 continue;
  303:                         if (r) {
  304:                                 ready = sp->file->readyR;
  305:                                 guns = sp->specs->gunR;
  306:                                 car = sp->specs->carR;
  307:                         } else {
  308:                                 ready = sp->file->readyL;
  309:                                 guns = sp->specs->gunL;
  310:                                 car = sp->specs->carL;
  311:                         }
  312:                         if (!guns && !car)
  313:                                 continue;
  314:                         if ((ready & R_LOADED) == 0)
  315:                                 continue;
  316:                         closest = closestenemy(sp, r ? 'r' : 'l', 0);
  317:                         if (closest == 0)
  318:                                 continue;
  319:                         if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
  320:                                 continue;
  321:                         if (closest->file->struck)
  322:                                 continue;
  323:                         target = range(sp, closest);
  324:                         if (target > 10)
  325:                                 continue;
  326:                         if (!guns && target >= 3)
  327:                                 continue;
  328:                         load = L_ROUND;
  329:                         if (target == 1 && sp->file->loadwith == L_GRAPE)
  330:                                 load = L_GRAPE;
  331:                         if (target <= 3 && closest->file->FS)
  332:                                 load = L_CHAIN;
  333:                         if (target == 1 && load != L_GRAPE)
  334:                                 load = L_DOUBLE;
  335:                         if (load > L_CHAIN && target < 6)
  336:                                 shootat = HULL;
  337:                         else
  338:                                 shootat = RIGGING;
  339:                         rakehim = gunsbear(sp, closest)
  340:                                 && !gunsbear(closest, sp);
  341:                         temp = portside(closest, sp, 1)
  342:                                 - closest->file->dir + 1;
  343:                         if (temp < 1)
  344:                                 temp += 8;
  345:                         if (temp > 8)
  346:                                 temp -= 8;
  347:                         sternrake = temp > 4 && temp < 6;
  348:                         index = guns;
  349:                         if (target < 3)
  350:                                 index += car;
  351:                         index = (index - 1) / 3;
  352:                         index = index > 8 ? 8 : index;
  353:                         if (!rakehim)
  354:                                 hit = HDT[index][target-1];
  355:                         else
  356:                                 hit = HDTrake[index][target-1];
  357:                         if (rakehim && sternrake)
  358:                                 hit++;
  359:                         hit += QUAL[index][capship(sp)->specs->qual - 1];
  360:                         for (n = 0; n < 3 && sp->file->captured == 0; n++)
  361:                                 if (!crew[n]) {
  362:                                         if (index <= 5)
  363:                                                 hit--;
  364:                                         else
  365:                                                 hit -= 2;
  366:                                 }
  367:                         if (ready & R_INITIAL) {
  368:                                 if (!r)
  369:                                         sp->file->readyL &= ~R_INITIAL;
  370:                                 else
  371:                                         sp->file->readyR &= ~R_INITIAL;
  372:                                 if (index <= 3)
  373:                                         hit++;
  374:                                 else
  375:                                         hit += 2;
  376:                         }
  377:                         if (sp->file->captured != 0) {
  378:                                 if (index <= 1)
  379:                                         hit--;
  380:                                 else
  381:                                         hit -= 2;
  382:                         }
  383:                         hit += AMMO[index][load - 1];
  384:                         temp = sp->specs->class;
  385:                         if ((temp >= 5 || temp == 1) && windspeed == 5)
  386:                                 hit--;
  387:                         if (windspeed == 6 && temp == 4)
  388:                                 hit -= 2;
  389:                         if (windspeed == 6 && temp <= 3)
  390:                                 hit--;
  391:                         if (hit >= 0) {
  392:                                 if (load != L_GRAPE)
  393:                                         hit = hit > 10 ? 10 : hit;
  394:                                 table(sp, closest, shootat, load, hit, dieroll());
  395:                         }
  396:                 }
  397:         }
  398: }
  399: 
  400: int
  401: next(void)
  402: {
  403:         if (++turn % 55 == 0) {
  404:                 if (alive)
  405:                         alive = 0;
  406:                 else
  407:                         people = 0;
  408:         }
  409:         if (people <= 0 || windspeed == 7) {
  410:                 struct ship *s;
  411:                 struct ship *bestship = NULL;
  412:                 float net, best = 0.0;
  413:                 foreachship(s) {
  414:                         if (*s->file->captain)
  415:                                 continue;
  416:                         net = (float)s->file->points / s->specs->pts;
  417:                         if (net > best) {
  418:                                 best = net;
  419:                                 bestship = s;
  420:                         }
  421:                 }
  422:                 if (best > 0.0) {
  423:                         char *tp = getenv("WOTD");
  424:                         const char *p;
  425:                         if (tp == 0)
  426:                                 p = "Driver";
  427:                         else {
  428:                                 *tp = toupper((unsigned char)*tp);
  429:                                 p = tp;
  430:                         }
  431:                         strlcpy(bestship->file->captain, p,
  432:                                 sizeof bestship->file->captain);
  433:                         logger(bestship);
  434:                 }
  435:                 return -1;
  436:         }
  437:         Write(W_TURN, SHIP(0), turn, 0, 0, 0);
  438:         if (turn % 7 == 0 && (dieroll() >= cc->windchange || !windspeed)) {
  439:                 switch (dieroll()) {
  440:                 case 1:
  441:                         winddir = 1;
  442:                         break;
  443:                 case 2:
  444:                         break;
  445:                 case 3:
  446:                         winddir++;
  447:                         break;
  448:                 case 4:
  449:                         winddir--;
  450:                         break;
  451:                 case 5:
  452:                         winddir += 2;
  453:                         break;
  454:                 case 6:
  455:                         winddir -= 2;
  456:                         break;
  457:                 }
  458:                 if (winddir > 8)
  459:                         winddir -= 8;
  460:                 if (winddir < 1)
  461:                         winddir += 8;
  462:                 if (windspeed)
  463:                         switch (dieroll()) {
  464:                         case 1:
  465:                         case 2:
  466:                                 windspeed--;
  467:                                 break;
  468:                         case 5:
  469:                         case 6:
  470:                                 windspeed++;
  471:                                 break;
  472:                         }
  473:                 else
  474:                         windspeed++;
  475:                 Write(W_WIND, SHIP(0), winddir, windspeed, 0, 0);
  476:         }
  477:         return 0;
  478: }
Syntax (Markdown)