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[] = "@(#)misc.c 8.2 (Berkeley) 4/28/95";
36: #else
37: __RCSID("$NetBSD: misc.c,v 1.15 2004/11/05 21:30:32 dsl Exp $");
38: #endif
39: #endif
40:
41: #include <sys/file.h>
42:
43: #include <ctype.h>
44: #include <stdio.h>
45: #include <unistd.h>
46: #include <stdlib.h>
47: #include <string.h>
48: #include "extern.h"
49: #include "pathnames.h"
50:
51: #define distance(x,y) (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2)
52:
53: static int angle(int, int);
54:
55:
56: int
57: range(struct ship *from, struct ship *to)
58: {
59: int bow1r, bow1c, bow2r, bow2c;
60: int stern1r, stern1c, stern2c, stern2r;
61: int bb, bs, sb, ss, result;
62:
63: if (!to->file->dir)
64: return -1;
65: stern1r = bow1r = from->file->row;
66: stern1c = bow1c = from->file->col;
67: stern2r = bow2r = to->file->row;
68: stern2c = bow2c = to->file->col;
69: result = bb = distance(bow2r - bow1r, bow2c - bow1c);
70: if (bb < 5) {
71: stern2r += dr[to->file->dir];
72: stern2c += dc[to->file->dir];
73: stern1r += dr[from->file->dir];
74: stern1c += dc[from->file->dir];
75: bs = distance((bow2r - stern1r), (bow2c - stern1c));
76: sb = distance((bow1r - stern2r), (bow1c - stern2c));
77: ss = distance((stern2r - stern1r) ,(stern2c - stern1c));
78: result = min(bb, min(bs, min(sb, ss)));
79: }
80: return result;
81: }
82:
83: struct ship *
84: closestenemy(struct ship *from, int side, int anyship)
85: {
86: struct ship *sp;
87: char a;
88: int olddist = 30000, dist;
89: struct ship *closest = 0;
90:
91: a = capship(from)->nationality;
92: foreachship(sp) {
93: if (sp == from)
94: continue;
95: if (sp->file->dir == 0)
96: continue;
97: if (a == capship(sp)->nationality && !anyship)
98: continue;
99: if (side && gunsbear(from, sp) != side)
100: continue;
101: dist = range(from, sp);
102: if (dist < olddist) {
103: closest = sp;
104: olddist = dist;
105: }
106: }
107: return closest;
108: }
109:
110: static int
111: angle(int dr, int dc)
112: {
113: int i;
114:
115: if (dc >= 0 && dr > 0)
116: i = 0;
117: else if (dr <= 0 && dc > 0)
118: i = 2;
119: else if (dc <= 0 && dr < 0)
120: i = 4;
121: else
122: i = 6;
123: dr = abs(dr);
124: dc = abs(dc);
125: if ((i == 0 || i == 4) && dc * 2.4 > dr) {
126: i++;
127: if (dc > dr * 2.4)
128: i++;
129: } else if ((i == 2 || i == 6) && dr * 2.4 > dc) {
130: i++;
131: if (dr > dc * 2.4)
132: i++;
133: }
134: return i % 8 + 1;
135: }
136:
137:
138: int
139: gunsbear(struct ship *from, struct ship *to)
140: {
141: int Dr, Dc, i;
142: int ang;
143:
144: Dr = from->file->row - to->file->row;
145: Dc = to->file->col - from->file->col;
146: for (i = 2; i; i--) {
147: if ((ang = angle(Dr, Dc) - from->file->dir + 1) < 1)
148: ang += 8;
149: if (ang >= 2 && ang <= 4)
150: return 'r';
151: if (ang >= 6 && ang <= 7)
152: return 'l';
153: Dr += dr[to->file->dir];
154: Dc += dc[to->file->dir];
155: }
156: return 0;
157: }
158:
159:
160: int
161: portside(struct ship *from, struct ship *on, int quick)
162: {
163: int ang;
164: int Dr, Dc;
165:
166: Dr = from->file->row - on->file->row;
167: Dc = on->file->col - from->file->col;
168: if (quick == -1) {
169: Dr += dr[on->file->dir];
170: Dc += dc[on->file->dir];
171: }
172: ang = angle(Dr, Dc);
173: if (quick != 0)
174: return ang;
175: ang = (ang + 4 - on->file->dir - 1) % 8 + 1;
176: return ang < 5;
177: }
178:
179: int
180: colours(struct ship *sp)
181: {
182: char flag = '\0';
183:
184: if (sp->file->struck)
185: flag = '!';
186: if (sp->file->explode)
187: flag = '#';
188: if (sp->file->sink)
189: flag = '~';
190: if (sp->file->struck)
191: return flag;
192: flag = *countryname[capship(sp)->nationality];
193: return sp->file->FS ? flag : tolower((unsigned char)flag);
194: }
195:
196: void
197: logger(struct ship *s)
198: {
199: FILE *fp;
200: int persons;
201: int n;
202: struct logs log[NLOG];
203: float net;
204: struct logs *lp;
205:
206: setegid(egid);
207: if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL) {
208: setegid(gid);
209: return;
210: }
211: setegid(gid);
212: #ifdef LOCK_EX
213: if (flock(fileno(fp), LOCK_EX) < 0)
214: return;
215: #endif
216: net = (float)s->file->points / s->specs->pts;
217: persons = getw(fp);
218: n = fread((char *)log, sizeof(struct logs), NLOG, fp);
219: for (lp = &log[n]; lp < &log[NLOG]; lp++)
220: lp->l_name[0] = lp->l_uid = lp->l_shipnum
221: = lp->l_gamenum = lp->l_netpoints = 0;
222: rewind(fp);
223: if (persons < 0)
224: putw(1, fp);
225: else
226: putw(persons + 1, fp);
227: for (lp = log; lp < &log[NLOG]; lp++)
228: if (net > (float)lp->l_netpoints
229: / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) {
230: fwrite((char *)log, sizeof (struct logs), lp - log, fp);
231: strcpy(log[NLOG-1].l_name, s->file->captain);
232: log[NLOG-1].l_uid = getuid();
233: log[NLOG-1].l_shipnum = s->file->index;
234: log[NLOG-1].l_gamenum = game;
235: log[NLOG-1].l_netpoints = s->file->points;
236: fwrite((char *)&log[NLOG-1], sizeof (struct logs), 1, fp);
237: fwrite((char *)lp, sizeof (struct logs), &log[NLOG-1] - lp, fp);
238: break;
239: }
240: #ifdef LOCK_EX
241: flock(fileno(fp), LOCK_UN);
242: #endif
243: fclose(fp);
244: }