00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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, §);
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
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, §) && 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
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
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
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
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
00167 if (todelete)
00168 free(todelete);
00169 return nsat;
00170 }