1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char sccsid[] = "@(#)dr_2.c 5.4 (Berkeley) 6/1/90"; 36 #endif /* not lint */ 37 38 #include "driver.h" 39 40 #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5) 41 42 thinkofgrapples() 43 { 44 register struct ship *sp, *sq; 45 char friendly; 46 47 foreachship(sp) { 48 if (sp->file->captain[0] || sp->file->dir == 0) 49 continue; 50 foreachship(sq) { 51 friendly = sp->nationality == capship(sq)->nationality; 52 if (!friendly) { 53 if (sp->file->struck || sp->file->captured != 0) 54 continue; 55 if (range(sp, sq) != 1) 56 continue; 57 if (grappled2(sp, sq)) 58 if (toughmelee(sp, sq, 0, 0)) 59 ungrap(sp, sq); 60 else 61 grap(sp, sq); 62 else if (couldwin(sp, sq)) { 63 grap(sp, sq); 64 sp->file->loadwith = L_GRAPE; 65 } 66 } else 67 ungrap(sp, sq); 68 } 69 } 70 } 71 72 checkup() 73 { 74 register struct ship *sp, *sq; 75 register char explode, sink; 76 77 foreachship(sp) { 78 if (sp->file->dir == 0) 79 continue; 80 explode = sp->file->explode; 81 sink = sp->file->sink; 82 if (explode != 1 && sink != 1) 83 continue; 84 if (die() < 5) 85 continue; 86 Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0); 87 Write(W_DIR, sp, 0, 0, 0, 0, 0); 88 if (snagged(sp)) 89 foreachship(sq) 90 cleansnag(sp, sq, 1); 91 if (sink != 1) { 92 makesignal(sp, "exploding!", (struct ship *)0); 93 foreachship(sq) { 94 if (sp != sq && sq->file->dir && range(sp, sq) < 4) 95 table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6); 96 } 97 } else 98 makesignal(sp, "sinking!", (struct ship *)0); 99 } 100 } 101 102 prizecheck() 103 { 104 register struct ship *sp; 105 106 foreachship(sp) { 107 if (sp->file->captured == 0) 108 continue; 109 if (sp->file->struck || sp->file->dir == 0) 110 continue; 111 if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) { 112 Write(W_SIGNAL, sp, 1, 113 (int)"prize crew overthrown", 0, 0, 0); 114 Write(W_POINTS, sp->file->captured, 0, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0); 115 Write(W_CAPTURED, sp, 0, -1, 0, 0, 0); 116 } 117 } 118 } 119 120 strend(str) 121 char *str; 122 { 123 register char *p; 124 125 for (p = str; *p; p++) 126 ; 127 return p == str ? 0 : p[-1]; 128 } 129 130 closeon(from, to, command, ta, ma, af) 131 register struct ship *from, *to; 132 char command[]; 133 int ma, ta, af; 134 { 135 int high; 136 char temp[10]; 137 138 temp[0] = command[0] = '\0'; 139 high = -30000; 140 try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0); 141 } 142 143 int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */ 144 145 score(movement, ship, to, onlytemp) 146 char movement[]; 147 register struct ship *ship, *to; 148 char onlytemp; 149 { 150 char drift; 151 int row, col, dir, total, ran; 152 register struct File *fp = ship->file; 153 154 if ((dir = fp->dir) == 0) 155 return 0; 156 row = fp->row; 157 col = fp->col; 158 drift = fp->drift; 159 move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift); 160 if (!*movement) 161 (void) strcpy(movement, "d"); 162 163 ran = range(ship, to); 164 total = -50 * ran; 165 if (ran < 4 && gunsbear(ship, to)) 166 total += 60; 167 if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4) 168 total = -30000; 169 170 if (!onlytemp) { 171 fp->row = row; 172 fp->col = col; 173 fp->dir = dir; 174 } 175 return total; 176 } 177 178 move(p, ship, dir, row, col, drift) 179 register char *p; 180 register struct ship *ship; 181 register char *dir; 182 register short *row, *col; 183 register char *drift; 184 { 185 int dist; 186 char moved = 0; 187 188 for (; *p; p++) { 189 switch (*p) { 190 case 'r': 191 if (++*dir == 9) 192 *dir = 1; 193 break; 194 case 'l': 195 if (--*dir == 0) 196 *dir = 8; 197 break; 198 case '1': case '2': case '3': case '4': 199 case '5': case '6': case '7': 200 moved++; 201 if (*dir % 2 == 0) 202 dist = dtab[*p - '0']; 203 else 204 dist = *p - '0'; 205 *row -= dr[*dir] * dist; 206 *col -= dc[*dir] * dist; 207 break; 208 } 209 } 210 if (!moved) { 211 if (windspeed != 0 && ++*drift > 2) { 212 if (ship->specs->class >= 3 && !snagged(ship) 213 || (turn & 1) == 0) { 214 *row -= dr[winddir]; 215 *col -= dc[winddir]; 216 } 217 } 218 } else 219 *drift = 0; 220 } 221 222 try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme) 223 register struct ship *f, *t; 224 int ma, ta, af, *high, rakeme; 225 char command[], temp[]; 226 { 227 register int new, n; 228 char st[4]; 229 #define rakeyou (gunsbear(f, t) && !gunsbear(t, f)) 230 231 if ((n = strend(temp)) < '1' || n > '9') 232 for (n = 1; vma - n >= 0; n++) { 233 (void) sprintf(st, "%d", n); 234 (void) strcat(temp, st); 235 new = score(temp, f, t, rakeme); 236 if (new > *high && (!rakeme || rakeyou)) { 237 *high = new; 238 (void) strcpy(command, temp); 239 } 240 try(command, temp, ma-n, ta, af, vma-n, 241 dir, f, t, high, rakeme); 242 rmend(temp); 243 } 244 if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) { 245 (void) strcat(temp, "r"); 246 new = score(temp, f, t, rakeme); 247 if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) { 248 *high = new; 249 (void) strcpy(command, temp); 250 } 251 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); 252 rmend(temp); 253 } 254 if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){ 255 (void) strcat(temp, "l"); 256 new = score(temp, f, t, rakeme); 257 if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){ 258 *high = new; 259 (void) strcpy(command, temp); 260 } 261 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); 262 rmend(temp); 263 } 264 } 265 266 rmend(str) 267 char *str; 268 { 269 register char *p; 270 271 for (p = str; *p; p++) 272 ; 273 if (p != str) 274 *--p = 0; 275 } 276