1 /* $NetBSD: dr_3.c,v 1.18 2009/03/14 20:04:43 dholland Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)dr_3.c 8.1 (Berkeley) 5/31/93";
37 __RCSID("$NetBSD: dr_3.c,v 1.18 2009/03/14 20:04:43 dholland Exp $");
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 *);
51 /* move all comp ships */
58 int row
[NSHIP
], col
[NSHIP
], dir
[NSHIP
], drift
[NSHIP
];
62 * first try to create moves for OUR ships
69 if (sp
->file
->captain
[0] || sp
->file
->dir
== 0)
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);
77 *sp
->file
->movebuf
= '\0';
79 closeon(sp
, closest
, sp
->file
->movebuf
,
80 sizeof(sp
->file
->movebuf
),
83 *sp
->file
->movebuf
= '\0';
86 * Then execute the moves for ALL ships (dead ones too),
87 * checking for collisions and snags at each step.
88 * The old positions are saved in row[], col[], dir[].
89 * At the end, we compare and write out the changes.
94 strcpy(sp
->file
->movebuf
, "d");
96 if (*sp
->file
->movebuf
!= 'd')
97 strcat(sp
->file
->movebuf
, "d");
98 row
[n
] = sp
->file
->row
;
99 col
[n
] = sp
->file
->col
;
100 dir
[n
] = sp
->file
->dir
;
101 drift
[n
] = sp
->file
->drift
;
106 * Now resolve collisions.
107 * This is the tough part.
109 for (k
= 0; stillmoving(k
); k
++) {
112 * And propagate the nulls at the end of sp->file->movebuf.
116 if (!sp
->file
->movebuf
[k
])
117 sp
->file
->movebuf
[k
+1] = '\0';
118 else if (sp
->file
->dir
)
119 step(sp
, sp
->file
->movebuf
[k
], &moved
[n
]);
127 if (sp
->file
->dir
== 0 || is_isolated(sp
))
135 if (sq
->file
->dir
== 0)
139 if (snagged2(sp
, sq
) && range(sp
, sq
) > 1)
141 if (!range(sp
, sq
) && !fouled2(sp
, sq
)) {
142 makesignal(sp
, "collision with $$", sq
);
144 makesignal(sp
, "fouled with $$",
152 sp
->file
->movebuf
[k
+ 1] = 0;
153 sq
->file
->movebuf
[k
+ 1] = 0;
154 sq
->file
->row
= sp
->file
->row
- 1;
155 if (sp
->file
->dir
== 1
156 || sp
->file
->dir
== 5)
160 sq
->file
->col
= sp
->file
->col
;
161 sq
->file
->dir
= sp
->file
->dir
;
171 * Clear old moves. And write out new pos.
175 if (sp
->file
->dir
!= 0) {
176 *sp
->file
->movebuf
= 0;
177 if (row
[n
] != sp
->file
->row
)
178 send_row(sp
, sp
->file
->row
);
179 if (col
[n
] != sp
->file
->col
)
180 send_col(sp
, sp
->file
->col
);
181 if (dir
[n
] != sp
->file
->dir
)
182 send_dir(sp
, sp
->file
->dir
);
183 if (drift
[n
] != sp
->file
->drift
)
184 send_drift(sp
, sp
->file
->drift
);
196 if (sp
->file
->movebuf
[k
])
202 is_isolated(struct ship
*ship
)
207 if (ship
!= sp
&& range(ship
, sp
) <= 10)
214 push(struct ship
*from
, struct ship
*to
)
218 sb
= to
->specs
->guns
;
219 bs
= from
->specs
->guns
;
228 step(struct ship
*sp
, int com
, char *moved
)
234 if (++sp
->file
->dir
== 9)
238 if (--sp
->file
->dir
== 0)
241 case '0': case '1': case '2': case '3':
242 case '4': case '5': case '6': case '7':
243 if (sp
->file
->dir
% 2 == 0)
244 dist
= dtab
[com
- '0'];
247 sp
->file
->row
-= dr
[sp
->file
->dir
] * dist
;
248 sp
->file
->col
-= dc
[sp
->file
->dir
] * dist
;
255 if (windspeed
!= 0 && ++sp
->file
->drift
> 2 &&
256 ((sp
->specs
->class >= 3 && !snagged(sp
))
257 || (turn
& 1) == 0)) {
258 sp
->file
->row
-= dr
[winddir
];
259 sp
->file
->col
-= dc
[winddir
];
269 sendbp(struct ship
*from
, struct ship
*to
, int sections
, int isdefense
)
274 bp
= isdefense
? from
->file
->DBP
: from
->file
->OBP
;
275 for (n
= 0; n
< NBP
&& bp
[n
].turnsent
; n
++)
277 if (n
< NBP
&& sections
) {
279 send_dbp(from
, n
, turn
, to
->file
->index
, sections
);
281 send_obp(from
, n
, turn
, to
->file
->index
, sections
);
284 makemsg(from
, "repelling boarders");
286 makesignal(from
, "boarding the $$", to
);
291 is_toughmelee(struct ship
*ship
, struct ship
*to
, int isdefense
, int count
)
295 int n
, OBP
= 0, DBP
= 0, dbp
= 0;
298 qual
= ship
->specs
->qual
;
299 bp
= isdefense
? ship
->file
->DBP
: ship
->file
->OBP
;
300 for (n
= 0; n
< NBP
; n
++, bp
++) {
301 if (bp
->turnsent
&& (to
== bp
->toship
|| isdefense
)) {
302 obp
+= bp
->mensent
/ 100
303 ? ship
->specs
->crew1
* qual
: 0;
304 obp
+= (bp
->mensent
% 100)/10
305 ? ship
->specs
->crew2
* qual
: 0;
306 obp
+= bp
->mensent
% 10
307 ? ship
->specs
->crew3
* qual
: 0;
310 if (count
|| isdefense
)
312 OBP
= is_toughmelee(to
, ship
, 0, count
+ 1);
313 dbp
= is_toughmelee(ship
, to
, 1, count
+ 1);
314 DBP
= is_toughmelee(to
, ship
, 1, count
+ 1);
315 if (OBP
> obp
+ 10 || OBP
+ DBP
>= obp
+ dbp
+ 10)
327 sp
->file
->loadwith
= 0;
339 if (sp
->file
->captain
[0] != 0)
341 rig
= sp
->specs
->rig1
;
342 if (windspeed
== 6 || (windspeed
== 5 && sp
->specs
->class > 4))
344 if (rig
&& sp
->specs
->crew3
) {
345 close
= closestenemy(sp
, 0, 0);
347 if (range(sp
, close
) > 9)
357 if ((sp
->file
->FS
!= 0) != full
)