1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: #include <sys/cdefs.h>
33: #ifndef lint
34: #if 0
35: static char sccsid[] = "@(#)dr_3.c 8.1 (Berkeley) 5/31/93";
36: #else
37: __RCSID("$NetBSD: dr_3.c,v 1.15 2003/08/07 09:37:42 agc Exp $");
38: #endif
39: #endif
40:
41: #include <stdlib.h>
42: #include <string.h>
43: #include "extern.h"
44: #include "driver.h"
45:
46: static int stillmoving(int);
47: static int is_isolated(struct ship *);
48: static int push(struct ship *, struct ship *);
49: static void step(struct ship *, int, char *);
50:
51:
52: void
53: moveall(void)
54: {
55: struct ship *sp, *sq;
56: int n;
57: int k, l;
58: int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
59: char moved[NSHIP];
60:
61:
62:
63:
64: foreachship(sp) {
65: struct ship *closest;
66: int ma, ta;
67: char af;
68:
69: if (sp->file->captain[0] || sp->file->dir == 0)
70: continue;
71: if (!sp->file->struck && windspeed && !snagged(sp)
72: && sp->specs->crew3) {
73: ta = maxturns(sp, &af);
74: ma = maxmove(sp, sp->file->dir, 0);
75: closest = closestenemy(sp, 0, 0);
76: if (closest == 0)
77: *sp->file->movebuf = '\0';
78: else
79: closeon(sp, closest, sp->file->movebuf,
80: ta, ma, af);
81: } else
82: *sp->file->movebuf = '\0';
83: }
84:
85:
86:
87:
88:
89:
90: n = 0;
91: foreachship(sp) {
92: if (snagged(sp))
93: strcpy(sp->file->movebuf, "d");
94: else
95: if (*sp->file->movebuf != 'd')
96: strcat(sp->file->movebuf, "d");
97: row[n] = sp->file->row;
98: col[n] = sp->file->col;
99: dir[n] = sp->file->dir;
100: drift[n] = sp->file->drift;
101: moved[n] = 0;
102: n++;
103: }
104:
105:
106:
107:
108: for (k = 0; stillmoving(k); k++) {
109:
110:
111:
112:
113: n = 0;
114: foreachship(sp) {
115: if (!sp->file->movebuf[k])
116: sp->file->movebuf[k+1] = '\0';
117: else if (sp->file->dir)
118: step(sp, sp->file->movebuf[k], &moved[n]);
119: n++;
120: }
121:
122:
123:
124: n = 0;
125: foreachship(sp) {
126: if (sp->file->dir == 0 || is_isolated(sp))
127: goto cont1;
128: l = 0;
129: foreachship(sq) {
130: char snap = 0;
131:
132: if (sp == sq)
133: goto cont2;
134: if (sq->file->dir == 0)
135: goto cont2;
136: if (!push(sp, sq))
137: goto cont2;
138: if (snagged2(sp, sq) && range(sp, sq) > 1)
139: snap++;
140: if (!range(sp, sq) && !fouled2(sp, sq)) {
141: makesignal(sp, "collision with $$", sq);
142: if (dieroll() < 4) {
143: makesignal(sp, "fouled with $$",
144: sq);
145: Write(W_FOUL, sp, l, 0, 0, 0);
146: Write(W_FOUL, sq, n, 0, 0, 0);
147: }
148: snap++;
149: }
150: if (snap) {
151: sp->file->movebuf[k + 1] = 0;
152: sq->file->movebuf[k + 1] = 0;
153: sq->file->row = sp->file->row - 1;
154: if (sp->file->dir == 1
155: || sp->file->dir == 5)
156: sq->file->col =
157: sp->file->col - 1;
158: else
159: sq->file->col = sp->file->col;
160: sq->file->dir = sp->file->dir;
161: }
162: cont2:
163: l++;
164: }
165: cont1:
166: n++;
167: }
168: }
169:
170:
171:
172: n = 0;
173: foreachship(sp) {
174: if (sp->file->dir != 0) {
175: *sp->file->movebuf = 0;
176: if (row[n] != sp->file->row)
177: Write(W_ROW, sp, sp->file->row, 0, 0, 0);
178: if (col[n] != sp->file->col)
179: Write(W_COL, sp, sp->file->col, 0, 0, 0);
180: if (dir[n] != sp->file->dir)
181: Write(W_DIR, sp, sp->file->dir, 0, 0, 0);
182: if (drift[n] != sp->file->drift)
183: Write(W_DRIFT, sp, sp->file->drift, 0, 0, 0);
184: }
185: n++;
186: }
187: }
188:
189: static int
190: stillmoving(int k)
191: {
192: struct ship *sp;
193:
194: foreachship(sp)
195: if (sp->file->movebuf[k])
196: return 1;
197: return 0;
198: }
199:
200: static int
201: is_isolated(struct ship *ship)
202: {
203: struct ship *sp;
204:
205: foreachship(sp) {
206: if (ship != sp && range(ship, sp) <= 10)
207: return 0;
208: }
209: return 1;
210: }
211:
212: static int
213: push(struct ship *from, struct ship *to)
214: {
215: int bs, sb;
216:
217: sb = to->specs->guns;
218: bs = from->specs->guns;
219: if (sb > bs)
220: return 1;
221: if (sb < bs)
222: return 0;
223: return from < to;
224: }
225:
226: static void
227: step(struct ship *sp, int com, char *moved)
228: {
229: int dist;
230:
231: switch (com) {
232: case 'r':
233: if (++sp->file->dir == 9)
234: sp->file->dir = 1;
235: break;
236: case 'l':
237: if (--sp->file->dir == 0)
238: sp->file->dir = 8;
239: break;
240: case '0': case '1': case '2': case '3':
241: case '4': case '5': case '6': case '7':
242: if (sp->file->dir % 2 == 0)
243: dist = dtab[com - '0'];
244: else
245: dist = com - '0';
246: sp->file->row -= dr[sp->file->dir] * dist;
247: sp->file->col -= dc[sp->file->dir] * dist;
248: *moved = 1;
249: break;
250: case 'b':
251: break;
252: case 'd':
253: if (!*moved) {
254: if (windspeed != 0 && ++sp->file->drift > 2 &&
255: ((sp->specs->class >= 3 && !snagged(sp))
256: || (turn & 1) == 0)) {
257: sp->file->row -= dr[winddir];
258: sp->file->col -= dc[winddir];
259: }
260: } else
261: sp->file->drift = 0;
262: break;
263: }
264: }
265:
266: void
267: sendbp(struct ship *from, struct ship *to, int sections, int isdefense)
268: {
269: int n;
270: struct BP *bp;
271:
272: bp = isdefense ? from->file->DBP : from->file->OBP;
273: for (n = 0; n < NBP && bp[n].turnsent; n++)
274: ;
275: if (n < NBP && sections) {
276: Write(isdefense ? W_DBP : W_OBP, from,
277: n, turn, to->file->index, sections);
278: if (isdefense)
279: makemsg(from, "repelling boarders");
280: else
281: makesignal(from, "boarding the $$", to);
282: }
283: }
284:
285: int
286: is_toughmelee(struct ship *ship, struct ship *to, int isdefense, int count)
287: {
288: struct BP *bp;
289: int obp = 0;
290: int n, OBP = 0, DBP = 0, dbp = 0;
291: int qual;
292:
293: qual = ship->specs->qual;
294: bp = isdefense ? ship->file->DBP : ship->file->OBP;
295: for (n = 0; n < NBP; n++, bp++) {
296: if (bp->turnsent && (to == bp->toship || isdefense)) {
297: obp += bp->mensent / 100
298: ? ship->specs->crew1 * qual : 0;
299: obp += (bp->mensent % 100)/10
300: ? ship->specs->crew2 * qual : 0;
301: obp += bp->mensent % 10
302: ? ship->specs->crew3 * qual : 0;
303: }
304: }
305: if (count || isdefense)
306: return obp;
307: OBP = is_toughmelee(to, ship, 0, count + 1);
308: dbp = is_toughmelee(ship, to, 1, count + 1);
309: DBP = is_toughmelee(to, ship, 1, count + 1);
310: if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
311: return 1;
312: else
313: return 0;
314: }
315:
316: void
317: reload(void)
318: {
319: struct ship *sp;
320:
321: foreachship(sp) {
322: sp->file->loadwith = 0;
323: }
324: }
325:
326: void
327: checksails(void)
328: {
329: struct ship *sp;
330: int rig, full;
331: struct ship *close;
332:
333: foreachship(sp) {
334: if (sp->file->captain[0] != 0)
335: continue;
336: rig = sp->specs->rig1;
337: if (windspeed == 6 || (windspeed == 5 && sp->specs->class > 4))
338: rig = 0;
339: if (rig && sp->specs->crew3) {
340: close = closestenemy(sp, 0, 0);
341: if (close != 0) {
342: if (range(sp, close) > 9)
343: full = 1;
344: else
345: full = 0;
346: } else
347: full = 0;
348: } else
349: full = 0;
350: if ((sp->file->FS != 0) != full)
351: Write(W_FS, sp, full, 0, 0, 0);
352: }
353: }