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