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_3.c 5.1 (Berkeley) 5/29/85"; 9: #endif not lint 10: 11: #include "driver.h" 12: 13: moveall() /* move all comp ships */ 14: { 15: register struct ship *sp, *sq; /* r11, r10 */ 16: register int n; /* r9 */ 17: register int k, l; /* r8, r7 */ 18: int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; 19: char moved[NSHIP]; 20: 21: /* 22: * first try to create moves for OUR ships 23: */ 24: foreachship(sp) { 25: struct ship *closest; 26: int ma, ta; 27: char af; 28: 29: if (sp->file->captain[0] || sp->file->dir == 0) 30: continue; 31: if (!sp->file->struck && windspeed && !snagged(sp) 32: && sp->specs->crew3) { 33: ta = maxturns(sp, &af); 34: ma = maxmove(sp, sp->file->dir, 0); 35: closest = closestenemy(sp, 0, 0); 36: if (closest == 0) 37: *sp->file->movebuf = '\0'; 38: else 39: closeon(sp, closest, sp->file->movebuf, 40: ta, ma, af); 41: } else 42: *sp->file->movebuf = '\0'; 43: } 44: /* 45: * Then execute the moves for ALL ships (dead ones too), 46: * checking for collisions and snags at each step. 47: * The old positions are saved in row[], col[], dir[]. 48: * At the end, we compare and write out the changes. 49: */ 50: n = 0; 51: foreachship(sp) { 52: if (snagged(sp)) 53: (void) strcpy(sp->file->movebuf, "d"); 54: else 55: if (*sp->file->movebuf != 'd') 56: (void) strcat(sp->file->movebuf, "d"); 57: row[n] = sp->file->row; 58: col[n] = sp->file->col; 59: dir[n] = sp->file->dir; 60: drift[n] = sp->file->drift; 61: moved[n] = 0; 62: n++; 63: } 64: /* 65: * Now resolve collisions. 66: * This is the tough part. 67: */ 68: for (k = 0; stillmoving(k); k++) { 69: /* 70: * Step once. 71: * And propagate the nulls at the end of sp->file->movebuf. 72: */ 73: n = 0; 74: foreachship(sp) { 75: if (!sp->file->movebuf[k]) 76: sp->file->movebuf[k+1] = '\0'; 77: else if (sp->file->dir) 78: step(sp->file->movebuf[k], sp, &moved[n]); 79: n++; 80: } 81: /* 82: * The real stuff. 83: */ 84: n = 0; 85: foreachship(sp) { 86: if (sp->file->dir == 0 || isolated(sp)) 87: goto cont1; 88: l = 0; 89: foreachship(sq) { 90: char snap = 0; 91: 92: if (sp == sq) 93: goto cont2; 94: if (sq->file->dir == 0) 95: goto cont2; 96: if (!push(sp, sq)) 97: goto cont2; 98: if (snagged2(sp, sq) && range(sp, sq) > 1) 99: snap++; 100: if (!range(sp, sq) && !fouled2(sp, sq)) { 101: makesignal(sp, 102: "collision with %s (%c%c)", sq); 103: if (die() < 4) { 104: makesignal(sp, 105: "fouled with %s (%c%c)", 106: sq); 107: Write(W_FOUL, sp, 0, l, 0, 0, 0); 108: Write(W_FOUL, sq, 0, n, 0, 0, 0); 109: } 110: snap++; 111: } 112: if (snap) { 113: sp->file->movebuf[k + 1] = 0; 114: sq->file->movebuf[k + 1] = 0; 115: sq->file->row = sp->file->row - 1; 116: if (sp->file->dir == 1 117: || sp->file->dir == 5) 118: sq->file->col = 119: sp->file->col - 1; 120: else 121: sq->file->col = sp->file->col; 122: sq->file->dir = sp->file->dir; 123: } 124: cont2: 125: l++; 126: } 127: cont1: 128: n++; 129: } 130: } 131: /* 132: * Clear old moves. And write out new pos. 133: */ 134: n = 0; 135: foreachship(sp) { 136: if (sp->file->dir != 0) { 137: *sp->file->movebuf = 0; 138: if (row[n] != sp->file->row) 139: Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0); 140: if (col[n] != sp->file->col) 141: Write(W_COL, sp, 0, sp->file->col, 0, 0, 0); 142: if (dir[n] != sp->file->dir) 143: Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0); 144: if (drift[n] != sp->file->drift) 145: Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0); 146: } 147: n++; 148: } 149: } 150: 151: stillmoving(k) 152: register int k; 153: { 154: register struct ship *sp; 155: 156: foreachship(sp) 157: if (sp->file->movebuf[k]) 158: return 1; 159: return 0; 160: } 161: 162: isolated(ship) 163: register struct ship *ship; 164: { 165: register struct ship *sp; 166: 167: foreachship(sp) { 168: if (ship != sp && range(ship, sp) <= 10) 169: return 0; 170: } 171: return 1; 172: } 173: 174: push(from, to) 175: register struct ship *from, *to; 176: { 177: register int bs, sb; 178: 179: sb = to->specs->guns; 180: bs = from->specs->guns; 181: if (sb > bs) 182: return 1; 183: if (sb < bs) 184: return 0; 185: return from < to; 186: } 187: 188: step(com, sp, moved) 189: char com; 190: register struct ship *sp; 191: char *moved; 192: { 193: register int dist; 194: 195: switch (com) { 196: case 'r': 197: if (++sp->file->dir == 9) 198: sp->file->dir = 1; 199: break; 200: case 'l': 201: if (--sp->file->dir == 0) 202: sp->file->dir = 8; 203: break; 204: case '0': case '1': case '2': case '3': 205: case '4': case '5': case '6': case '7': 206: if (sp->file->dir % 2 == 0) 207: dist = dtab[com - '0']; 208: else 209: dist = com - '0'; 210: sp->file->row -= dr[sp->file->dir] * dist; 211: sp->file->col -= dc[sp->file->dir] * dist; 212: *moved = 1; 213: break; 214: case 'b': 215: break; 216: case 'd': 217: if (!*moved) { 218: if (windspeed != 0 && ++sp->file->drift > 2 && 219: (sp->specs->class >= 3 && !snagged(sp) 220: || (turn & 1) == 0)) { 221: sp->file->row -= dr[winddir]; 222: sp->file->col -= dc[winddir]; 223: } 224: } else 225: sp->file->drift = 0; 226: break; 227: } 228: } 229: 230: sendbp(from, to, sections, isdefense) 231: register struct ship *from, *to; 232: int sections; 233: char isdefense; 234: { 235: int n; 236: register struct BP *bp; 237: 238: bp = isdefense ? from->file->DBP : from->file->OBP; 239: for (n = 0; n < NBP && bp[n].turnsent; n++) 240: ; 241: if (n < NBP && sections) { 242: Write(isdefense ? W_DBP : W_OBP, from, 0, 243: n, turn, to->file->index, sections); 244: if (isdefense) 245: makesignal(from, "repelling boarders", 246: (struct ship *)0); 247: else 248: makesignal(from, "boarding the %s (%c%c)", to); 249: } 250: } 251: 252: toughmelee(ship, to, isdefense, count) 253: register struct ship *ship, *to; 254: int isdefense, count; 255: { 256: register struct BP *bp; 257: register obp = 0; 258: int n, OBP = 0, DBP = 0, dbp = 0; 259: int qual; 260: 261: qual = ship->specs->qual; 262: bp = isdefense ? ship->file->DBP : ship->file->OBP; 263: for (n = 0; n < NBP; n++, bp++) { 264: if (bp->turnsent && (to == bp->toship || isdefense)) { 265: obp += bp->mensent / 100 266: ? ship->specs->crew1 * qual : 0; 267: obp += (bp->mensent % 100)/10 268: ? ship->specs->crew2 * qual : 0; 269: obp += bp->mensent % 10 270: ? ship->specs->crew3 * qual : 0; 271: } 272: } 273: if (count || isdefense) 274: return obp; 275: OBP = toughmelee(to, ship, 0, count + 1); 276: dbp = toughmelee(ship, to, 1, count + 1); 277: DBP = toughmelee(to, ship, 1, count + 1); 278: if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) 279: return 1; 280: else 281: return 0; 282: } 283: 284: reload() 285: { 286: register struct ship *sp; 287: 288: foreachship(sp) { 289: sp->file->loadwith = 0; 290: } 291: } 292: 293: checksails() 294: { 295: register struct ship *sp; 296: register int rig, full; 297: struct ship *close; 298: 299: foreachship(sp) { 300: if (sp->file->captain[0] != 0) 301: continue; 302: rig = sp->specs->rig1; 303: if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4) 304: rig = 0; 305: if (rig && sp->specs->crew3) { 306: close = closestenemy(sp, 0, 0); 307: if (close != 0) { 308: if (range(sp, close) > 9) 309: full = 1; 310: else 311: full = 0; 312: } else 313: full = 0; 314: } else 315: full = 0; 316: if ((sp->file->FS != 0) != full) 317: Write(W_FS, sp, 0, full, 0, 0, 0); 318: } 319: }