|
|
1.1 root 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 are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)dr_3.c 5.4 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: #include "driver.h"
25:
26: moveall() /* move all comp ships */
27: {
28: register struct ship *sp, *sq; /* r11, r10 */
29: register int n; /* r9 */
30: register int k, l; /* r8, r7 */
31: int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
32: char moved[NSHIP];
33:
34: /*
35: * first try to create moves for OUR ships
36: */
37: foreachship(sp) {
38: struct ship *closest;
39: int ma, ta;
40: char af;
41:
42: if (sp->file->captain[0] || sp->file->dir == 0)
43: continue;
44: if (!sp->file->struck && windspeed && !snagged(sp)
45: && sp->specs->crew3) {
46: ta = maxturns(sp, &af);
47: ma = maxmove(sp, sp->file->dir, 0);
48: closest = closestenemy(sp, 0, 0);
49: if (closest == 0)
50: *sp->file->movebuf = '\0';
51: else
52: closeon(sp, closest, sp->file->movebuf,
53: ta, ma, af);
54: } else
55: *sp->file->movebuf = '\0';
56: }
57: /*
58: * Then execute the moves for ALL ships (dead ones too),
59: * checking for collisions and snags at each step.
60: * The old positions are saved in row[], col[], dir[].
61: * At the end, we compare and write out the changes.
62: */
63: n = 0;
64: foreachship(sp) {
65: if (snagged(sp))
66: (void) strcpy(sp->file->movebuf, "d");
67: else
68: if (*sp->file->movebuf != 'd')
69: (void) strcat(sp->file->movebuf, "d");
70: row[n] = sp->file->row;
71: col[n] = sp->file->col;
72: dir[n] = sp->file->dir;
73: drift[n] = sp->file->drift;
74: moved[n] = 0;
75: n++;
76: }
77: /*
78: * Now resolve collisions.
79: * This is the tough part.
80: */
81: for (k = 0; stillmoving(k); k++) {
82: /*
83: * Step once.
84: * And propagate the nulls at the end of sp->file->movebuf.
85: */
86: n = 0;
87: foreachship(sp) {
88: if (!sp->file->movebuf[k])
89: sp->file->movebuf[k+1] = '\0';
90: else if (sp->file->dir)
91: step(sp->file->movebuf[k], sp, &moved[n]);
92: n++;
93: }
94: /*
95: * The real stuff.
96: */
97: n = 0;
98: foreachship(sp) {
99: if (sp->file->dir == 0 || isolated(sp))
100: goto cont1;
101: l = 0;
102: foreachship(sq) {
103: char snap = 0;
104:
105: if (sp == sq)
106: goto cont2;
107: if (sq->file->dir == 0)
108: goto cont2;
109: if (!push(sp, sq))
110: goto cont2;
111: if (snagged2(sp, sq) && range(sp, sq) > 1)
112: snap++;
113: if (!range(sp, sq) && !fouled2(sp, sq)) {
114: makesignal(sp,
115: "collision with %s (%c%c)", sq);
116: if (die() < 4) {
117: makesignal(sp,
118: "fouled with %s (%c%c)",
119: sq);
120: Write(W_FOUL, sp, 0, l, 0, 0, 0);
121: Write(W_FOUL, sq, 0, n, 0, 0, 0);
122: }
123: snap++;
124: }
125: if (snap) {
126: sp->file->movebuf[k + 1] = 0;
127: sq->file->movebuf[k + 1] = 0;
128: sq->file->row = sp->file->row - 1;
129: if (sp->file->dir == 1
130: || sp->file->dir == 5)
131: sq->file->col =
132: sp->file->col - 1;
133: else
134: sq->file->col = sp->file->col;
135: sq->file->dir = sp->file->dir;
136: }
137: cont2:
138: l++;
139: }
140: cont1:
141: n++;
142: }
143: }
144: /*
145: * Clear old moves. And write out new pos.
146: */
147: n = 0;
148: foreachship(sp) {
149: if (sp->file->dir != 0) {
150: *sp->file->movebuf = 0;
151: if (row[n] != sp->file->row)
152: Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
153: if (col[n] != sp->file->col)
154: Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
155: if (dir[n] != sp->file->dir)
156: Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
157: if (drift[n] != sp->file->drift)
158: Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
159: }
160: n++;
161: }
162: }
163:
164: stillmoving(k)
165: register int k;
166: {
167: register struct ship *sp;
168:
169: foreachship(sp)
170: if (sp->file->movebuf[k])
171: return 1;
172: return 0;
173: }
174:
175: isolated(ship)
176: register struct ship *ship;
177: {
178: register struct ship *sp;
179:
180: foreachship(sp) {
181: if (ship != sp && range(ship, sp) <= 10)
182: return 0;
183: }
184: return 1;
185: }
186:
187: push(from, to)
188: register struct ship *from, *to;
189: {
190: register int bs, sb;
191:
192: sb = to->specs->guns;
193: bs = from->specs->guns;
194: if (sb > bs)
195: return 1;
196: if (sb < bs)
197: return 0;
198: return from < to;
199: }
200:
201: step(com, sp, moved)
202: char com;
203: register struct ship *sp;
204: char *moved;
205: {
206: register int dist;
207:
208: switch (com) {
209: case 'r':
210: if (++sp->file->dir == 9)
211: sp->file->dir = 1;
212: break;
213: case 'l':
214: if (--sp->file->dir == 0)
215: sp->file->dir = 8;
216: break;
217: case '0': case '1': case '2': case '3':
218: case '4': case '5': case '6': case '7':
219: if (sp->file->dir % 2 == 0)
220: dist = dtab[com - '0'];
221: else
222: dist = com - '0';
223: sp->file->row -= dr[sp->file->dir] * dist;
224: sp->file->col -= dc[sp->file->dir] * dist;
225: *moved = 1;
226: break;
227: case 'b':
228: break;
229: case 'd':
230: if (!*moved) {
231: if (windspeed != 0 && ++sp->file->drift > 2 &&
232: (sp->specs->class >= 3 && !snagged(sp)
233: || (turn & 1) == 0)) {
234: sp->file->row -= dr[winddir];
235: sp->file->col -= dc[winddir];
236: }
237: } else
238: sp->file->drift = 0;
239: break;
240: }
241: }
242:
243: sendbp(from, to, sections, isdefense)
244: register struct ship *from, *to;
245: int sections;
246: char isdefense;
247: {
248: int n;
249: register struct BP *bp;
250:
251: bp = isdefense ? from->file->DBP : from->file->OBP;
252: for (n = 0; n < NBP && bp[n].turnsent; n++)
253: ;
254: if (n < NBP && sections) {
255: Write(isdefense ? W_DBP : W_OBP, from, 0,
256: n, turn, to->file->index, sections);
257: if (isdefense)
258: makesignal(from, "repelling boarders",
259: (struct ship *)0);
260: else
261: makesignal(from, "boarding the %s (%c%c)", to);
262: }
263: }
264:
265: toughmelee(ship, to, isdefense, count)
266: register struct ship *ship, *to;
267: int isdefense, count;
268: {
269: register struct BP *bp;
270: register obp = 0;
271: int n, OBP = 0, DBP = 0, dbp = 0;
272: int qual;
273:
274: qual = ship->specs->qual;
275: bp = isdefense ? ship->file->DBP : ship->file->OBP;
276: for (n = 0; n < NBP; n++, bp++) {
277: if (bp->turnsent && (to == bp->toship || isdefense)) {
278: obp += bp->mensent / 100
279: ? ship->specs->crew1 * qual : 0;
280: obp += (bp->mensent % 100)/10
281: ? ship->specs->crew2 * qual : 0;
282: obp += bp->mensent % 10
283: ? ship->specs->crew3 * qual : 0;
284: }
285: }
286: if (count || isdefense)
287: return obp;
288: OBP = toughmelee(to, ship, 0, count + 1);
289: dbp = toughmelee(ship, to, 1, count + 1);
290: DBP = toughmelee(to, ship, 1, count + 1);
291: if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
292: return 1;
293: else
294: return 0;
295: }
296:
297: reload()
298: {
299: register struct ship *sp;
300:
301: foreachship(sp) {
302: sp->file->loadwith = 0;
303: }
304: }
305:
306: checksails()
307: {
308: register struct ship *sp;
309: register int rig, full;
310: struct ship *close;
311:
312: foreachship(sp) {
313: if (sp->file->captain[0] != 0)
314: continue;
315: rig = sp->specs->rig1;
316: if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
317: rig = 0;
318: if (rig && sp->specs->crew3) {
319: close = closestenemy(sp, 0, 0);
320: if (close != 0) {
321: if (range(sp, close) > 9)
322: full = 1;
323: else
324: full = 0;
325: } else
326: full = 0;
327: } else
328: full = 0;
329: if ((sp->file->FS != 0) != full)
330: Write(W_FS, sp, 0, full, 0, 0, 0);
331: }
332: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.