1 /* $NetBSD: misc.c,v 1.17 2009/03/14 18:41:21 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
[] = "@(#)misc.c 8.2 (Berkeley) 4/28/95";
37 __RCSID("$NetBSD: misc.c,v 1.17 2009/03/14 18:41:21 dholland Exp $");
47 #include "pathnames.h"
49 #define distance(x,y) \
50 (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2)
52 static int angle(int, int);
56 range(struct ship
*from
, struct ship
*to
)
58 int bow1r
, bow1c
, bow2r
, bow2c
;
59 int stern1r
, stern1c
, stern2c
, stern2r
;
60 int bb
, bs
, sb
, ss
, result
;
64 stern1r
= bow1r
= from
->file
->row
;
65 stern1c
= bow1c
= from
->file
->col
;
66 stern2r
= bow2r
= to
->file
->row
;
67 stern2c
= bow2c
= to
->file
->col
;
68 result
= bb
= distance(bow2r
- bow1r
, bow2c
- bow1c
);
70 stern2r
+= dr
[to
->file
->dir
];
71 stern2c
+= dc
[to
->file
->dir
];
72 stern1r
+= dr
[from
->file
->dir
];
73 stern1c
+= dc
[from
->file
->dir
];
74 bs
= distance((bow2r
- stern1r
), (bow2c
- stern1c
));
75 sb
= distance((bow1r
- stern2r
), (bow1c
- stern2c
));
76 ss
= distance((stern2r
- stern1r
) ,(stern2c
- stern1c
));
77 result
= min(bb
, min(bs
, min(sb
, ss
)));
83 closestenemy(struct ship
*from
, int side
, int anyship
)
87 int olddist
= 30000, dist
;
88 struct ship
*closest
= 0;
90 a
= capship(from
)->nationality
;
94 if (sp
->file
->dir
== 0)
96 if (a
== capship(sp
)->nationality
&& !anyship
)
98 if (side
&& gunsbear(from
, sp
) != side
)
100 dist
= range(from
, sp
);
101 if (dist
< olddist
) {
110 angle(int Dr
, int Dc
)
114 if (Dc
>= 0 && Dr
> 0)
116 else if (Dr
<= 0 && Dc
> 0)
118 else if (Dc
<= 0 && Dr
< 0)
124 if ((i
== 0 || i
== 4) && Dc
* 2.4 > Dr
) {
128 } else if ((i
== 2 || i
== 6) && Dr
* 2.4 > Dc
) {
136 /* checks for target bow or stern */
138 gunsbear(struct ship
*from
, struct ship
*to
)
143 Dr
= from
->file
->row
- to
->file
->row
;
144 Dc
= to
->file
->col
- from
->file
->col
;
145 for (i
= 2; i
; i
--) {
146 if ((ang
= angle(Dr
, Dc
) - from
->file
->dir
+ 1) < 1)
148 if (ang
>= 2 && ang
<= 4)
150 if (ang
>= 6 && ang
<= 7)
152 Dr
+= dr
[to
->file
->dir
];
153 Dc
+= dc
[to
->file
->dir
];
158 /* returns true if fromship is shooting at onship's starboard side */
160 portside(struct ship
*from
, struct ship
*on
, int quick
)
165 Dr
= from
->file
->row
- on
->file
->row
;
166 Dc
= on
->file
->col
- from
->file
->col
;
168 Dr
+= dr
[on
->file
->dir
];
169 Dc
+= dc
[on
->file
->dir
];
174 ang
= (ang
+ 4 - on
->file
->dir
- 1) % 8 + 1;
179 colours(struct ship
*sp
)
183 if (sp
->file
->struck
)
185 if (sp
->file
->explode
)
189 if (sp
->file
->struck
)
191 flag
= *countryname
[capship(sp
)->nationality
];
192 return sp
->file
->FS
? flag
: tolower((unsigned char)flag
);
196 logger(struct ship
*s
)
201 struct logs log
[NLOG
];
206 if ((fp
= fopen(_PATH_LOGFILE
, "r+")) == NULL
) {
212 if (flock(fileno(fp
), LOCK_EX
) < 0)
215 net
= (float)s
->file
->points
/ s
->specs
->pts
;
217 n
= fread(log
, sizeof(struct logs
), NLOG
, fp
);
218 for (lp
= &log
[n
]; lp
< &log
[NLOG
]; lp
++)
219 lp
->l_name
[0] = lp
->l_uid
= lp
->l_shipnum
220 = lp
->l_gamenum
= lp
->l_netpoints
= 0;
225 putw(persons
+ 1, fp
);
226 for (lp
= log
; lp
< &log
[NLOG
]; lp
++)
227 if (net
> (float)lp
->l_netpoints
228 / scene
[lp
->l_gamenum
].ship
[lp
->l_shipnum
].specs
->pts
) {
229 fwrite(log
, sizeof (struct logs
), lp
- log
, fp
);
230 strcpy(log
[NLOG
-1].l_name
, s
->file
->captain
);
231 log
[NLOG
-1].l_uid
= getuid();
232 log
[NLOG
-1].l_shipnum
= s
->file
->index
;
233 log
[NLOG
-1].l_gamenum
= game
;
234 log
[NLOG
-1].l_netpoints
= s
->file
->points
;
235 fwrite(&log
[NLOG
-1], sizeof (struct logs
), 1, fp
);
236 fwrite(lp
, sizeof (struct logs
), &log
[NLOG
-1] - lp
, fp
);
240 flock(fileno(fp
), LOCK_UN
);