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