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