1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)misc.c 8.2 (Berkeley) 04/28/95";
10 #endif /* not lint */
11
12 #include "extern.h"
13 #include "pathnames.h"
14
15 #define distance(x,y) (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2)
16
17 /* XXX */
18 range(from, to)
19 struct ship *from, *to;
20 {
21 register bow1r, bow1c, bow2r, bow2c;
22 int stern1r, stern1c, stern2c, stern2r;
23 register int bb, bs, sb, ss, result;
24
25 if (!to->file->dir)
26 return -1;
27 stern1r = bow1r = from->file->row;
28 stern1c = bow1c = from->file->col;
29 stern2r = bow2r = to->file->row;
30 stern2c = bow2c = to->file->col;
31 result = bb = distance(bow2r - bow1r, bow2c - bow1c);
32 if (bb < 5) {
33 stern2r += dr[to->file->dir];
34 stern2c += dc[to->file->dir];
35 stern1r += dr[from->file->dir];
36 stern1c += dc[from->file->dir];
37 bs = distance((bow2r - stern1r), (bow2c - stern1c));
38 sb = distance((bow1r - stern2r), (bow1c - stern2c));
39 ss = distance((stern2r - stern1r) ,(stern2c - stern1c));
40 result = min(bb, min(bs, min(sb, ss)));
41 }
42 return result;
43 }
44
45 struct ship *
closestenemy(from,side,anyship)46 closestenemy(from, side, anyship)
47 register struct ship *from;
48 char side, anyship;
49 {
50 register struct ship *sp;
51 register char a;
52 int olddist = 30000, dist;
53 struct ship *closest = 0;
54
55 a = capship(from)->nationality;
56 foreachship(sp) {
57 if (sp == from)
58 continue;
59 if (sp->file->dir == 0)
60 continue;
61 if (a == capship(sp)->nationality && !anyship)
62 continue;
63 if (side && gunsbear(from, sp) != side)
64 continue;
65 dist = range(from, sp);
66 if (dist < olddist) {
67 closest = sp;
68 olddist = dist;
69 }
70 }
71 return closest;
72 }
73
angle(dr,dc)74 angle(dr, dc)
75 register dr, dc;
76 {
77 register i;
78
79 if (dc >= 0 && dr > 0)
80 i = 0;
81 else if (dr <= 0 && dc > 0)
82 i = 2;
83 else if (dc <= 0 && dr < 0)
84 i = 4;
85 else
86 i = 6;
87 dr = abs(dr);
88 dc = abs(dc);
89 if ((i == 0 || i == 4) && dc * 2.4 > dr) {
90 i++;
91 if (dc > dr * 2.4)
92 i++;
93 } else if ((i == 2 || i == 6) && dr * 2.4 > dc) {
94 i++;
95 if (dr > dc * 2.4)
96 i++;
97 }
98 return i % 8 + 1;
99 }
100
gunsbear(from,to)101 gunsbear(from, to) /* checks for target bow or stern */
102 register struct ship *from, *to;
103 {
104 int Dr, Dc, i;
105 register ang;
106
107 Dr = from->file->row - to->file->row;
108 Dc = to->file->col - from->file->col;
109 for (i = 2; i; i--) {
110 if ((ang = angle(Dr, Dc) - from->file->dir + 1) < 1)
111 ang += 8;
112 if (ang >= 2 && ang <= 4)
113 return 'r';
114 if (ang >= 6 && ang <= 7)
115 return 'l';
116 Dr += dr[to->file->dir];
117 Dc += dc[to->file->dir];
118 }
119 return 0;
120 }
121
portside(from,on,quick)122 portside(from, on, quick)
123 register struct ship *from, *on;
124 int quick; /* returns true if fromship is */
125 { /* shooting at onship's starboard side */
126 register ang;
127 register Dr, Dc;
128
129 Dr = from->file->row - on->file->row;
130 Dc = on->file->col - from->file->col;
131 if (quick == -1) {
132 Dr += dr[on->file->dir];
133 Dc += dc[on->file->dir];
134 }
135 ang = angle(Dr, Dc);
136 if (quick != 0)
137 return ang;
138 ang = (ang + 4 - on->file->dir - 1) % 8 + 1;
139 return ang < 5;
140 }
141
colours(sp)142 colours(sp)
143 register struct ship *sp;
144 {
145 register char flag;
146
147 if (sp->file->struck)
148 flag = '!';
149 if (sp->file->explode)
150 flag = '#';
151 if (sp->file->sink)
152 flag = '~';
153 if (sp->file->struck)
154 return flag;
155 flag = *countryname[capship(sp)->nationality];
156 return sp->file->FS ? flag : tolower(flag);
157 }
158
159 #include <sys/file.h>
log(s)160 log(s)
161 register struct ship *s;
162 {
163 FILE *fp;
164 int persons;
165 int n;
166 struct logs log[NLOG];
167 float net;
168 register struct logs *lp;
169
170 if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL)
171 return;
172 #ifdef LOCK_EX
173 if (flock(fileno(fp), LOCK_EX) < 0)
174 return;
175 #endif
176 net = (float)s->file->points / s->specs->pts;
177 persons = getw(fp);
178 n = fread((char *)log, sizeof(struct logs), NLOG, fp);
179 for (lp = &log[n]; lp < &log[NLOG]; lp++)
180 lp->l_name[0] = lp->l_uid = lp->l_shipnum
181 = lp->l_gamenum = lp->l_netpoints = 0;
182 rewind(fp);
183 if (persons < 0)
184 (void) putw(1, fp);
185 else
186 (void) putw(persons + 1, fp);
187 for (lp = log; lp < &log[NLOG]; lp++)
188 if (net > (float)lp->l_netpoints
189 / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) {
190 (void) fwrite((char *)log,
191 sizeof (struct logs), lp - log, fp);
192 (void) strcpy(log[NLOG-1].l_name, s->file->captain);
193 log[NLOG-1].l_uid = getuid();
194 log[NLOG-1].l_shipnum = s->file->index;
195 log[NLOG-1].l_gamenum = game;
196 log[NLOG-1].l_netpoints = s->file->points;
197 (void) fwrite((char *)&log[NLOG-1],
198 sizeof (struct logs), 1, fp);
199 (void) fwrite((char *)lp,
200 sizeof (struct logs), &log[NLOG-1] - lp, fp);
201 break;
202 }
203 #ifdef LOCK_EX
204 (void) flock(fileno(fp), LOCK_UN);
205 #endif
206 (void) fclose(fp);
207 }
208