| 1 | #ifndef lint |
| 2 | static char *sccsid = "@(#)dr_2.c 1.6 83/10/27"; |
| 3 | #endif |
| 4 | |
| 5 | #include "driver.h" |
| 6 | |
| 7 | #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5) |
| 8 | |
| 9 | thinkofgrapples() |
| 10 | { |
| 11 | register struct ship *sp, *sq; |
| 12 | char friendly; |
| 13 | |
| 14 | foreachship(sp) { |
| 15 | if (sp->file->captain[0] || sp->file->dir == 0) |
| 16 | continue; |
| 17 | foreachship(sq) { |
| 18 | friendly = sp->nationality == capship(sq)->nationality; |
| 19 | if (!friendly) { |
| 20 | if (sp->file->struck || sp->file->captured != 0) |
| 21 | continue; |
| 22 | if (range(sp, sq) != 1) |
| 23 | continue; |
| 24 | if (grappled2(sp, sq)) |
| 25 | if (toughmelee(sp, sq, 0, 0)) |
| 26 | ungrap(sp, sq); |
| 27 | else |
| 28 | grap(sp, sq); |
| 29 | else if (couldwin(sp, sq)) { |
| 30 | grap(sp, sq); |
| 31 | sp->file->loadwith = L_GRAPE; |
| 32 | } |
| 33 | } else |
| 34 | ungrap(sp, sq); |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | checkup() |
| 40 | { |
| 41 | register int k; |
| 42 | register struct ship *sp, *sq; |
| 43 | register char explode, sink; |
| 44 | |
| 45 | /* |
| 46 | readpos(); |
| 47 | */ |
| 48 | foreachship(sp) { |
| 49 | explode = sp->file->explode; |
| 50 | sink = sp->file->sink; |
| 51 | if (die() < 5) |
| 52 | continue; |
| 53 | if (explode != 1 && sink != 1) |
| 54 | continue; |
| 55 | Write(sink ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0); |
| 56 | sp->file->dir = 0; /* hopefully enough to kill ship */ |
| 57 | /* Write(n, 0, 10, 0); XXX */ |
| 58 | Write(W_CLASS, sp, 0, 0, 0, 0, 0); |
| 59 | if (fouled(sp) || grappled(sp)) { |
| 60 | for (k = 0; k < NSHIP; k++) { |
| 61 | if (sp->file->fouls[k].turnfoul) |
| 62 | cleanfoul(sp, |
| 63 | sp->file->fouls[k].toship, k); |
| 64 | } |
| 65 | for (k = 0; k < NSHIP; k++) { |
| 66 | if (sp->file->grapples[k].turnfoul) |
| 67 | cleangrapple(sp, |
| 68 | sp->file->grapples[k].toship, |
| 69 | k); |
| 70 | } |
| 71 | } |
| 72 | if (sink != 1) { |
| 73 | makesignal(sp, "exploding!", (struct ship *)0); |
| 74 | foreachship(sq) { |
| 75 | if (sp != sq && sq->file->dir && range(sp, sq) < 4) |
| 76 | table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6); |
| 77 | } |
| 78 | } else |
| 79 | makesignal(sp, "sinking!", (struct ship *)0); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | prizecheck() |
| 84 | { |
| 85 | register struct ship *sp; |
| 86 | register int prisoners, points; |
| 87 | |
| 88 | foreachship(sp) { |
| 89 | if (sp->file->captured == 0) |
| 90 | continue; |
| 91 | if (sp->file->struck || sp->file->dir == 0) |
| 92 | continue; |
| 93 | prisoners = sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3; |
| 94 | if (prisoners > sp->file->pcrew * 6) { |
| 95 | Write(W_CAPTURED, sp, 0, -1, 0, 0, 0); |
| 96 | Write(W_SIGNAL, sp, 1, |
| 97 | (int)"prize crew overthrown", 0, 0, 0); |
| 98 | points = sp->file->captured->file->points |
| 99 | - 2 * sp->specs->pts; |
| 100 | Write(W_POINTS, sp->file->captured, 0, points, 0, 0, 0); |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | strend(str) |
| 106 | char *str; |
| 107 | { |
| 108 | register char *p; |
| 109 | |
| 110 | for (p = str; *p; p++) |
| 111 | ; |
| 112 | return p == str ? 0 : p[-1]; |
| 113 | } |
| 114 | |
| 115 | closeon(from, to, command, ta, ma, af) |
| 116 | register struct ship *from, *to; |
| 117 | char command[]; |
| 118 | int ma, ta, af; |
| 119 | { |
| 120 | int high; |
| 121 | char temp[10]; |
| 122 | |
| 123 | temp[0] = command[0] = '\0'; |
| 124 | high = -30000; |
| 125 | try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0); |
| 126 | } |
| 127 | |
| 128 | int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */ |
| 129 | |
| 130 | score(movement, ship, to, onlytemp) |
| 131 | char movement[]; |
| 132 | register struct ship *ship, *to; |
| 133 | char onlytemp; |
| 134 | { |
| 135 | char drift; |
| 136 | int row, col, dir, total, ran; |
| 137 | register struct File *fp = ship->file; |
| 138 | |
| 139 | if ((dir = fp->dir) == 0) |
| 140 | return 0; |
| 141 | row = fp->row; |
| 142 | col = fp->col; |
| 143 | drift = fp->drift; |
| 144 | move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift); |
| 145 | if (!*movement) |
| 146 | (void) strcpy(movement, "d"); |
| 147 | |
| 148 | ran = range(ship, to); |
| 149 | total = -50 * ran; |
| 150 | if (ran < 4 && gunsbear(ship, to)) |
| 151 | total += 60; |
| 152 | if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4) |
| 153 | total = -30000; |
| 154 | |
| 155 | if (!onlytemp) { |
| 156 | fp->row = row; |
| 157 | fp->col = col; |
| 158 | fp->dir = dir; |
| 159 | } |
| 160 | return total; |
| 161 | } |
| 162 | |
| 163 | moveship(ship, movement) |
| 164 | struct ship *ship; |
| 165 | char *movement; |
| 166 | { |
| 167 | register struct File *fp = ship->file; |
| 168 | char drift = fp->drift; |
| 169 | int row = fp->row; |
| 170 | int col = fp->col; |
| 171 | int dir = fp->dir; |
| 172 | |
| 173 | if (fp->dir == 0) |
| 174 | return; |
| 175 | move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift); |
| 176 | if (drift > 2 || *movement == 0) |
| 177 | (void) strcat(movement, "d"); |
| 178 | if (fp->drift != drift) |
| 179 | Write(W_DRIFT, ship, 0, drift, 0, 0, 0); |
| 180 | if (fp->row != row) |
| 181 | Write(W_SHIPROW, ship, 0, fp->row, 0, 0, 0); |
| 182 | if (fp->col != col) |
| 183 | Write(W_SHIPCOL, ship, 0, fp->col, 0, 0, 0); |
| 184 | if (fp->dir != dir) |
| 185 | Write(W_SHIPDIR, ship, 0, fp->dir, 0, 0, 0); |
| 186 | } |
| 187 | |
| 188 | move(p, ship, dir, row, col, drift) |
| 189 | register char *p; |
| 190 | register struct ship *ship; |
| 191 | register char *dir; |
| 192 | register short *row, *col; |
| 193 | register char *drift; |
| 194 | { |
| 195 | int dist; |
| 196 | char moved = 0; |
| 197 | |
| 198 | for (; *p; p++) { |
| 199 | switch (*p) { |
| 200 | case 'r': |
| 201 | if (++*dir == 9) |
| 202 | *dir = 1; |
| 203 | break; |
| 204 | case 'l': |
| 205 | if (--*dir == 0) |
| 206 | *dir = 8; |
| 207 | break; |
| 208 | case '1': case '2': case '3': case '4': |
| 209 | case '5': case '6': case '7': |
| 210 | moved++; |
| 211 | if (*dir % 2 == 0) |
| 212 | dist = dtab[*p - '0']; |
| 213 | else |
| 214 | dist = *p - '0'; |
| 215 | *row -= dr[*dir] * dist; |
| 216 | *col -= dc[*dir] * dist; |
| 217 | break; |
| 218 | } |
| 219 | } |
| 220 | if (!windspeed) |
| 221 | *drift = 1; |
| 222 | if (!moved) { |
| 223 | if (++*drift > 2) { |
| 224 | if (ship->specs->class >= 3 && !snagged(ship) |
| 225 | || (turn & 1) == 0) { |
| 226 | *row -= dr[winddir]; |
| 227 | *col -= dc[winddir]; |
| 228 | } |
| 229 | } |
| 230 | } else |
| 231 | *drift = 0; |
| 232 | } |
| 233 | |
| 234 | try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme) |
| 235 | register struct ship *f, *t; |
| 236 | int ma, ta, af, *high, rakeme; |
| 237 | char command[], temp[]; |
| 238 | { |
| 239 | register int new, n; |
| 240 | char st[4]; |
| 241 | #define rakeyou (gunsbear(f, t) && !gunsbear(t, f)) |
| 242 | |
| 243 | if ((n = strend(temp)) < '1' || n > '9') |
| 244 | for (n = 1; vma - n >= 0; n++) { |
| 245 | (void) sprintf(st, "%d", n); |
| 246 | (void) strcat(temp, st); |
| 247 | new = score(temp, f, t, rakeme); |
| 248 | if (new > *high && (!rakeme || rakeyou)) { |
| 249 | *high = new; |
| 250 | (void) strcpy(command, temp); |
| 251 | } |
| 252 | try(command, temp, ma-n, ta, af, vma-n, |
| 253 | dir, f, t, high, rakeme); |
| 254 | rmend(temp); |
| 255 | } |
| 256 | if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) { |
| 257 | (void) strcat(temp, "r"); |
| 258 | new = score(temp, f, t, rakeme); |
| 259 | if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) { |
| 260 | *high = new; |
| 261 | (void) strcpy(command, temp); |
| 262 | } |
| 263 | try(command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1),f,t,high,rakeme); |
| 264 | rmend(temp); |
| 265 | } |
| 266 | if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){ |
| 267 | (void) strcat(temp, "l"); |
| 268 | new = score(temp, f, t, rakeme); |
| 269 | if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){ |
| 270 | *high = new; |
| 271 | (void) strcpy(command, temp); |
| 272 | } |
| 273 | try(command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), f, t, high, rakeme); |
| 274 | rmend(temp); |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | rmend(str) |
| 279 | char *str; |
| 280 | { |
| 281 | register char *p; |
| 282 | |
| 283 | for (p = str; *p; p++) |
| 284 | ; |
| 285 | if (p != str) |
| 286 | *--p = 0; |
| 287 | } |