111589Sleres #ifndef lint 2*16082Sedward static char *sccsid = "@(#)dr_1.c 2.8 84/02/23"; 311589Sleres #endif 412619Sroot 514007Sedward #include "driver.h" 611589Sleres 715202Sedward main(argc, argv) 815202Sedward int argc; 915202Sedward char **argv; 1015202Sedward { 1115202Sedward register int n; 1215202Sedward register struct ship *sp; 1315202Sedward int nat[NNATION]; 1415202Sedward 1515202Sedward if (argc != 2) 1615202Sedward exit(1); 1715202Sedward (void) signal(SIGINT, SIG_IGN); 1815202Sedward (void) signal(SIGQUIT, SIG_IGN); 1915369Sedward (void) signal(SIGTSTP, SIG_IGN); 2015202Sedward (void) srand(getpid()); 2115202Sedward /* ;;; add code here to check the game number. */ 2215202Sedward game = atoi(argv[1]); 2315202Sedward cc = &scene[game]; 2415899Sedward ls = SHIP(cc->vessels); 2515202Sedward if (sync_open() < 0) { 2615202Sedward perror("driver: syncfile"); 2715202Sedward exit(1); 2815202Sedward } 2915202Sedward for (n = 0; n < NNATION; n++) 3015202Sedward nat[n] = 0; 3115202Sedward foreachship(sp) { 3215202Sedward sp->file = (struct File *) calloc(1, sizeof (struct File)); 3315202Sedward if (sp == NULL) { 3415202Sedward (void) printf("driver: OUT OF MEMORY\n"); 35*16082Sedward exit(1); 3615202Sedward } 3715721Sedward sp->file->index = sp - SHIP(0); 3815202Sedward sp->file->loadL = L_ROUND; 3915202Sedward sp->file->loadR = L_ROUND; 4015202Sedward sp->file->readyR = R_LOADED|R_INITIAL; 4115202Sedward sp->file->readyL = R_LOADED|R_INITIAL; 4215202Sedward sp->file->stern = nat[sp->nationality]++; 4315202Sedward sp->file->dir = sp->shipdir; 4415202Sedward sp->file->row = sp->shiprow; 4515202Sedward sp->file->col = sp->shipcol; 4615202Sedward } 4715202Sedward windspeed = cc->windspeed; 4815202Sedward winddir = cc->winddir; 4915202Sedward for (;;) { 5015353Sedward sleep(7); 51*16082Sedward if (Sync() < 0) { 52*16082Sedward sync_close(1); 53*16082Sedward exit(1); 54*16082Sedward } 5515202Sedward next(); 5615202Sedward unfoul(); 5715202Sedward checkup(); 5815202Sedward prizecheck(); 5915202Sedward moveall(); 6015202Sedward thinkofgrapples(); 6115202Sedward boardcomp(); 6215202Sedward compcombat(); 6315202Sedward resolve(); 6415202Sedward reload(); 6515202Sedward checksails(); 66*16082Sedward if (Sync() < 0) { 67*16082Sedward sync_close(1); 68*16082Sedward exit(1); 69*16082Sedward } 7015202Sedward } 7115202Sedward } 7215202Sedward 7311589Sleres unfoul() 7411589Sleres { 7514007Sedward register struct ship *sp; 7614007Sedward struct ship *to; 7714007Sedward register int nat; 7815721Sedward register i; 7911589Sleres 8014007Sedward foreachship(sp) { 8114007Sedward if (sp->file->captain[0]) 8214007Sedward continue; 8314007Sedward nat = capship(sp)->nationality; 8415721Sedward foreachship(to) { 8515721Sedward if (nat != capship(to)->nationality 8615721Sedward && !toughmelee(sp, to, 0, 0)) 8714007Sedward continue; 8815721Sedward for (i = fouled2(sp, to); --i >= 0;) 8915721Sedward if (die() <= 2) 9015721Sedward cleanfoul(sp, to, 0); 9111589Sleres } 9211589Sleres } 9311589Sleres } 9411589Sleres 9511589Sleres boardcomp() 9611589Sleres { 9712619Sroot int crew[3]; 9814007Sedward register struct ship *sp, *sq; 9911589Sleres 10014007Sedward foreachship(sp) { 10114007Sedward if (*sp->file->captain) 10214007Sedward continue; 10314007Sedward if (sp->file->dir == 0) 10414007Sedward continue; 10514007Sedward if (sp->file->struck || sp->file->captured != 0) 10614007Sedward continue; 10715721Sedward if (!snagged(sp)) 10815721Sedward continue; 10914007Sedward crew[0] = sp->specs->crew1 != 0; 11014007Sedward crew[1] = sp->specs->crew2 != 0; 11114007Sedward crew[2] = sp->specs->crew3 != 0; 11214007Sedward foreachship(sq) { 11314007Sedward if (!Xsnagged2(sp, sq)) 11414007Sedward continue; 11514007Sedward if (meleeing(sp, sq)) 11614007Sedward continue; 11714007Sedward if (!sq->file->dir 11814007Sedward || sp->nationality == capship(sq)->nationality) 11914007Sedward continue; 12014007Sedward switch (sp->specs->class - sq->specs->class) { 12114007Sedward case -3: case -4: case -5: 12214007Sedward if (crew[0]) { 12314007Sedward /* OBP */ 12414007Sedward sendbp(sp, sq, crew[0]*100, 0); 12514007Sedward crew[0] = 0; 12614007Sedward } else if (crew[1]){ 12714007Sedward /* OBP */ 12814007Sedward sendbp(sp, sq, crew[1]*10, 0); 12914007Sedward crew[1] = 0; 13011589Sleres } 13114007Sedward break; 13214007Sedward case -2: 13314007Sedward if (crew[0] || crew[1]) { 13414007Sedward /* OBP */ 13514007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10, 13614007Sedward 0); 13714007Sedward crew[0] = crew[1] = 0; 13814007Sedward } 13914007Sedward break; 14014007Sedward case -1: case 0: case 1: 14114007Sedward if (crew[0]) { 14214007Sedward /* OBP */ 14314007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10, 14414007Sedward 0); 14514007Sedward crew[0] = crew[1] = 0; 14614007Sedward } 14714007Sedward break; 14814007Sedward case 2: case 3: case 4: case 5: 14914007Sedward /* OBP */ 15014007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2], 15114007Sedward 0); 15214007Sedward crew[0] = crew[1] = crew[2] = 0; 15314007Sedward break; 15411589Sleres } 15514007Sedward } 15611589Sleres } 15711589Sleres } 15811589Sleres 15911589Sleres fightitout(from, to, key) 16014007Sedward struct ship *from, *to; 16114007Sedward int key; 16211589Sleres { 16314007Sedward struct ship *fromcap, *tocap; 16414007Sedward int crewfrom[3], crewto[3], menfrom, mento; 16511589Sleres int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured; 16614007Sedward int topoints; 16714007Sedward int index, totalfrom = 0, totalto = 0; 16814007Sedward int count; 16911589Sleres char message[60]; 17011589Sleres 17114007Sedward menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key); 17214007Sedward mento = mensent(to, from, crewto, &tocap, &pcto, 0); 17314007Sedward if (fromcap == 0) 17411589Sleres fromcap = from; 17514007Sedward if (tocap == 0) 17611589Sleres tocap = to; 17715721Sedward if (key) { 17815330Sedward if (!menfrom) { /* if crew surprised */ 17915330Sedward if (fromcap == from) 18015330Sedward menfrom = from->specs->crew1 18115330Sedward + from->specs->crew2 18215330Sedward + from->specs->crew3; 18315330Sedward else 18415330Sedward menfrom = from->file->pcrew; 18515330Sedward } else { 18615330Sedward menfrom *= 2; /* DBP's fight at an advantage */ 18715330Sedward } 18815330Sedward } 18914007Sedward fromstrength = menfrom * fromcap->specs->qual; 19014007Sedward strengthto = mento * tocap->specs->qual; 19114007Sedward for (count = 0; 19214007Sedward (fromstrength < strengthto * 3 && strengthto < fromstrength * 3 19314007Sedward || fromstrength == -1) && count < 4; 19414007Sedward count++) { 19511589Sleres index = fromstrength/10; 19611589Sleres if (index > 8) 19711589Sleres index = 8; 19811589Sleres toinjured = MT[index][2 - die() / 3]; 19911589Sleres totalto += toinjured; 20011589Sleres index = strengthto/10; 20111589Sleres if (index > 8) 20211589Sleres index = 8; 20311589Sleres frominjured = MT[index][2 - die() / 3]; 20411589Sleres totalfrom += frominjured; 20511589Sleres menfrom -= frominjured; 20611589Sleres mento -= toinjured; 20714007Sedward fromstrength = menfrom * fromcap->specs->qual; 20814007Sedward strengthto = mento * tocap->specs->qual; 20911589Sleres } 21014007Sedward if (fromstrength >= strengthto * 3 || count == 4) { 21111589Sleres unboard(to, from, 0); 21211589Sleres subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 21311589Sleres subtract(to, totalto, crewto, tocap, pcto); 21414007Sedward makesignal(from, "boarders from %s repelled", to); 21514007Sedward (void) sprintf(message, "killed in melee: %d. %s: %d", 21614007Sedward totalto, from->shipname, totalfrom); 21714007Sedward Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 21811589Sleres if (key) 21914007Sedward return 1; 22014007Sedward } else if (strengthto >= fromstrength * 3) { 22111589Sleres unboard(from, to, 0); 22211589Sleres subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 22311589Sleres subtract(to, totalto, crewto, tocap, pcto); 22414007Sedward if (key) { 22511589Sleres if (fromcap != from) 22614007Sedward Write(W_POINTS, fromcap, 0, 22714007Sedward fromcap->file->points - 22814007Sedward from->file->struck 22914007Sedward ? from->specs->pts 23014007Sedward : 2 * from->specs->pts, 23114007Sedward 0, 0, 0); 23211589Sleres 23311589Sleres /* ptr1 points to the shipspec for the ship that was just unboarded. 23411589Sleres I guess that what is going on here is that the pointer is multiplied 23511589Sleres or something. */ 23611589Sleres 23715721Sedward Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0); 23814007Sedward topoints = 2 * from->specs->pts + to->file->points; 23914007Sedward if (from->file->struck) 24014007Sedward topoints -= from->specs->pts; 24114007Sedward Write(W_POINTS, to, 0, topoints, 0, 0, 0); 24211589Sleres mento = crewto[0] ? crewto[0] : crewto[1]; 24314007Sedward if (mento) { 24411589Sleres subtract(to, mento, crewto, tocap, pcto); 24514007Sedward subtract(from, - mento, crewfrom, to, 0); 24611589Sleres } 24714007Sedward (void) sprintf(message, "captured by the %s!", 24814007Sedward to->shipname); 24914007Sedward Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0); 25014007Sedward (void) sprintf(message, "killed in melee: %d. %s: %d", 25114007Sedward totalto, from->shipname, totalfrom); 25214007Sedward Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 25311589Sleres mento = 0; 25414007Sedward return 0; 25511589Sleres } 25611589Sleres } 25714007Sedward return 0; 25814007Sedward } 25911589Sleres 26011589Sleres resolve() 26111589Sleres { 26214007Sedward int thwart; 26314007Sedward register struct ship *sp, *sq; 26411589Sleres 26514007Sedward foreachship(sp) { 26614007Sedward if (sp->file->dir == 0) 26714007Sedward continue; 26815330Sedward for (sq = sp + 1; sq < ls; sq++) 26914007Sedward if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp)) 27014007Sedward (void) fightitout(sp, sq, 0); 27115395Sedward thwart = 2; 27214007Sedward foreachship(sq) { 27314007Sedward if (sq->file->dir && meleeing(sq, sp)) 27414007Sedward thwart = fightitout(sp, sq, 1); 27514007Sedward if (!thwart) 27614007Sedward break; 27711589Sleres } 27815395Sedward if (!thwart) { 27915395Sedward foreachship(sq) { 28015395Sedward if (sq->file->dir && meleeing(sq, sp)) 28115395Sedward unboard(sq, sp, 0); 28215395Sedward unboard(sp, sq, 0); 28315395Sedward } 28414007Sedward unboard(sp, sp, 1); 28515395Sedward } else if (thwart == 2) 28615395Sedward unboard(sp, sp, 1); 28711589Sleres } 28811589Sleres } 28911589Sleres 29011589Sleres compcombat() 29111589Sleres { 29214007Sedward register n; 29314007Sedward register struct ship *sp; 29414007Sedward struct ship *closest; 29511589Sleres int crew[3], men = 0, target, temp; 29615311Sedward int r, guns, ready, load, car; 29715311Sedward int index, rakehim, sternrake; 29814007Sedward int shootat, hit; 29911589Sleres 30014007Sedward foreachship(sp) { 30114007Sedward if (sp->file->captain[0] || sp->file->dir == 0) 30214007Sedward continue; 30314007Sedward crew[0] = sp->specs->crew1; 30414007Sedward crew[1] = sp->specs->crew2; 30514007Sedward crew[2] = sp->specs->crew3; 30614007Sedward for (n = 0; n < 3; n++) { 30714007Sedward if (sp->file->OBP[n].turnsent) 30814007Sedward men += sp->file->OBP[n].mensent; 30914007Sedward } 31014007Sedward for (n = 0; n < 3; n++) { 31114007Sedward if (sp->file->DBP[n].turnsent) 31214007Sedward men += sp->file->DBP[n].mensent; 31314007Sedward } 31414007Sedward if (men){ 31514007Sedward crew[0] = men/100 ? 0 : crew[0] != 0; 31614007Sedward crew[1] = (men%100)/10 ? 0 : crew[1] != 0; 31714007Sedward crew[2] = men%10 ? 0 : crew[2] != 0; 31814007Sedward } 31914007Sedward for (r = 0; r < 2; r++) { 32014007Sedward if (!crew[2]) 32114007Sedward continue; 32214007Sedward if (sp->file->struck) 32314007Sedward continue; 32414007Sedward if (r) { 32514007Sedward ready = sp->file->readyR; 32614007Sedward guns = sp->specs->gunR; 32714007Sedward car = sp->specs->carR; 32814007Sedward } else { 32914007Sedward ready = sp->file->readyL; 33014007Sedward guns = sp->specs->gunL; 33114007Sedward car = sp->specs->carL; 33211589Sleres } 33314007Sedward if (!guns && !car) 33414007Sedward continue; 33514007Sedward if ((ready & R_LOADED) == 0) 33614007Sedward continue; 33714007Sedward closest = closestenemy(sp, r ? 'r' : 'l', 0); 33814007Sedward if (closest == 0) 33914007Sedward continue; 34014007Sedward if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1))) 34114007Sedward continue; 34214007Sedward if (closest->file->struck) 34314007Sedward continue; 34414007Sedward target = range(sp, closest); 34514007Sedward if (target > 10) 34614007Sedward continue; 34714007Sedward if (!guns && target >= 3) 34814007Sedward continue; 34914007Sedward load = L_ROUND; 35014007Sedward if (target == 1 && sp->file->loadwith == L_GRAPE) 35114007Sedward load = L_GRAPE; 35214007Sedward if (target <= 3 && closest->file->FS) 35314007Sedward load = L_CHAIN; 35414007Sedward if (target == 1 && load != L_GRAPE) 35514007Sedward load = L_DOUBLE; 35614007Sedward if (load > L_CHAIN && target < 6) 35714007Sedward shootat = HULL; 35814007Sedward else 35914007Sedward shootat = RIGGING; 36014007Sedward rakehim = gunsbear(sp, closest) 36114007Sedward && !gunsbear(closest, sp); 36214007Sedward temp = portside(closest, sp, 1) 36314007Sedward - closest->file->dir + 1; 36414007Sedward if (temp < 1) 36514007Sedward temp += 8; 36614007Sedward if (temp > 8) 36714007Sedward temp -= 8; 36814007Sedward sternrake = temp > 4 && temp < 6; 36914007Sedward index = guns; 37014007Sedward if (target < 3) 37114007Sedward index += car; 37214007Sedward index = (index - 1) / 3; 37314007Sedward index = index > 8 ? 8 : index; 37414007Sedward if (!rakehim) 37514007Sedward hit = HDT[index][target-1]; 37614007Sedward else 37714007Sedward hit = HDTrake[index][target-1]; 37814007Sedward if (rakehim && sternrake) 37914007Sedward hit++; 38014007Sedward hit += QUAL[index][capship(sp)->specs->qual - 1]; 38114007Sedward for (n = 0; n < 3 && sp->file->captured == 0; n++) 38214007Sedward if (!crew[n]) 38314007Sedward if (index <= 5) 38414007Sedward hit--; 38514007Sedward else 38614007Sedward hit -= 2; 38715311Sedward if (ready & R_INITIAL) { 38815311Sedward if (!r) 38915311Sedward sp->file->readyL &= ~R_INITIAL; 39015311Sedward else 39115311Sedward sp->file->readyR &= ~R_INITIAL; 39214007Sedward if (index <= 3) 39314007Sedward hit++; 39411589Sleres else 39514007Sedward hit += 2; 39615311Sedward } 39714007Sedward if (sp->file->captured != 0) 39814007Sedward if (index <= 1) 39914007Sedward hit--; 40014007Sedward else 40114007Sedward hit -= 2; 40214007Sedward hit += AMMO[index][load - 1]; 40314007Sedward temp = sp->specs->class; 40414007Sedward if ((temp >= 5 || temp == 1) && windspeed == 5) 40514007Sedward hit--; 40614007Sedward if (windspeed == 6 && temp == 4) 40714007Sedward hit -= 2; 40814007Sedward if (windspeed == 6 && temp <= 3) 40914007Sedward hit--; 41014007Sedward if (hit >= 0) { 41114007Sedward if (load != L_GRAPE) 41214007Sedward hit = hit > 10 ? 10 : hit; 41314007Sedward table(shootat, load, hit, closest, sp, die()); 41411589Sleres } 41511589Sleres } 41611589Sleres } 41711589Sleres } 41811589Sleres 41911589Sleres next() 42011589Sleres { 42114007Sedward if (++turn % 55 == 0) 42215202Sedward if (alive) 42315202Sedward alive = 0; 42414007Sedward else 42515202Sedward people = 0; 42615202Sedward if (people <= 0 || windspeed == 7) { 427*16082Sedward register struct ship *s; 428*16082Sedward struct ship *bestship; 429*16082Sedward float net, best = 0.0; 430*16082Sedward foreachship(s) { 431*16082Sedward if (*s->file->captain) 432*16082Sedward continue; 433*16082Sedward net = (float)s->file->points / s->specs->pts; 434*16082Sedward if (net > best) { 435*16082Sedward best = net; 436*16082Sedward bestship = s; 437*16082Sedward } 438*16082Sedward } 439*16082Sedward if (best > 0.0) { 440*16082Sedward char *p = getenv("WOTD"); 441*16082Sedward if (p == 0) 442*16082Sedward p = "Driver"; 443*16082Sedward strcpy(bestship->file->captain, p); 444*16082Sedward log(bestship); 445*16082Sedward } 44615202Sedward sync_close(1); 44711589Sleres exit(0); 44811589Sleres } 44914007Sedward Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0); 45014007Sedward if (turn % 7 == 0) { 45114007Sedward if (die() >= cc->windchange || !windspeed) { 45214007Sedward switch (die()) { 45314007Sedward case 1: 45414007Sedward winddir = 1; 45514007Sedward break; 45614007Sedward case 2: 45714007Sedward break; 45814007Sedward case 3: 45914007Sedward winddir++; 46014007Sedward break; 46114007Sedward case 4: 46214007Sedward winddir--; 46314007Sedward break; 46414007Sedward case 5: 46514007Sedward winddir += 2; 46614007Sedward break; 46714007Sedward case 6: 46814007Sedward winddir -= 2; 46914007Sedward break; 47014007Sedward } 47114007Sedward if (winddir > 8) 47214007Sedward winddir -= 8; 47314007Sedward if (winddir < 1) 47414007Sedward winddir += 8; 47514007Sedward if (windspeed) 47614007Sedward switch (die()) { 47711589Sleres case 1: 47811589Sleres case 2: 47914007Sedward windspeed--; 48011589Sleres break; 48111589Sleres case 5: 48211589Sleres case 6: 48314007Sedward windspeed++; 48411589Sleres break; 48511589Sleres } 48611589Sleres else 48711589Sleres windspeed++; 48814007Sedward Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0); 48914007Sedward } 49011589Sleres } 49111589Sleres } 49215237Sedward 49315721Sedward /*ARGSUSED*/ 49415237Sedward /*VARARGS2*/ 49515237Sedward Signal(fmt, ship, a, b, c) 49615237Sedward char *fmt; 49715237Sedward struct ship *ship; 49815237Sedward { 49915237Sedward } 500