src/lib/commands/skyw.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  skyw.c: Look at satellites in the sky.
00029  * 
00030  *  Known contributors to this file:
00031  *     Ken Stevens, 1995
00032  */
00033 
00034 #include <config.h>
00035 
00036 #include "commands.h"
00037 #include "optlist.h"
00038 #include "plane.h"
00039 
00040 #define TSIZE   200
00041 
00042 struct sky {
00043     struct sky *s_next;
00044     int s_spotted;
00045     struct plnstr s_sat;
00046 };
00047 
00048 static int showsat(struct sky **skypp, int x, int y);
00049 
00050 /*
00051  * format: skywatch [<SECTS>]
00052  */
00053 int
00054 skyw(void)
00055 {
00056     struct sctstr sect;
00057     struct nstr_sect nstr;
00058     struct sky *skyp;
00059     struct sky *list[TSIZE];
00060     int i, k, j, n;
00061     int vrange, see;
00062     int x, y;
00063     int mink, minj, maxk, maxj;
00064     int nsat = 0;
00065     double tech;
00066     struct nstr_item ni;
00067 
00068     if (!snxtsct(&nstr, player->argp[1]))
00069         return RET_SYN;
00070     for (i = 0; i < TSIZE; i++)
00071         list[i] = 0;
00072     skyp = malloc(sizeof(*skyp));
00073     snxtitem_all(&ni, EF_PLANE);
00074     while (nxtitem(&ni, &skyp->s_sat)) {
00075         if (!skyp->s_sat.pln_own)
00076             continue;
00077         if (!(skyp->s_sat.pln_flags & PLN_LAUNCHED))
00078             continue;
00079         getsect(skyp->s_sat.pln_x, skyp->s_sat.pln_y, &sect);
00080         n = scthash(skyp->s_sat.pln_x, skyp->s_sat.pln_y, TSIZE);
00081         skyp->s_spotted = 0;
00082         skyp->s_next = list[n];
00083         list[n] = skyp;
00084         skyp = malloc(sizeof(*skyp));
00085         nsat++;
00086     }
00087     /* get that last one! */
00088     free(skyp);
00089     pr("- = [ Skywatch report for %s ] = -\n", cname(player->cnum));
00090     pr(" %18s%20s        %s\n", "Country", "Satellite", "Location");
00091     tech = tfact(player->cnum, 1.0);
00092     while (nxtsct(&nstr, &sect) && nsat) {
00093         if (sect.sct_own != player->cnum)
00094             continue;
00095         see = sect.sct_type == SCT_RADAR ? 14 : 4;
00096         vrange = (int)(sect.sct_effic / 100.0 * see * tech);
00097         if (vrange < 1)
00098             vrange = 1;
00099         maxk = vrange;
00100         maxj = vrange * 2;
00101         vrange *= vrange;
00102         mink = -maxk;
00103         minj = -maxj;
00104         for (j = minj; j <= maxj && nsat; j++) {
00105             x = xnorm(sect.sct_x + j);
00106             for (k = mink; k <= maxk && nsat; k++) {
00107                 if ((j + k) & 01)
00108                     continue;
00109                 /* quick range check to save time... */
00110                 if (vrange < (j * j + 3 * k * k) / 4)
00111                     continue;
00112                 y = ynorm(sect.sct_y + k);
00113                 n = scthash(x, y, TSIZE);
00114                 if (list[n] == 0)
00115                     continue;
00116                 nsat -= showsat(&list[n], x, y);
00117             }
00118         }
00119     }
00120     /* free up the sky structs calloc'ed above */
00121     for (i = 0; i < TSIZE; i++) {
00122         while (NULL != (skyp = list[i])) {
00123             list[i] = skyp->s_next;
00124             free(skyp);
00125         }
00126     }
00127     return RET_OK;
00128 }
00129 
00130 static int
00131 showsat(struct sky **skypp, int x, int y)
00132 {
00133     struct sky *skyp;
00134     struct sky *todelete = 0;
00135     struct sky **prev;
00136     struct plchrstr *pcp;
00137     char *name;
00138     int nsat = 0;
00139 
00140     prev = 0;
00141     skyp = *skypp;
00142     prev = skypp;
00143     do {
00144         /* we delete it, we free it. */
00145         if (todelete) {
00146             free(todelete);
00147             todelete = 0;
00148         }
00149         if (skyp->s_sat.pln_x != x || skyp->s_sat.pln_y != y) {
00150             prev = &(*prev)->s_next;
00151             continue;
00152         }
00153         pcp = &plchr[(int)skyp->s_sat.pln_type];
00154         name = pcp->pl_name;
00155         pr(" %12.12s (#%d) %20s            %s\n",
00156            cname(skyp->s_sat.pln_own), skyp->s_sat.pln_own,
00157            name, xyas(x, y, player->cnum));
00158         if (opt_HIDDEN) {
00159             /* FOUND_COAST should probably be changed to FOUND_SKY -KHS */
00160             setcont(player->cnum, skyp->s_sat.pln_own, FOUND_COAST);
00161         }
00162         *prev = skyp->s_next;
00163         todelete = skyp;
00164         nsat++;
00165     } while (NULL != (skyp = skyp->s_next));
00166     /* check that last one! */
00167     if (todelete)
00168         free(todelete);
00169     return nsat;
00170 }

Generated on Fri Mar 28 11:01:13 2008 for empserver by  doxygen 1.5.2