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