118696Sedward /* 221228Sdist * Copyright (c) 1983 Regents of the University of California. 333695Sbostic * All rights reserved. 433695Sbostic * 5*42601Sbostic * %sccs.include.redist.c% 618696Sedward */ 718696Sedward 811589Sleres #ifndef lint 9*42601Sbostic static char sccsid[] = "@(#)dr_1.c 5.4 (Berkeley) 06/01/90"; 1033695Sbostic #endif /* not lint */ 1112619Sroot 1214007Sedward #include "driver.h" 1311589Sleres 1411589Sleres unfoul() 1511589Sleres { 1614007Sedward register struct ship *sp; 1714007Sedward struct ship *to; 1814007Sedward register int nat; 1915721Sedward register i; 2011589Sleres 2114007Sedward foreachship(sp) { 2214007Sedward if (sp->file->captain[0]) 2314007Sedward continue; 2414007Sedward nat = capship(sp)->nationality; 2515721Sedward foreachship(to) { 2618251Sedward if (nat != capship(to)->nationality && 2718251Sedward !toughmelee(sp, to, 0, 0)) 2814007Sedward continue; 2915721Sedward for (i = fouled2(sp, to); --i >= 0;) 3015721Sedward if (die() <= 2) 3115721Sedward cleanfoul(sp, to, 0); 3211589Sleres } 3311589Sleres } 3411589Sleres } 3511589Sleres 3611589Sleres boardcomp() 3711589Sleres { 3812619Sroot int crew[3]; 3914007Sedward register struct ship *sp, *sq; 4011589Sleres 4114007Sedward foreachship(sp) { 4214007Sedward if (*sp->file->captain) 4314007Sedward continue; 4414007Sedward if (sp->file->dir == 0) 4514007Sedward continue; 4614007Sedward if (sp->file->struck || sp->file->captured != 0) 4714007Sedward continue; 4815721Sedward if (!snagged(sp)) 4915721Sedward continue; 5014007Sedward crew[0] = sp->specs->crew1 != 0; 5114007Sedward crew[1] = sp->specs->crew2 != 0; 5214007Sedward crew[2] = sp->specs->crew3 != 0; 5314007Sedward foreachship(sq) { 5414007Sedward if (!Xsnagged2(sp, sq)) 5514007Sedward continue; 5614007Sedward if (meleeing(sp, sq)) 5714007Sedward continue; 5814007Sedward if (!sq->file->dir 5914007Sedward || sp->nationality == capship(sq)->nationality) 6014007Sedward continue; 6114007Sedward switch (sp->specs->class - sq->specs->class) { 6214007Sedward case -3: case -4: case -5: 6314007Sedward if (crew[0]) { 6414007Sedward /* OBP */ 6514007Sedward sendbp(sp, sq, crew[0]*100, 0); 6614007Sedward crew[0] = 0; 6714007Sedward } else if (crew[1]){ 6814007Sedward /* OBP */ 6914007Sedward sendbp(sp, sq, crew[1]*10, 0); 7014007Sedward crew[1] = 0; 7111589Sleres } 7214007Sedward break; 7314007Sedward case -2: 7414007Sedward if (crew[0] || crew[1]) { 7514007Sedward /* OBP */ 7614007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10, 7714007Sedward 0); 7814007Sedward crew[0] = crew[1] = 0; 7914007Sedward } 8014007Sedward break; 8114007Sedward case -1: case 0: case 1: 8214007Sedward if (crew[0]) { 8314007Sedward /* OBP */ 8414007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10, 8514007Sedward 0); 8614007Sedward crew[0] = crew[1] = 0; 8714007Sedward } 8814007Sedward break; 8914007Sedward case 2: case 3: case 4: case 5: 9014007Sedward /* OBP */ 9114007Sedward sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2], 9214007Sedward 0); 9314007Sedward crew[0] = crew[1] = crew[2] = 0; 9414007Sedward break; 9511589Sleres } 9614007Sedward } 9711589Sleres } 9811589Sleres } 9911589Sleres 10011589Sleres fightitout(from, to, key) 10114007Sedward struct ship *from, *to; 10214007Sedward int key; 10311589Sleres { 10414007Sedward struct ship *fromcap, *tocap; 10514007Sedward int crewfrom[3], crewto[3], menfrom, mento; 10611589Sleres int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured; 10714007Sedward int topoints; 10814007Sedward int index, totalfrom = 0, totalto = 0; 10914007Sedward int count; 11011589Sleres char message[60]; 11111589Sleres 11214007Sedward menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key); 11314007Sedward mento = mensent(to, from, crewto, &tocap, &pcto, 0); 11414007Sedward if (fromcap == 0) 11511589Sleres fromcap = from; 11614007Sedward if (tocap == 0) 11711589Sleres tocap = to; 11815721Sedward if (key) { 11915330Sedward if (!menfrom) { /* if crew surprised */ 12015330Sedward if (fromcap == from) 12115330Sedward menfrom = from->specs->crew1 12215330Sedward + from->specs->crew2 12315330Sedward + from->specs->crew3; 12415330Sedward else 12515330Sedward menfrom = from->file->pcrew; 12615330Sedward } else { 12715330Sedward menfrom *= 2; /* DBP's fight at an advantage */ 12815330Sedward } 12915330Sedward } 13014007Sedward fromstrength = menfrom * fromcap->specs->qual; 13114007Sedward strengthto = mento * tocap->specs->qual; 13214007Sedward for (count = 0; 13314007Sedward (fromstrength < strengthto * 3 && strengthto < fromstrength * 3 13414007Sedward || fromstrength == -1) && count < 4; 13514007Sedward count++) { 13611589Sleres index = fromstrength/10; 13711589Sleres if (index > 8) 13811589Sleres index = 8; 13911589Sleres toinjured = MT[index][2 - die() / 3]; 14011589Sleres totalto += toinjured; 14111589Sleres index = strengthto/10; 14211589Sleres if (index > 8) 14311589Sleres index = 8; 14411589Sleres frominjured = MT[index][2 - die() / 3]; 14511589Sleres totalfrom += frominjured; 14611589Sleres menfrom -= frominjured; 14711589Sleres mento -= toinjured; 14814007Sedward fromstrength = menfrom * fromcap->specs->qual; 14914007Sedward strengthto = mento * tocap->specs->qual; 15011589Sleres } 15114007Sedward if (fromstrength >= strengthto * 3 || count == 4) { 15211589Sleres unboard(to, from, 0); 15311589Sleres subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 15411589Sleres subtract(to, totalto, crewto, tocap, pcto); 15514007Sedward makesignal(from, "boarders from %s repelled", to); 15614007Sedward (void) sprintf(message, "killed in melee: %d. %s: %d", 15714007Sedward totalto, from->shipname, totalfrom); 15814007Sedward Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 15911589Sleres if (key) 16014007Sedward return 1; 16114007Sedward } else if (strengthto >= fromstrength * 3) { 16211589Sleres unboard(from, to, 0); 16311589Sleres subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 16411589Sleres subtract(to, totalto, crewto, tocap, pcto); 16514007Sedward if (key) { 16611589Sleres if (fromcap != from) 16714007Sedward Write(W_POINTS, fromcap, 0, 16814007Sedward fromcap->file->points - 16914007Sedward from->file->struck 17014007Sedward ? from->specs->pts 17114007Sedward : 2 * from->specs->pts, 17214007Sedward 0, 0, 0); 17311589Sleres 17411589Sleres /* ptr1 points to the shipspec for the ship that was just unboarded. 17511589Sleres I guess that what is going on here is that the pointer is multiplied 17611589Sleres or something. */ 17711589Sleres 17815721Sedward Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0); 17914007Sedward topoints = 2 * from->specs->pts + to->file->points; 18014007Sedward if (from->file->struck) 18114007Sedward topoints -= from->specs->pts; 18214007Sedward Write(W_POINTS, to, 0, topoints, 0, 0, 0); 18311589Sleres mento = crewto[0] ? crewto[0] : crewto[1]; 18414007Sedward if (mento) { 18511589Sleres subtract(to, mento, crewto, tocap, pcto); 18614007Sedward subtract(from, - mento, crewfrom, to, 0); 18711589Sleres } 18814007Sedward (void) sprintf(message, "captured by the %s!", 18914007Sedward to->shipname); 19014007Sedward Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0); 19114007Sedward (void) sprintf(message, "killed in melee: %d. %s: %d", 19214007Sedward totalto, from->shipname, totalfrom); 19314007Sedward Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 19411589Sleres mento = 0; 19514007Sedward return 0; 19611589Sleres } 19711589Sleres } 19814007Sedward return 0; 19914007Sedward } 20011589Sleres 20111589Sleres resolve() 20211589Sleres { 20314007Sedward int thwart; 20414007Sedward register struct ship *sp, *sq; 20511589Sleres 20614007Sedward foreachship(sp) { 20714007Sedward if (sp->file->dir == 0) 20814007Sedward continue; 20915330Sedward for (sq = sp + 1; sq < ls; sq++) 21014007Sedward if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp)) 21114007Sedward (void) fightitout(sp, sq, 0); 21215395Sedward thwart = 2; 21314007Sedward foreachship(sq) { 21414007Sedward if (sq->file->dir && meleeing(sq, sp)) 21514007Sedward thwart = fightitout(sp, sq, 1); 21614007Sedward if (!thwart) 21714007Sedward break; 21811589Sleres } 21915395Sedward if (!thwart) { 22015395Sedward foreachship(sq) { 22115395Sedward if (sq->file->dir && meleeing(sq, sp)) 22215395Sedward unboard(sq, sp, 0); 22315395Sedward unboard(sp, sq, 0); 22415395Sedward } 22514007Sedward unboard(sp, sp, 1); 22615395Sedward } else if (thwart == 2) 22715395Sedward unboard(sp, sp, 1); 22811589Sleres } 22911589Sleres } 23011589Sleres 23111589Sleres compcombat() 23211589Sleres { 23314007Sedward register n; 23414007Sedward register struct ship *sp; 23514007Sedward struct ship *closest; 23611589Sleres int crew[3], men = 0, target, temp; 23715311Sedward int r, guns, ready, load, car; 23815311Sedward int index, rakehim, sternrake; 23914007Sedward int shootat, hit; 24011589Sleres 24114007Sedward foreachship(sp) { 24214007Sedward if (sp->file->captain[0] || sp->file->dir == 0) 24314007Sedward continue; 24414007Sedward crew[0] = sp->specs->crew1; 24514007Sedward crew[1] = sp->specs->crew2; 24614007Sedward crew[2] = sp->specs->crew3; 24714007Sedward for (n = 0; n < 3; n++) { 24814007Sedward if (sp->file->OBP[n].turnsent) 24914007Sedward men += sp->file->OBP[n].mensent; 25014007Sedward } 25114007Sedward for (n = 0; n < 3; n++) { 25214007Sedward if (sp->file->DBP[n].turnsent) 25314007Sedward men += sp->file->DBP[n].mensent; 25414007Sedward } 25514007Sedward if (men){ 25614007Sedward crew[0] = men/100 ? 0 : crew[0] != 0; 25714007Sedward crew[1] = (men%100)/10 ? 0 : crew[1] != 0; 25814007Sedward crew[2] = men%10 ? 0 : crew[2] != 0; 25914007Sedward } 26014007Sedward for (r = 0; r < 2; r++) { 26114007Sedward if (!crew[2]) 26214007Sedward continue; 26314007Sedward if (sp->file->struck) 26414007Sedward continue; 26514007Sedward if (r) { 26614007Sedward ready = sp->file->readyR; 26714007Sedward guns = sp->specs->gunR; 26814007Sedward car = sp->specs->carR; 26914007Sedward } else { 27014007Sedward ready = sp->file->readyL; 27114007Sedward guns = sp->specs->gunL; 27214007Sedward car = sp->specs->carL; 27311589Sleres } 27414007Sedward if (!guns && !car) 27514007Sedward continue; 27614007Sedward if ((ready & R_LOADED) == 0) 27714007Sedward continue; 27814007Sedward closest = closestenemy(sp, r ? 'r' : 'l', 0); 27914007Sedward if (closest == 0) 28014007Sedward continue; 28114007Sedward if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1))) 28214007Sedward continue; 28314007Sedward if (closest->file->struck) 28414007Sedward continue; 28514007Sedward target = range(sp, closest); 28614007Sedward if (target > 10) 28714007Sedward continue; 28814007Sedward if (!guns && target >= 3) 28914007Sedward continue; 29014007Sedward load = L_ROUND; 29114007Sedward if (target == 1 && sp->file->loadwith == L_GRAPE) 29214007Sedward load = L_GRAPE; 29314007Sedward if (target <= 3 && closest->file->FS) 29414007Sedward load = L_CHAIN; 29514007Sedward if (target == 1 && load != L_GRAPE) 29614007Sedward load = L_DOUBLE; 29714007Sedward if (load > L_CHAIN && target < 6) 29814007Sedward shootat = HULL; 29914007Sedward else 30014007Sedward shootat = RIGGING; 30114007Sedward rakehim = gunsbear(sp, closest) 30214007Sedward && !gunsbear(closest, sp); 30314007Sedward temp = portside(closest, sp, 1) 30414007Sedward - closest->file->dir + 1; 30514007Sedward if (temp < 1) 30614007Sedward temp += 8; 30714007Sedward if (temp > 8) 30814007Sedward temp -= 8; 30914007Sedward sternrake = temp > 4 && temp < 6; 31014007Sedward index = guns; 31114007Sedward if (target < 3) 31214007Sedward index += car; 31314007Sedward index = (index - 1) / 3; 31414007Sedward index = index > 8 ? 8 : index; 31514007Sedward if (!rakehim) 31614007Sedward hit = HDT[index][target-1]; 31714007Sedward else 31814007Sedward hit = HDTrake[index][target-1]; 31914007Sedward if (rakehim && sternrake) 32014007Sedward hit++; 32114007Sedward hit += QUAL[index][capship(sp)->specs->qual - 1]; 32214007Sedward for (n = 0; n < 3 && sp->file->captured == 0; n++) 32314007Sedward if (!crew[n]) 32414007Sedward if (index <= 5) 32514007Sedward hit--; 32614007Sedward else 32714007Sedward hit -= 2; 32815311Sedward if (ready & R_INITIAL) { 32915311Sedward if (!r) 33015311Sedward sp->file->readyL &= ~R_INITIAL; 33115311Sedward else 33215311Sedward sp->file->readyR &= ~R_INITIAL; 33314007Sedward if (index <= 3) 33414007Sedward hit++; 33511589Sleres else 33614007Sedward hit += 2; 33715311Sedward } 33814007Sedward if (sp->file->captured != 0) 33914007Sedward if (index <= 1) 34014007Sedward hit--; 34114007Sedward else 34214007Sedward hit -= 2; 34314007Sedward hit += AMMO[index][load - 1]; 34414007Sedward temp = sp->specs->class; 34514007Sedward if ((temp >= 5 || temp == 1) && windspeed == 5) 34614007Sedward hit--; 34714007Sedward if (windspeed == 6 && temp == 4) 34814007Sedward hit -= 2; 34914007Sedward if (windspeed == 6 && temp <= 3) 35014007Sedward hit--; 35114007Sedward if (hit >= 0) { 35214007Sedward if (load != L_GRAPE) 35314007Sedward hit = hit > 10 ? 10 : hit; 35414007Sedward table(shootat, load, hit, closest, sp, die()); 35511589Sleres } 35611589Sleres } 35711589Sleres } 35811589Sleres } 35911589Sleres 36011589Sleres next() 36111589Sleres { 36214007Sedward if (++turn % 55 == 0) 36315202Sedward if (alive) 36415202Sedward alive = 0; 36514007Sedward else 36615202Sedward people = 0; 36715202Sedward if (people <= 0 || windspeed == 7) { 36816082Sedward register struct ship *s; 36916082Sedward struct ship *bestship; 37016082Sedward float net, best = 0.0; 37116082Sedward foreachship(s) { 37216082Sedward if (*s->file->captain) 37316082Sedward continue; 37416082Sedward net = (float)s->file->points / s->specs->pts; 37516082Sedward if (net > best) { 37616082Sedward best = net; 37716082Sedward bestship = s; 37816082Sedward } 37916082Sedward } 38016082Sedward if (best > 0.0) { 38116082Sedward char *p = getenv("WOTD"); 38216082Sedward if (p == 0) 38316082Sedward p = "Driver"; 38416102Sedward if (islower(*p)) 38516102Sedward *p = toupper(*p); 38618767Sedward (void) strncpy(bestship->file->captain, p, 38716129Sedward sizeof bestship->file->captain); 38816129Sedward bestship->file->captain 38916129Sedward [sizeof bestship->file->captain - 1] = 0; 39016082Sedward log(bestship); 39116082Sedward } 39218772Sedward return -1; 39311589Sleres } 39414007Sedward Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0); 39518772Sedward if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) { 39618772Sedward switch (die()) { 39718772Sedward case 1: 39818772Sedward winddir = 1; 39918772Sedward break; 40018772Sedward case 2: 40118772Sedward break; 40218772Sedward case 3: 40318772Sedward winddir++; 40418772Sedward break; 40518772Sedward case 4: 40618772Sedward winddir--; 40718772Sedward break; 40818772Sedward case 5: 40918772Sedward winddir += 2; 41018772Sedward break; 41118772Sedward case 6: 41218772Sedward winddir -= 2; 41318772Sedward break; 41418772Sedward } 41518772Sedward if (winddir > 8) 41618772Sedward winddir -= 8; 41718772Sedward if (winddir < 1) 41818772Sedward winddir += 8; 41918772Sedward if (windspeed) 42014007Sedward switch (die()) { 42114007Sedward case 1: 42214007Sedward case 2: 42318772Sedward windspeed--; 42414007Sedward break; 42514007Sedward case 5: 42614007Sedward case 6: 42718772Sedward windspeed++; 42814007Sedward break; 42914007Sedward } 43018772Sedward else 43118772Sedward windspeed++; 43218772Sedward Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0); 43311589Sleres } 43418772Sedward return 0; 43511589Sleres } 436