1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)dr_1.c 5.1 (Berkeley) 5/29/85"; 9: #endif not lint 10: 11: #include "driver.h" 12: 13: unfoul() 14: { 15: register struct ship *sp; 16: struct ship *to; 17: register int nat; 18: register i; 19: 20: foreachship(sp) { 21: if (sp->file->captain[0]) 22: continue; 23: nat = capship(sp)->nationality; 24: foreachship(to) { 25: if (nat != capship(to)->nationality && 26: !toughmelee(sp, to, 0, 0)) 27: continue; 28: for (i = fouled2(sp, to); --i >= 0;) 29: if (die() <= 2) 30: cleanfoul(sp, to, 0); 31: } 32: } 33: } 34: 35: boardcomp() 36: { 37: int crew[3]; 38: register struct ship *sp, *sq; 39: 40: foreachship(sp) { 41: if (*sp->file->captain) 42: continue; 43: if (sp->file->dir == 0) 44: continue; 45: if (sp->file->struck || sp->file->captured != 0) 46: continue; 47: if (!snagged(sp)) 48: continue; 49: crew[0] = sp->specs->crew1 != 0; 50: crew[1] = sp->specs->crew2 != 0; 51: crew[2] = sp->specs->crew3 != 0; 52: foreachship(sq) { 53: if (!Xsnagged2(sp, sq)) 54: continue; 55: if (meleeing(sp, sq)) 56: continue; 57: if (!sq->file->dir 58: || sp->nationality == capship(sq)->nationality) 59: continue; 60: switch (sp->specs->class - sq->specs->class) { 61: case -3: case -4: case -5: 62: if (crew[0]) { 63: /* OBP */ 64: sendbp(sp, sq, crew[0]*100, 0); 65: crew[0] = 0; 66: } else if (crew[1]){ 67: /* OBP */ 68: sendbp(sp, sq, crew[1]*10, 0); 69: crew[1] = 0; 70: } 71: break; 72: case -2: 73: if (crew[0] || crew[1]) { 74: /* OBP */ 75: sendbp(sp, sq, crew[0]*100+crew[1]*10, 76: 0); 77: crew[0] = crew[1] = 0; 78: } 79: break; 80: case -1: case 0: case 1: 81: if (crew[0]) { 82: /* OBP */ 83: sendbp(sp, sq, crew[0]*100+crew[1]*10, 84: 0); 85: crew[0] = crew[1] = 0; 86: } 87: break; 88: case 2: case 3: case 4: case 5: 89: /* OBP */ 90: sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2], 91: 0); 92: crew[0] = crew[1] = crew[2] = 0; 93: break; 94: } 95: } 96: } 97: } 98: 99: fightitout(from, to, key) 100: struct ship *from, *to; 101: int key; 102: { 103: struct ship *fromcap, *tocap; 104: int crewfrom[3], crewto[3], menfrom, mento; 105: int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured; 106: int topoints; 107: int index, totalfrom = 0, totalto = 0; 108: int count; 109: char message[60]; 110: 111: menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key); 112: mento = mensent(to, from, crewto, &tocap, &pcto, 0); 113: if (fromcap == 0) 114: fromcap = from; 115: if (tocap == 0) 116: tocap = to; 117: if (key) { 118: if (!menfrom) { /* if crew surprised */ 119: if (fromcap == from) 120: menfrom = from->specs->crew1 121: + from->specs->crew2 122: + from->specs->crew3; 123: else 124: menfrom = from->file->pcrew; 125: } else { 126: menfrom *= 2; /* DBP's fight at an advantage */ 127: } 128: } 129: fromstrength = menfrom * fromcap->specs->qual; 130: strengthto = mento * tocap->specs->qual; 131: for (count = 0; 132: (fromstrength < strengthto * 3 && strengthto < fromstrength * 3 133: || fromstrength == -1) && count < 4; 134: count++) { 135: index = fromstrength/10; 136: if (index > 8) 137: index = 8; 138: toinjured = MT[index][2 - die() / 3]; 139: totalto += toinjured; 140: index = strengthto/10; 141: if (index > 8) 142: index = 8; 143: frominjured = MT[index][2 - die() / 3]; 144: totalfrom += frominjured; 145: menfrom -= frominjured; 146: mento -= toinjured; 147: fromstrength = menfrom * fromcap->specs->qual; 148: strengthto = mento * tocap->specs->qual; 149: } 150: if (fromstrength >= strengthto * 3 || count == 4) { 151: unboard(to, from, 0); 152: subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 153: subtract(to, totalto, crewto, tocap, pcto); 154: makesignal(from, "boarders from %s repelled", to); 155: (void) sprintf(message, "killed in melee: %d. %s: %d", 156: totalto, from->shipname, totalfrom); 157: Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 158: if (key) 159: return 1; 160: } else if (strengthto >= fromstrength * 3) { 161: unboard(from, to, 0); 162: subtract(from, totalfrom, crewfrom, fromcap, pcfrom); 163: subtract(to, totalto, crewto, tocap, pcto); 164: if (key) { 165: if (fromcap != from) 166: Write(W_POINTS, fromcap, 0, 167: fromcap->file->points - 168: from->file->struck 169: ? from->specs->pts 170: : 2 * from->specs->pts, 171: 0, 0, 0); 172: 173: /* ptr1 points to the shipspec for the ship that was just unboarded. 174: I guess that what is going on here is that the pointer is multiplied 175: or something. */ 176: 177: Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0); 178: topoints = 2 * from->specs->pts + to->file->points; 179: if (from->file->struck) 180: topoints -= from->specs->pts; 181: Write(W_POINTS, to, 0, topoints, 0, 0, 0); 182: mento = crewto[0] ? crewto[0] : crewto[1]; 183: if (mento) { 184: subtract(to, mento, crewto, tocap, pcto); 185: subtract(from, - mento, crewfrom, to, 0); 186: } 187: (void) sprintf(message, "captured by the %s!", 188: to->shipname); 189: Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0); 190: (void) sprintf(message, "killed in melee: %d. %s: %d", 191: totalto, from->shipname, totalfrom); 192: Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); 193: mento = 0; 194: return 0; 195: } 196: } 197: return 0; 198: } 199: 200: resolve() 201: { 202: int thwart; 203: register struct ship *sp, *sq; 204: 205: foreachship(sp) { 206: if (sp->file->dir == 0) 207: continue; 208: for (sq = sp + 1; sq < ls; sq++) 209: if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp)) 210: (void) fightitout(sp, sq, 0); 211: thwart = 2; 212: foreachship(sq) { 213: if (sq->file->dir && meleeing(sq, sp)) 214: thwart = fightitout(sp, sq, 1); 215: if (!thwart) 216: break; 217: } 218: if (!thwart) { 219: foreachship(sq) { 220: if (sq->file->dir && meleeing(sq, sp)) 221: unboard(sq, sp, 0); 222: unboard(sp, sq, 0); 223: } 224: unboard(sp, sp, 1); 225: } else if (thwart == 2) 226: unboard(sp, sp, 1); 227: } 228: } 229: 230: compcombat() 231: { 232: register n; 233: register struct ship *sp; 234: struct ship *closest; 235: int crew[3], men = 0, target, temp; 236: int r, guns, ready, load, car; 237: int index, rakehim, sternrake; 238: int shootat, hit; 239: 240: foreachship(sp) { 241: if (sp->file->captain[0] || sp->file->dir == 0) 242: continue; 243: crew[0] = sp->specs->crew1; 244: crew[1] = sp->specs->crew2; 245: crew[2] = sp->specs->crew3; 246: for (n = 0; n < 3; n++) { 247: if (sp->file->OBP[n].turnsent) 248: men += sp->file->OBP[n].mensent; 249: } 250: for (n = 0; n < 3; n++) { 251: if (sp->file->DBP[n].turnsent) 252: men += sp->file->DBP[n].mensent; 253: } 254: if (men){ 255: crew[0] = men/100 ? 0 : crew[0] != 0; 256: crew[1] = (men%100)/10 ? 0 : crew[1] != 0; 257: crew[2] = men%10 ? 0 : crew[2] != 0; 258: } 259: for (r = 0; r < 2; r++) { 260: if (!crew[2]) 261: continue; 262: if (sp->file->struck) 263: continue; 264: if (r) { 265: ready = sp->file->readyR; 266: guns = sp->specs->gunR; 267: car = sp->specs->carR; 268: } else { 269: ready = sp->file->readyL; 270: guns = sp->specs->gunL; 271: car = sp->specs->carL; 272: } 273: if (!guns && !car) 274: continue; 275: if ((ready & R_LOADED) == 0) 276: continue; 277: closest = closestenemy(sp, r ? 'r' : 'l', 0); 278: if (closest == 0) 279: continue; 280: if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1))) 281: continue; 282: if (closest->file->struck) 283: continue; 284: target = range(sp, closest); 285: if (target > 10) 286: continue; 287: if (!guns && target >= 3) 288: continue; 289: load = L_ROUND; 290: if (target == 1 && sp->file->loadwith == L_GRAPE) 291: load = L_GRAPE; 292: if (target <= 3 && closest->file->FS) 293: load = L_CHAIN; 294: if (target == 1 && load != L_GRAPE) 295: load = L_DOUBLE; 296: if (load > L_CHAIN && target < 6) 297: shootat = HULL; 298: else 299: shootat = RIGGING; 300: rakehim = gunsbear(sp, closest) 301: && !gunsbear(closest, sp); 302: temp = portside(closest, sp, 1) 303: - closest->file->dir + 1; 304: if (temp < 1) 305: temp += 8; 306: if (temp > 8) 307: temp -= 8; 308: sternrake = temp > 4 && temp < 6; 309: index = guns; 310: if (target < 3) 311: index += car; 312: index = (index - 1) / 3; 313: index = index > 8 ? 8 : index; 314: if (!rakehim) 315: hit = HDT[index][target-1]; 316: else 317: hit = HDTrake[index][target-1]; 318: if (rakehim && sternrake) 319: hit++; 320: hit += QUAL[index][capship(sp)->specs->qual - 1]; 321: for (n = 0; n < 3 && sp->file->captured == 0; n++) 322: if (!crew[n]) 323: if (index <= 5) 324: hit--; 325: else 326: hit -= 2; 327: if (ready & R_INITIAL) { 328: if (!r) 329: sp->file->readyL &= ~R_INITIAL; 330: else 331: sp->file->readyR &= ~R_INITIAL; 332: if (index <= 3) 333: hit++; 334: else 335: hit += 2; 336: } 337: if (sp->file->captured != 0) 338: if (index <= 1) 339: hit--; 340: else 341: hit -= 2; 342: hit += AMMO[index][load - 1]; 343: temp = sp->specs->class; 344: if ((temp >= 5 || temp == 1) && windspeed == 5) 345: hit--; 346: if (windspeed == 6 && temp == 4) 347: hit -= 2; 348: if (windspeed == 6 && temp <= 3) 349: hit--; 350: if (hit >= 0) { 351: if (load != L_GRAPE) 352: hit = hit > 10 ? 10 : hit; 353: table(shootat, load, hit, closest, sp, die()); 354: } 355: } 356: } 357: } 358: 359: next() 360: { 361: if (++turn % 55 == 0) 362: if (alive) 363: alive = 0; 364: else 365: people = 0; 366: if (people <= 0 || windspeed == 7) { 367: register struct ship *s; 368: struct ship *bestship; 369: float net, best = 0.0; 370: foreachship(s) { 371: if (*s->file->captain) 372: continue; 373: net = (float)s->file->points / s->specs->pts; 374: if (net > best) { 375: best = net; 376: bestship = s; 377: } 378: } 379: if (best > 0.0) { 380: char *p = getenv("WOTD"); 381: if (p == 0) 382: p = "Driver"; 383: if (islower(*p)) 384: *p = toupper(*p); 385: (void) strncpy(bestship->file->captain, p, 386: sizeof bestship->file->captain); 387: bestship->file->captain 388: [sizeof bestship->file->captain - 1] = 0; 389: log(bestship); 390: } 391: return -1; 392: } 393: Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0); 394: if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) { 395: switch (die()) { 396: case 1: 397: winddir = 1; 398: break; 399: case 2: 400: break; 401: case 3: 402: winddir++; 403: break; 404: case 4: 405: winddir--; 406: break; 407: case 5: 408: winddir += 2; 409: break; 410: case 6: 411: winddir -= 2; 412: break; 413: } 414: if (winddir > 8) 415: winddir -= 8; 416: if (winddir < 1) 417: winddir += 8; 418: if (windspeed) 419: switch (die()) { 420: case 1: 421: case 2: 422: windspeed--; 423: break; 424: case 5: 425: case 6: 426: windspeed++; 427: break; 428: } 429: else 430: windspeed++; 431: Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0); 432: } 433: return 0; 434: }