(linenum→info "unix/slp.c:2238")

bsd-games/2.17/sail/misc.c

    1: /*      $NetBSD: misc.c,v 1.15 2004/11/05 21:30:32 dsl Exp $ */
    2: 
    3: /*
    4:  * Copyright (c) 1983, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    6:  *
    7:  * Redistribution and use in source and binary forms, with or without
    8:  * modification, are permitted provided that the following conditions
    9:  * are met:
   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.
   18:  *
   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
   29:  * SUCH DAMAGE.
   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 /* not lint */
   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: /* XXX */
   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: /* checks for target bow or stern */
  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: /* returns true if fromship is shooting at onship's starboard side */
  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: }
Syntax (Markdown)