misc.c revision 1.3
1/* $OpenBSD: misc.c,v 1.3 2003/04/06 18:50:38 deraadt Exp $ */ 2/* $NetBSD: misc.c,v 1.3 1995/04/22 10:37:03 cgd Exp $ */ 3 4/* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38#if 0 39static char sccsid[] = "@(#)misc.c 8.2 (Berkeley) 4/28/95"; 40#else 41static char rcsid[] = "$OpenBSD: misc.c,v 1.3 2003/04/06 18:50:38 deraadt Exp $"; 42#endif 43#endif /* not lint */ 44 45#include <fcntl.h> 46#include <stdlib.h> 47#include <sys/file.h> 48#include <unistd.h> 49#include "extern.h" 50#include "pathnames.h" 51 52#define distance(x,y) (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2) 53 54/* XXX */ 55int 56range(from, to) 57 struct ship *from, *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 83struct ship * 84closestenemy(from, side, anyship) 85 struct ship *from; 86 char side, anyship; 87{ 88 struct ship *sp; 89 char a; 90 int olddist = 30000, dist; 91 struct ship *closest = 0; 92 93 a = capship(from)->nationality; 94 foreachship(sp) { 95 if (sp == from) 96 continue; 97 if (sp->file->dir == 0) 98 continue; 99 if (a == capship(sp)->nationality && !anyship) 100 continue; 101 if (side && gunsbear(from, sp) != side) 102 continue; 103 dist = range(from, sp); 104 if (dist < olddist) { 105 closest = sp; 106 olddist = dist; 107 } 108 } 109 return closest; 110} 111 112int 113angle(dr, dc) 114 int dr, dc; 115{ 116 int i; 117 118 if (dc >= 0 && dr > 0) 119 i = 0; 120 else if (dr <= 0 && dc > 0) 121 i = 2; 122 else if (dc <= 0 && dr < 0) 123 i = 4; 124 else 125 i = 6; 126 dr = abs(dr); 127 dc = abs(dc); 128 if ((i == 0 || i == 4) && dc * 2.4 > dr) { 129 i++; 130 if (dc > dr * 2.4) 131 i++; 132 } else if ((i == 2 || i == 6) && dr * 2.4 > dc) { 133 i++; 134 if (dr > dc * 2.4) 135 i++; 136 } 137 return i % 8 + 1; 138} 139 140int 141gunsbear(from, to) /* checks for target bow or stern */ 142 struct ship *from, *to; 143{ 144 int Dr, Dc, i; 145 int ang; 146 147 Dr = from->file->row - to->file->row; 148 Dc = to->file->col - from->file->col; 149 for (i = 2; i; i--) { 150 if ((ang = angle(Dr, Dc) - from->file->dir + 1) < 1) 151 ang += 8; 152 if (ang >= 2 && ang <= 4) 153 return 'r'; 154 if (ang >= 6 && ang <= 7) 155 return 'l'; 156 Dr += dr[to->file->dir]; 157 Dc += dc[to->file->dir]; 158 } 159 return 0; 160} 161 162int 163portside(from, on, quick) 164 struct ship *from, *on; 165 int quick; /* returns true if fromship is */ 166{ /* shooting at onship's starboard side */ 167 int ang; 168 int Dr, Dc; 169 170 Dr = from->file->row - on->file->row; 171 Dc = on->file->col - from->file->col; 172 if (quick == -1) { 173 Dr += dr[on->file->dir]; 174 Dc += dc[on->file->dir]; 175 } 176 ang = angle(Dr, Dc); 177 if (quick != 0) 178 return ang; 179 ang = (ang + 4 - on->file->dir - 1) % 8 + 1; 180 return ang < 5; 181} 182 183int 184colours(sp) 185 struct ship *sp; 186{ 187 char flag; 188 189 if (sp->file->struck) { 190 flag = '!'; 191 return flag; 192 } 193 if (sp->file->explode) 194 flag = '#'; 195 if (sp->file->sink) 196 flag = '~'; 197 flag = *countryname[capship(sp)->nationality]; 198 return sp->file->FS ? flag : tolower(flag); 199} 200 201void 202logger(s) 203 struct ship *s; 204{ 205 FILE *fp; 206 int persons; 207 int n; 208 struct logs log[NLOG]; 209 float net; 210 struct logs *lp; 211 212 setegid(egid); 213 if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL) { 214 setegid(gid); 215 return; 216 } 217 setegid(gid); 218#ifdef LOCK_EX 219 if (flock(fileno(fp), LOCK_EX) < 0) 220 return; 221#endif 222 net = (float)s->file->points / s->specs->pts; 223 persons = getw(fp); 224 n = fread((char *)log, sizeof(struct logs), NLOG, fp); 225 for (lp = &log[n]; lp < &log[NLOG]; lp++) 226 lp->l_name[0] = lp->l_uid = lp->l_shipnum 227 = lp->l_gamenum = lp->l_netpoints = 0; 228 rewind(fp); 229 if (persons < 0) 230 (void) putw(1, fp); 231 else 232 (void) putw(persons + 1, fp); 233 for (lp = log; lp < &log[NLOG]; lp++) 234 if (net > (float)lp->l_netpoints 235 / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) { 236 (void) fwrite((char *)log, 237 sizeof (struct logs), lp - log, fp); 238 (void) strlcpy(log[NLOG-1].l_name, s->file->captain, 239 sizeof log[NLOG-1].l_name); 240 log[NLOG-1].l_uid = getuid(); 241 log[NLOG-1].l_shipnum = s->file->index; 242 log[NLOG-1].l_gamenum = game; 243 log[NLOG-1].l_netpoints = s->file->points; 244 (void) fwrite((char *)&log[NLOG-1], 245 sizeof (struct logs), 1, fp); 246 (void) fwrite((char *)lp, 247 sizeof (struct logs), &log[NLOG-1] - lp, fp); 248 break; 249 } 250#ifdef LOCK_EX 251 (void) flock(fileno(fp), LOCK_UN); 252#endif 253 (void) fclose(fp); 254} 255